【问题标题】:CMake: correctly linking system library using gccCMake:使用 gcc 正确链接系统库
【发布时间】:2013-02-17 09:08:13
【问题描述】:

我有一个依赖于数学库的静态库 mylib。

如果我首先将 mylib 与数学链接,然后链接到我的可执行文件,它就可以工作:

add_executable(myapp main.c)
target_link_libraries(mylib m)
target_link_libraries(myapp mylib)

但是,如果我直接与可执行文件进行链接,则在使用 gcc 时会失败(使用 clang 它可以工作!)

add_executable(myapp main.c)
target_link_libraries(myapp m mylib)

为什么这有什么不同?
我认为无论如何不可能将库链接在一起?

【问题讨论】:

    标签: gcc cmake clang


    【解决方案1】:

    当使用 cmake 的 target_link_libraries 时,并不意味着你会链接任何东西。它会在target 和类型/操作linklibrary 之间创建依赖关系。

    我猜第一个示例的实际构建行会产生类似的结果:

    gcc -o myapp myapp.o -lmylib -lm
    

    还有第二个

    gcc -o myapp myapp.o -lm -lmylib
    

    。如果mylib 引用了m,则第二个示例(可能)没有链接。

    尝试运行make VERBOSE=1 并研究链接进程的命令行以真正了解正在发生的事情。 clang 的链接器可能是智能的,它会在链接过程中实际删除库之前等待所有调用被链接。

    【讨论】:

    • 我认为你是对的 - 如果在二进制文件之后没有提供库,gcc 似乎会在链接期间删除库。如果我将命令更改为 target_link_libraries(myapp mylib m) 它可以工作!
    • 你使用 make VERBOSE=1 和 clang 吗?
    【解决方案2】:

    使用target_link_libraries 时,指定链接库的顺序很重要。

    这在使用 gcc 时不起作用(至少在 v4.6.3 中):

    target_link_libraries(myapp m mylib)
    

    虽然这有效:

    target_link_libraries(myapp mylib m)
    

    所以 mylib 所依赖的所有库都必须在 mylib 之后。

    如果您使用 make VERBOSE=1 跟踪实际的链接器调用,您会发现这个损坏的示例:

    gcc main.c.o  -o luatest -rdynamic -lm mylib.a
    

    这是工作的:

    gcc main.c.o  -o luatest -rdynamic mylib.a -lm
    

    使用完全相同的参数调用 clang 在这两种情况下都有效!

    所以@PatrickB 似乎是对的:

    clang 的链接器可能是智能的并等待所有调用 在链接过程中实际删除库之前链接。

    【讨论】:

    • 您可能应该将@Patrick B. 的答案标记为正确 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多