C++ C++;构建流程库依赖项

C++ C++;构建流程库依赖项,c++,linux,windows,build,cmake,C++,Linux,Windows,Build,Cmake,我有一个包含5个项目的VisualStudio解决方案 主:应用程序 A、 B、C、D:静态库 主要取决于A,B。A取决于C,D 我对构建过程的理解很薄弱 LIB一家在建房子,特别是在建房子;我觉得我没有把C和D和A联系起来 为了构建主应用程序,我必须将A、B、C和D作为输入库,即使Main只直接依赖于A、B 现在我正试图用CMake在Linux上构建整个系统,我发现自己再次接触到了这些链接。这一次,我不想使用暴力,我更愿意理解这两者是如何联系在一起的 我应该只构建A、B、C和D作为静态库,

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

  • 主:应用程序
  • A、 B、C、D:静态库
主要取决于A,B。A取决于C,D

我对构建过程的理解很薄弱

LIB一家在建房子,特别是在建房子;我觉得我没有把C和D和A联系起来

为了构建主应用程序,我必须将A、B、C和D作为输入库,即使Main只直接依赖于A、B

现在我正试图用CMake在Linux上构建整个系统,我发现自己再次接触到了这些链接。这一次,我不想使用暴力,我更愿意理解这两者是如何联系在一起的

我应该只构建A、B、C和D作为静态库,并让Main包含它们吗


如果没有C和D的符号,A怎么可能构建呢?

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

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

在您的情况下,如果
A
B
C
D
是静态lib,则它们将彼此独立构建。从
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\u link\u库
命令不会导致
A
C
D
链接-正如我所写的,这不是静态libs工作的原因。相反,它通知CMake,当将可执行文件链接到
A
时,它还必须将其链接到
C
D

add_executable(Main ${MAIN_SOURCES})
target_link_libraries(Main PRIVATE A)
即使
target\u link\u库
只包含
A
,CMake生成的Makefile也会链接
C
D
,因为它们被指定为
A
的依赖项


dllexport和dllimport


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

如果没有C和D中的符号,A如何构建?
-静态库没有链接,因此它们不需要定义其他库中的符号
我是否应该将A、B、C和D构建为.A静态库,并让Main包含所有这些库?
-如果这样做有效,为什么需要找到其他方法?对于我来说,应用程序应该包含二级依赖项是没有意义的。如果依赖关系更深,这将意味着我必须包含整个链。您可能需要共享库-它们与依赖关系链接,并将链接存储在其中。我从我的队友那里看到了一些代码,其中包括带有一些混乱宏的附加标题:u declspec(dllexport/dllimport),我现在还不明白,回答得很好!非常感谢。只是为了讨论和澄清一个特定的案例。如果A和B都依赖于C,并且我使用目标链接库(…),这是否意味着我在构建Main时会从C添加两次代码?不,C只链接一次。CMake将以正确的顺序将库传递给链接器(因为当库之间存在依赖关系时,
ld
需要以正确的顺序传递lib),而不会不必要地复制它们。我认为只有当lib之间存在循环依赖关系时,才可以多次提到lib。顺便说一句-如果您使用CMake的Makefile生成器,您可以通过将
CMake\u VERBOSE\u Makefile
设置为
YES
来查看生成的命令。