C ++构建过程 - lib依赖项

时间:2018-05-30 18:35:45

标签: c++ linux windows build cmake

我有一个包含5个项目的Visual Studio解决方案

  • 主要:申请
  • A,B,C,D:静态库

主要取决于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怎么可能建立?

1 个答案:

答案 0 :(得分:2)

静态库仅仅是包含目标文件的档案(即,单独编译的源文件)。因此,在构建静态库时,不要“链接”它,而是“归档”它。

链接可执行文件或共享库时必须解析符号。此时链接器尝试解析所有符号,如果不能,则会出现undefined reference错误。但是,这又与链接有关。静态库不需要在其中定义所有符号。

在您的情况下,如果ABCD是静态库,则它们将彼此独立构建。从AC构建D所需的唯一内容是编译器需要的头文件。

在构建可执行文件时,您需要指定所有静态库,即使Main没有“直接”引用来自CD的符号。

现在,即使静态库不能隐式依赖其他库,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命令不会导致ACD链接 - 正如我写的那样,没有静态库工作。相反,它告知CMake,在将可执行文件与A相关联时,它必须将其与CD相关联:

add_executable(Main ${MAIN_SOURCES})
target_link_libraries(Main PRIVATE A)

即使target_link_libraries仅包含A,CMake生成的Makefile也会链接CD - 因为它们被指定为A的依赖项。

dllexport和dllimport

这两个属性仅适用于共享库(DLL)。它们控制从DLL导出哪些符号(即可从链接到该DLL的可执行文件访问)。 Here's a link在Linux上描述了这个想法和等价物。