网上关于 target_link_libraries 中的 PRIVATE, PUBLIC , INTERFACE 的解释大部分是错的,而且不是一般的错,是胡说。 因为这三个属性在不同的命令中使用时意义不同,有很多是从target_include_libraries中抄来的。
以下的解释主要场景是linux中,windows不存在这种关系,无需考虑。
我们来解释下,假设我们有一个程序 A , A调用库B, B调用库C.
A -> B -> C
A link B时不管是private还是public都没关系,毕竟A不需要导出符号,也没有人以API方式调用它。
现在主要问题就是B这个库用private还是public. C是动态库。
如果B是动态或静态库,C是动态库,这个问题就会有影响。同样,如果B、C同为静态库时也会有问题。
B用private link C, 此时A link B,但是不知道B->C这层关系,可以正常link B. 运行时,A->B->C 时,B找不到C中的函数。linux下没有直接依赖关系,所有的B/C的依赖都会转到到A下,可以用LDD命令验证,此时A只依赖于B, 不见C, 当B中的函数调用C中的函数时,因为没有加载C, 所以报找不到符号错误。解决的办法就是在A link B时,同样也写上C. 但是因为private的原因,A是不知道C中的符号这事,只能强制 link C到A才能解决。
如果B link C时用public 指示, 当编译A时,就会检查到C中的符号没有实现,此时你就会知道要把C link到A来解决这个问题了。
其实private/public 解决的是指示问题,本质上可以使用public 来解决, 可以减少坑。
下面是target_link_libraries中的解释,不想看英文的,直接拉到最后。
Link Inheritance
Similarly, for any target
, in the linking stage, we would need to decide, given the item
to be linked, whether we have to put the item
in the link dependencies, or the link interface, or both, in the compiled target
. Here the link dependencies means the item
has some implementations that the target
would use, and it is linked to the item
, so that whenever we call the functions or methods corresponding to those implementations it will always be mapped correctly to the implementations in item
via the link, whereas the link interface means the target
becomes an interface for linking the item
for other targets which have dependencies on the target
, and the target
does not have to use item
at all.
Link Type | Description |
---|---|
PUBLIC | All the objects following PUBLIC will be used for linking to the current target and providing the interface to the other targets that have dependencies on the current target. |
PRIVATE | All the objects following PRIVATE will only be used for linking to the current target. |
INTERFACE | All the objects following INTERFACE will only be used for providing the interface to the other targets that have dependencies on the current target. |
For example, if the fruit
library has the implementation of functions, such as size
and color
, and the apple
library has a function apple_size
which called the size
from the fruit
library and was PRIVATE
linked with the fruit
library. We could create an executable eat_apple
that calls apple_size
by PUBLIC
or PRIVATE
linking with the apple
library. However, if we want to create an executable eat_apple
that calls the size
and color
from the fruit
library, only linking with the apple
library will cause building error, since the fruit
library was not part of the interface in the apple
library, and is thus inaccessible to eat_apple
. To make the apple
library to inherit the size
and color
from the fruit
library, we have to make the linking of the apple
library to the the fruit
library PUBLIC
instead of PRIVATE
.
下面用人话(汉语)翻译下:
PUBLIC 在public后面的库会被Link到你的target中,并且里面的符号也会被导出,提供给第三方使用。
PRIVATE 在private后面的库仅被link到你的target中,并且终结掉,第三方不能感知你调了啥库
INTERFACE 在interface后面引入的库不会被链接到你的target中,只会导出符号。
---- 更新----------
target_link_libraries 会在目标程序中生成rpath, 这点请注意 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2022-07-19 李超:WebRTC传输与服务质量
2021-07-19 FFmpeg内存模型与API介绍(notes 2)
2018-07-19 centOS7服务管理与启动流程
2018-07-19 CentOS 6和CentOS 7防火墙的关闭
2018-07-19 linux 系统安装配置 zabbix服务(源码安装)
2018-07-19 zabbix_agentd客户端安装与配置(Linux操作系统)
2018-07-19 zabbix_agentd客户端安装与配置(windows操作系统)