这里有一个基本的问题(可能是dup,但到目前为止我找不到合适的答案,即使在How does the compilation/linking process work?中),关于C
++中的库链接和使用CMake时可能的特殊性。
当给定库的二进制文件在应用程序的依赖关系图中出现多次时(以类似菱形的模式),如何管理它?
假设A
和B
是两个库,C
是一个应用程序。A
依赖于B
C
依赖于A
,但也直接依赖于B
(B
的符号在C
代码中提到)
我的问题分为以下几个部分
1-A
正在暴露来自B
的符号(B
的符号在A
接口中提到)
a.没有cmake
如果我用-l A -l B
编译C
,用-l B
编译A
:在C
中会有多少个B
二进制文件的副本?A
和B
的性质是否会改变答案(根据A
和B
是否是动态的,因此给出4种可能性)
B.使用cmake
同样的问题,但不是-l
,而是find_package
,然后是target_link_libraries
。
(A
和B
应该正确打包和安装,以便被find_package
发现)C
包括A
和B
,如PRIVATE
A
包括B
作为PUBLIC
2-A
未暴露B
a.没有cmake
如果我用-l A -l B
编译C
,用-l B
编译A
:在C
中会有多少个B
二进制文件的副本?A
和B
的性质是否会改变答案(根据A
和B
是否是动态的,因此给出4种可能性)
B.使用cmake
同样的问题,但不是-l
,而是find_package
,后面是target_link_libraries
C
包括A
和B
,如PRIVATE
A
包括B
作为PRIVATE
[编辑]附加上下文这个问题出现在嵌入式上下文中,在使用共享或静态库之间存在争议。在钻石包含的情况下,我们担心系统上的二进制文件大小会无用地增加,并希望得到一个比“在某些设备上尝试它,希望它在任何地方都是相同的行为”更通用的答案。
1条答案
按热度按时间5f0d552i1#
你的担心是对的。很多年前我在Windows中有过一次不好的经历。我不确定你的嵌入式系统是否会同样工作,但原理可能是相似的。
如果你所有的库都是静态的或者都是动态的,你可能不会有问题。
但是如果你有一个依赖于静态库的动态库,那么这个静态库将被链接到动态库中。如果另一个动态库需要同样的静态库,它也会得到一个副本。应用程序将得到它自己的副本。
在我的例子中,我们在静态库中使用了单例,它们使用静态变量来确保单一性。由于库有多个副本,因此变量也有多个副本,单例不再那么单一。混乱随之而来。