我有一个包含5个项目的Visual studio解决方案
应用程序库Main:
Main取决于A,B。A取决于C,D。
我对构建过程的理解很脆弱。
libs单独构建很好,特别是A;我不觉得我是在将C和D与A联系起来。
为了构建主应用程序,我必须使用A、B、C和D作为输入库,即使Main只直接依赖于A、B。
现在我正试图用CMake在Linux上构建整个东西,我发现自己再次接触到了这些链接。这一次,我不想使用暴力,而是更愿意了解这是如何联系在一起的。
我应该只构建A、B、C和D作为.a静态库,并将它们全部包含在Main中吗?
如果没有C和D的符号,A怎么可能构建?
发布于 2018-05-31 07:33:27
静态库仅仅是包含目标文件(即单独编译的源文件)的归档文件。因此,在构建静态库时,您不是“链接”它,而是“存档”它。
在链接可执行文件或共享库时,必须解析符号。此时,链接器会尝试解析所有符号,如果无法解析,则会出现undefined reference
错误。但是,再说一次,这与链接有关。静态库不需要在其中定义所有符号。
在您的示例中,如果A
、B
、C
和D
是静态库,则它们将独立构建。要从C
和D
构建A
,唯一需要的就是头文件,编译器需要这些文件。
在构建可执行文件时,即使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上的等价物。
https://stackoverflow.com/questions/50611405
复制相似问题