Gcc CMake库链接顺序

Gcc CMake库链接顺序,gcc,cmake,Gcc,Cmake,我有以下库lib_A,lib_B,lib_C,lib_D。我在我的CMake文件中做了类似的事情(顺序很重要): 添加库(lib\u A) 添加库(lib\u B) 添加库(lib\u C) 添加库(lib\u D) TARGET\u LINK\u库(lib\u B lib\u C) TARGET\u LINK\u库(lib\u A lib\u B) 添加可执行文件(Exec) TARGET\u LINK\u库(exec lib\u A) TARGET\u LINK\u库(exec lib\u

我有以下库
lib_A
lib_B
lib_C
lib_D
。我在我的CMake文件中做了类似的事情(顺序很重要):

  • 添加库(lib\u A)
  • 添加库(lib\u B)
  • 添加库(lib\u C)
  • 添加库(lib\u D)
  • TARGET\u LINK\u库(lib\u B lib\u C)
  • TARGET\u LINK\u库(lib\u A lib\u B)
  • 添加可执行文件(Exec)
  • TARGET\u LINK\u库(exec lib\u A)
  • TARGET\u LINK\u库(exec lib\u D)
  • 这将导致执行以下链接器命令

    linker -llib_A -llib_D -llib_B -llib_C
    
    问题1。为什么
    lib_B
    lib_C
    lib_D
    之后

    问题2。当我改变CMake一点并做如下操作时:

    linker -llib_A -llib_B -llib_C -llib_D
    
  • TARGET\u LINK\u库(lib\u A lib\u D)
  • TARGET\u LINK\u库(exec lib\u A)
  • 那么链接顺序是这样的:

    linker -llib_A -llib_B -llib_C -llib_D
    
    这里,
    lib_B
    lib_C
    lib_D
    之前。这意味着
    target\u link\u库
    对于可执行目标和库目标的工作方式不同。我说得对吗

    这里的问题是
    lib_B
    lib_C
    也依赖于
    lib_D
    ,但我不想创建
    target_link_库(lib_B lib_D)
    target_link_库(lib_C lib_D)
    ,因为我有更多这样的案例,而且我必须为每个库手动创建。 当然,在第二季度像这样做可以解决问题,但是:

    Q3-该订单是由CMake提供某种保证,还是仅仅是一种偶然性


    谢谢

    只需将
    lib_B
    lib_C
    链接到
    lib_D
    ,这是值得的(我可以凭经验判断),否则您将遇到很大的麻烦,例如,如果您尝试安装程序
    lib_C
    lib_D
    应在创建完它们的库文件后,在将它们链接到任何其他库之前解决它们的所有符号

    顺便说一句,您可以将
    target\u link\u库压缩为每个目标一行,如:

    TARGET_LINK_LIBRARIES(exec lib_A lib_D)
    
    而且,如果exec不直接依赖于
    lib\u D
    ,那么如果将
    lib\u A
    正确链接到
    lib\u D
    ,则可以避免链接它


    无论如何,关于Q1:即使订单由CMake保证,也不能保证你的链接器处理它的方式,如果你依赖它,你将遭受痛苦

    不确定EXE和LIB之间的顺序差异,但是如果B和C都依赖于D,你们真的应该具体说明一下。问题是B和C在逻辑上是平台依赖A的一部分,而整个依赖于平台库D。我知道我应该这样做,但我有很多,手动操作会花费很多精力来维护它,提供一些自动解决方案会增加我基于cmake的构建系统的复杂性。另一个问题是,当我将此D依赖项显式设置为每个独立于平台的库时,会导致D多次出现在链接器列表中。例如,我对外部库boost也有同样的问题。我希望避免在每个库中将依赖项设置为boost。@user2301299我唯一的建议是创建一个链接到所有目标的外部库列表,以便为每个库压缩
    target\u link\u库。顺便说一句,如果你链接到一个不必要的动态库,链接器会理解这一点并删除依赖项:不是很干净,但你可以决定是否要带着它离开谢谢你的回答。我已经决定将依赖项自动添加到每个库中。它将解决另一个问题。其中一些库是跨多个可执行文件共享的。将依赖关系保持在每个库的级别,我不必担心在链接这些可执行文件时无法解析的符号。