下面是一组和GPT的对话,通过逐个排查,我们知道只有一种情况会导致符号重定义。以下假设在 CMake
配置环境。
Q:如果一个静态库a
,链接了b
,这个时候 c
链接了 a
和 b
,会导致 b
符号重复定义么?
A:
任何库(静态或动态)本身都不链接其他库。他们可能有对其他库的依赖性,但实际上并不包含其他库的代码。
在你给出的情况下,假设你有三个静态库a
、b
和一个可执行目标c
。
库a
使用了库b
中的一些符号(函数或变量);
目标c
链接了库a
和库b
。
在这种情况下,不会出现符号重复定义的问题,因为库a
并不会“包含”库b
,只是有对它的依赖性。链接器在链接可执行文件c
时,它会从库a
和库b
中提取所需的对象文件,如果同一符号在两个库中都找到了,链接器会选择其中一个(具体选择哪个取决于链接器的行为)。
然而需要注意的是,静态库的链接顺序是重要的。在上面的例子中,由于库a
依赖于库b
,所以在链接目标c
时,应该先链接库a
,然后再链接库b
,这样链接器才能正确解析库a
中对库b
的依赖。以下是在CMakeLists.txt中进行链接的示例:
target_link_libraries(c a b)
如果链接命令写成了 target_link_libraries(c b a)
,那么可能会出现未定义的符号错误。这是因为当链接器处理库b
时,它并不知道后面还有对这些符号的引用。
Q: 如果一个静态库a
,链接了b
,这个时候可执行程序 c
链接了 a
和 b
,会导致 b
符号重复定义么?
A:
在你的情况下,即使静态库a
有对静态库b
的依赖性,并且可执行程序c
同时链接了库a
和库b
,通常也不会出现符号重复定义的问题。
这是因为静态库并没有真正地“链接”其他静态库。当静态库a被编译时,它可能需要库b
中的符号(例如函数或变量),但是库b
的代码并没有被合并到库a
中,库a
只是有对库b
的依赖性。
然后,当链接可执行程序c
时,链接器将查看c
以及所有传递的库(在本例中为a
和b
)所需的所有符号,并从这些库中拉取需要的对象文件来满足这些需求。这意味着每个必要的符号只会被包含一次,而不会被重复包含。
请注意,虽然不会出现符号重复定义的问题,但可以会出现未解析的符号错误。这可能发生在库b
先于库a
被链接时。由于库a
依赖库b
,库b
应该在库a
之后链接,以便链接器能正确解析所有符号。所以正确的链接顺序应该是:
target_link_libraries(c a b)
而不是:
target_link_libraries(c b a)
Q: 如果一个动态库 a
链接了 b
,这个时候可执行程序 c
链接了 a
和 b
,会导致 b
符号重复定义么?
A:
在你的情况下,动态库(Shared Library)a
依赖于另一个动态库 b
,而可执行程序c
同时链接了a
和b
,这通常不会导致符号重复定义的问题。
对于动态库来说,它们在编译时并不包含其依赖库的代码。相反,动态库在运行时才解析它们的依赖关系。也就是说,如果动态库a
依赖于动态库b
,那么当程序加载库a
时,操作系统(通过动态链接器)将负责加载库b
(如果尚未加载)。
因此,即使可执行程序c
同时链接了a
和b
,也只有一份库b
的实例被加载到内存中。库a
和c
中引用库b
的符号都将解析到这同一份实例,所以不会有符号重复定义的问题。
然而,请注意确保动态库的正确路径,特别是在运行可执行程序c
时,库a
和b
必须能够被找到。一般来说,这需要将它们放置在标准库路径下,或者修改环境变量(如LD_LIBRARY_PATH
在Linux下,DYLD_LIBRARY_PATH
在MacOS下),以包含这些库的路径。
Q: 如果一个动态库a
链接了静态库 b
,这个时候可执行程序 c
链接了 a
和 b
,会导致 b
符号重复定义么?
A:
在你的情况下,动态库 a
链接了静态库 b
,然后可执行程序 c
又链接了动态库 a
和静态库 b
。这种情况可能会导致符号重复定义。
当一个动态库(如 a
)链接一个静态库(如 b
)时,静态库 b
中的所有对象代码实际上都会被包含到动态库 a
中。所以当你分别将动态库 a
和静态库 b
链接到可执行文件 c
时,因为动态库 a
已经包含了静态库 b
的所有代码,所以相同的符号实际上被包含了两次,这就可能导致符号重复定义。
解决这个问题的一种方法是只在一个地方链接静态库 b
。也就是说,要么只在动态库 a
中链接静态库 b
(然后在可执行程序 c
中只链接动态库 a
),要么在动态库 a
和可执行程序 c
中都不链接静态库 b
(而是只在链接可执行程序 c
时链接静态库 b
)。这样可以确保静态库 b
的代码只被包含一次,从而避免符号重复定义。
--end--
标签:定义,符号,静态,链接,动态,可执行程序 From: https://www.cnblogs.com/math/p/how_to_resolve_multi_define_symbols.html