可移植编程——在Win32上链接失败,但在linux上链接失败
Portable programming - Linking fails fails with Win32 but links with linux
我正在开发一个在Linux和Windows下运行的便携式应用程序。我使用cmake, gcc 4.4.4和mingw-gcc 4.4.4在linux系统上交叉编译。
我可以编译和链接我的应用程序的Linux版本没有问题。然而,如果我尝试在Windows上交叉编译,应用程序编译得很好,但链接器以"未定义的引用"错误结束。
以下是源代码的摘录:
头文件(fileactions.hpp):
class FileActions {
bool CopyFile(const std::string &source, const std::string &destination);
bool CopyFile(const boost::filesystem::path& source, const boost::filesystem::path& destination);
};
源文件(fileactions.cpp):
bool FileActions::CopyFile(const boost::filesystem::path& source, const boost::filesystem::path& destination)
{
return this->CopyFile(source.string(), destination.string());
}
bool FileActions::CopyFile(const std::string &source, const std::string &destination)
{
/* ... do something */
}
从导致链接错误的代码中摘录:
bool TmmProject::PostImportOldVersion(int old_version) {
namespace fs = boost::filesystem;
FileActions dd;
fs::path backup;
/* fs::path _location; // This is actually defined in the class declaration */
/* do something more */
if( !dd.CopyFile(_location, backup ) ) { <-- I get the linker error at this line
log << "<span style="color:red">Failed to create backup file. Stopping import </span><br>";
log << "The error message is: " << dd.GetError() << "<br>";
_last_error = log.str();
return false;
}
/* do something more */
}
如前所述,如果我在linux系统下编译,上面的代码链接良好,但如果我使用mingw来编译Win32,则会失败。确切的链接器错误是:
CMakeFiles/tmm.dir/tmmproject.cpp.obj:/.../tmm/tmmproject.cpp:408: undefined reference
to 'tmm::fileActions::CopyFileA(
boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const &,
boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const &
)'
文件fileactions.cpp被链接到一个静态库libtmm。导致错误的TmmProject类是同一个库的一部分。
用于链接库的CMakeLists.txt看起来像这样(缩短):
include_directories( ... )
link_directories ( ${Boost_LIBRARY_DIRS} )
file(GLOB TMM_HEADERS *.h)
file(GLOB TMM_SOURCES *.cpp)
set ( TMM_LIBS
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
m
)
IF( WIN32 )
ADD_LIBRARY( tmm STATIC ${TMM_SOURCES} )
target_link_libraries( tmm ${TMM_LIBS} )
# I found the following option from a similar quesiton in this froum, but
# actually it does not seem to make any difference
SET_TARGET_PROPERTIES( tmm PROPERTIES LINK_FLAGS -Wl,--export-all-symbols )
ELSE( WIN32 )
ADD_LIBRARY( tmm SHARED ${TMM_SOURCES} )
target_link_libraries( tmm ${TMM_LIBS} )
INSTALL(TARGETS tmm DESTINATION lib)
ENDIF( WIN32 )
有人知道失败的原因是什么吗?
Microsoft在其header中使用了许多定义来支持unicode。在您的情况下,名称OpenFile
似乎也被定义为OpenFileA
,或者如果您切换到unicode,它将是OpenFileW
。
要解决这个问题,请在包含microsoft.
#undef CopyFile
您当然可以将其打包到#ifdef
中,以将其限制为microsoft平台。
这是微软使用宏允许应用程序使用"UNICODE"(宽或16位字符)和"ASCII"(8位字符)形式的系统调用。在windows。h中有这样的内容:
#if UNICODE
#define CopyFile CopyFileW
#else
#define CopyFile CopyFileA
#endif
虽然使用#undef CopyFile
(和类似的)将工作,我建议你避免包括<windows.h>
,除非绝对必要-如果你必须,尽量限制到一个小数量(理想情况下一个)源文件,实际上直接与Widnows交互。
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- Netbeans 10:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 链接 c++ 动态库一直失败
- 链接器命令失败,macOS 上的退出代码为 1(使用 -v 查看调用)
- CMake 错误:链接器命令失败,退出代码为 1 和 cpp.o 文件
- clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) - 体系结构的未定义符号 x86_64:
- 如何修复 clang: 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 如何在 Linux 中构建共享库时使未定义引用的链接器失败
- mapreduce c编程与-fPIC链接失败,如何解决?
- Xcode:链接器命令失败,退出代码为 1(使用 -v 查看调用)[C++]
- 引用构造函数时链接失败
- 通过嵌入式 IWebBrowser2 控件中的链接打开 youtube 搜索失败
- Android NDK.Build命令失败.未定义的引用.clang++:错误:链接器命令失败,退出代码为1
- CMake链接库在Docker映像中失败
- 生成库失败:无法识别文件格式;作为链接器脚本处理
- 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用):在 Macbook 上
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- C++ XCODE ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -
- Android Studio 链接器命令在包含 Boost 库时失败
- 链接 openGL 库失败,因为它无法打开 libgl.so ...但它就在那里