我有一个包含5个项目的Visual Studio解决方案
主要取决于A,B。 A取决于C,D。
我对构建过程有一个脆弱的理解。
libs正在建设中,特别是A;我觉得我没把C和D连接到A.
要构建Main应用程序,我必须将A,B,C和D作为输入库,即使Main只直接依赖于A,B。
现在我正在尝试使用CMake在Linux上构建他的全部内容,并且我发现自己再次暴露于这些链接。这次我不想使用蛮力,更愿意理解这是如何联系在一起的。
我应该将A,B,C和D构建为.a静态库并将Main包括在内吗?
如果没有C和D的符号,A怎么可能建立?
答案 0 :(得分:2)
静态库仅仅是包含目标文件的档案(即,单独编译的源文件)。因此,在构建静态库时,不要“链接”它,而是“归档”它。
链接可执行文件或共享库时必须解析符号。此时链接器尝试解析所有符号,如果不能,则会出现undefined reference
错误。但是,这又与链接有关。静态库不需要在其中定义所有符号。
在您的情况下,如果A
,B
,C
和D
是静态库,则它们将彼此独立构建。从A
和C
构建D
所需的唯一内容是编译器需要的头文件。
在构建可执行文件时,您需要指定所有静态库,即使Main
没有“直接”引用来自C
或D
的符号。
现在,即使静态库不能隐式依赖其他库,CMake也提供了一种在构建系统级别表达此类依赖关系的方法。您可以执行以下操作
add_library(C STATIC ${B_SOURCES})
add_library(D STATIC ${D_SOURCES})
add_library(A STATIC ${A_SOURCES})
target_link_libraries(A PUBLIC C D)
上面的 target_link_libraries
命令不会导致A
与C
和D
链接 - 正如我写的那样,没有静态库工作。相反,它告知CMake,在将可执行文件与A
相关联时,它必须将其与C
和D
相关联:
add_executable(Main ${MAIN_SOURCES})
target_link_libraries(Main PRIVATE A)
即使target_link_libraries
仅包含A
,CMake生成的Makefile也会链接C
和D
- 因为它们被指定为A
的依赖项。
dllexport和dllimport
这两个属性仅适用于共享库(DLL)。它们控制从DLL导出哪些符号(即可从链接到该DLL的可执行文件访问)。 Here's a link在Linux上描述了这个想法和等价物。