c++ - 调用链接器时是否可以强制 CMake 重新排序参数?
问题描述
我有一个奇怪的行为,如果需要动态链接,CMake 无法链接任何可执行文件。g++ 无法找到库中定义的任何符号。
我发现它可能与链接时 CMake 传递给 g++ 的参数的顺序有关。
这是构建过程的详细输出(链接失败):
[ 50%] Building CXX object CMakeFiles/chargen.dir/test.cpp.obj
g++ -std=c++11 -o CMakeFiles/test.dir/test.cpp.obj -c /f/test/test.cpp
[100%] Linking CXX executable mytest
/usr/bin/cmake -E cmake_link_script CMakeFiles/test.dir/link.txt --verbose=1
g++ -std=c++11 -lSDL2 CMakeFiles/test.dir/test.cpp.obj -o mytest
事实上,如果我尝试使用该命令进行链接,我会得到未定义的引用,但是如果我在最后使用库标志进行编译:
g++ -std=c++11 CMakeFiles/test.dir/test.cpp.obj -o mytest -lSDL2
它运行得很好。如何强制 CMake 改用该参数顺序?
CMakeLists.txt 的内容:
cmake_minimum_required(VERSION 3.6)
project(mytest)
set(COMPILER_PATH "/usr/bin/")
set(CMAKE_MAKE_PROGRAM "make")
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lSDL2")
set(SOURCE_FILES test.cpp)
add_executable(mytest ${SOURCE_FILES})
解决方案
您可能已将-lSDL2添加到 CMAKE_CXX_FLAGS 中。在这种情况下,它会出现在实际链接命令中的源文件名前面,带有编译/链接标志,如您所示。不要那样做。
您应该使用 _target_link_libraries_ cmake 命令来定义要链接的库。简而言之,您的 CMakeLists.txt 的框架应该如下所示:
project (project_name)
add_executable (mytest test.cpp)
target_link_libraries( mytest SDL2)
在这种情况下,cmake 会将库放在正确的位置。请注意,您可以在添加目标 mytest 后使用 target_link_libraries
[编辑]
在看到您的 CMakeLists 之后,很明显您的问题出在错误的 CMAKE_EXE_LINKER_FLAGS 中。只需删除您设置它的行,然后在 add_executable 之后添加 target_link_libraries。
关于处理静态库之间的循环依赖关系的问题,您的处理方式与不使用 cmake 时相同:提及两次:
target_link_libraries(
mytest
circular_dep1
circular_dep2
circular_dep1
circular_dep2
)
关于您关于特定链接器标志的问题,只需将它们放入 target_link_libraries 命令,它也接受链接器标志。您可以在以下链接中找到文档:
https://cmake.org/cmake/help/latest/command/target_link_libraries.html
推荐阅读
- c# - 实现一个泛型类,该类具有需要泛型的约束
- reactjs - Error: Identifier already been declared. How can it be resolved?
- kubernetes - 在 k3s 集群中启用/配置审计日志(使用 k3d 设置集群)
- python - 从 DataFrames 的 dict 中删除以下重复值
- javascript - 如何在NodeJS和react中连接两个项目路由(我想在NodeJS项目中调用react)
- python - 为什么我的 sqlite 查询不打印所有数据?
- hibernate - Hibernate - Ehcache 配置不起作用(没有命中二级缓存)
- c# - 如何通过 nginx 负载均衡器连接到安全的 RabbitMQ 集群
- javascript - 如何优化编码数字游戏?
- javascript - D3.js 文本元素不显示函数的值