【问题标题】:Is it possible to force CMake to reorder arguments when calling the linker? [duplicate]调用链接器时是否可以强制 CMake 重新排序参数? [复制]
【发布时间】:2018-09-02 19:52:03
【问题描述】:

我有一个奇怪的行为,如果需要动态链接,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})

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:

    您可能已将 -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

    【讨论】:

    • 关闭,它是 CMAKE_EXE_LINKER_FLAGS,但是如何处理需要在 '-Wl,--start-group' 和 '-Wl,--end-group' 标志之间的静态库的循环依赖关系?
    • @G.Grantig 这是一个问题,未反映在原始问题中。另外,“关闭,它是 CMAKE_EXE_LINKER_FLAGS [...]”是什么意思?是不是这个问题?
    • @Grantig:只需将其放入 target_link_libraries 即可。它不仅接受库名称,还接受链接器标志。还有。请阅读文档:
    • @compor,是的,这是问题所在; Grantig 使用不同的变量(错误地)添加库,结果很糟糕。我在原始答案中写的所有内容。
    • @compor 我的意思不是答案中的 CMAKE_CXX_FLAGS,而是 CMAKE_EXE_LINKER_FLAGS,这会导致相同的结果。我还不能投票给答案。关于循环依赖的问题出现了,因为 'target_link_libraries( ... )' 乍一看似乎不如 CMAKE_EXE_LINKER_FLAGS 强大
    猜你喜欢
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    • 2013-04-27
    相关资源
    最近更新 更多