CMake中链接库的顺序问题

原文链接:https://blog.csdn.net/lifemap/article/details/7586363

cmake中链接库的顺序是a依赖b,那么b放在a的后面。

例如进程test依赖a库,b库, a库又依赖b 库,那么顺序如下:
TARGET_LINK_LIBRARIES(test a b)

原文链接:https://www.cnblogs.com/aquester/p/10084070.html

前言

C/C++程序的许多同学被静态库的依赖折腾,因为默认情况下要求被依赖的库放在依赖它的库后面,当一个程序或共享库依赖的静态库较多时,可能会陷入解决链接问题的坑中。如果对静态库不熟悉,需要结构nm等工具来解决顺序问题。

但也可以偷懒,不关心静态库的顺序问题,ld为此提供了start-group和end-group两个选项,让包含在这两者间的静态库顺序可以随意。

方法

以CMake为例,假设程序x依赖三个静态库:libX1.a、libX2.a和libX3.a,而libX2.a又依赖libX1.a,libX3.a依赖libX2.a和libX1.a,正常情况下的CMakeLists.txt格式如下:

add_executable(
    x
    x.cpp
)
target_link_libraries(
    x
    libX1.a
    libX2.a
    libX3.a
)

上面的写法libX1.a、libX2.a和libX3.a的顺序不能变,只能按上面的先后顺序。如果去掉顺序的烦恼和痛苦,可以采用如下的写法:

target_link_libraries(
    x
    -Wl,--start-group
    libX1.a
    libX3.a
    libX2.a
    -Wl,--end-group
)

target_link_libraries(
    x
    -Wl,--start-group
    libX3.a
    libX2.a
    libX1.a
    -Wl,--end-group
)

都可以,完全不用关心顺序。

附3:gcc链接参数–whole-archive的作用
默认情况下,对于未使用到的符号(函数是一种符号),链接器不会将它们链接进共享库和可执行程序。

这个时候,可以启用链接参数“--whole-archive”来告诉链接器,将后面库中所有符号都链接进来,参数“-no-whole-archive”则是重置,以避免后面库的所有符号被链接进来。

附4:如何让有些“-l”链接静态库,而另一些链接共享库?
用“-Wl,-Bstatic”指定链接静态库,使用“-Wl,-Bdynamic”指定链接共享库,使用示例:

-Wl,-Bstatic -lmysqlclient_r -lssl -lcrypto -Wl,-Bdynamic -lrt -Wl,-Bdynamic -pthread -Wl,-Bstatic -lgtest

"-Wl"表示是传递给链接器ld的参数,而不是编译器gcc/g++的参数。

### 如何使用 CMake 配置动态库链接其他动态库 在 CMake 中,当一个动态库需要依赖于另一个动态库,可以通过 `target_link_libraries` 命令来实现这种依赖关系。以下是详细的说明以及示例。 #### 动态库之间的依赖机制 动态库在构建过程中可以声明对其它动态库的依赖。通过这种方式,在最终的应用程序中加载这些动态库,操作系统会自动解析并加载所需的其它动态库[^1]。为了确保这种行为正常工作,必须正确设置 CMake 的目标链接命令。 #### 示例代码 假设我们有两个动态库:`libA.so` 和 `libB.so`,其中 `libB.so` 依赖于 `libA.so`。下面是具体的 CMakeLists.txt 文件配置: ```cmake # 定义 libA 动态库 add_library(libA SHARED src/libA.cpp) # 定义 libB 动态库 add_library(libB SHARED src/libB.cpp) # 将 libA 链接到 libB 上 target_link_libraries(libB PRIVATE libA) ``` 上述代码片段展示了如何让 `libB` 正确地依赖于 `libA`。这里的关键在于 `target_link_libraries` 函数中的参数顺序和作用范围的选择(如 `PRIVATE`, `PUBLIC`, 或 `INTERFACE`)。如果希望下游项目也能感知到这个依赖,则应选择 `PUBLIC` 而不是 `PRIVATE`[^2]。 #### 关键点解释 - **SHARED**: 表明正在创建的是共享库即动态库。 - **target_link_libraries**: 这一指令用于指定某个目标文件所要链接的库列表。在这里,“目标”指的是由前面定义好的库名或者可执行文件名称表示的目标对象。 对于 Android 平台上的 NDK 开发而言,同样的原则适用,并且还可以额外利用 Android Gradle 插件配合完成更复杂的多模块工程管理任务。 #### 注意事项 确保所有涉及的源码目录结构清晰合理;另外还需要注意不同平台下生成动态库的具体命名约定可能有所不同,比如 Linux 下通常以 `.so` 结束而 Windows 则可能是 `.dll` 等情况。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值