问题 用于多个库和可执行文件的CMakeLists.txt文件


我刚开始玩CMake。我有类似的东西:

/DEV
 |-- lib1
        | CMakeLists.txt

 |-- lib2
        | CMakeLists.txt

 |-- exe1
        | CMakeLists.txt

/BUILD
 |-- lib1
 |-- lib2
 |-- exe1

/INSTALL
 |-- include
 |-- lib
 |-- bin

我想要:

  • 在需要时独立构建每个lib和exe。 (所以我想我必须为每个lib和exe添加一个CMakeLists.txt文件);
  • 构建时,include和lib目录应该引用INSTALL目录; (这是不是一个好主意?)
  • 构建时,将依赖项添加到其他lib并重建它们(如果不是最新的)。

我没有任何线索从哪里开始。请帮忙...


9371
2018-03-12 19:13


起源

除了arrowdodgers优秀的答案:构建一个单独的lib,exe独立也可以通过cd'ing到生成的build-dir为该lib并调用make / msbuild。例如。使用visual studio,如果lib / exe有自己的CMakeLists.txt和project()命令,cmake将为每个lib / exe生成一个解决方案文件 - André


答案:


您不需要单独的CMakeLists.txt来独立构建目标。假设您有一个顶级CMakeLists.txt:

ADD_LIBRARY(lib1 ${all_lib1_files})
ADD_LIBRARY(lib2 ${all_lib2_files})
ADD_EXECUTABLE(exe1 ${all_exe1_files})
TARGET_LINK_LIBRARIES(lib2 lib1)  # lib2 now depends on lib1
TARGET_LINK_LIBRARIES(exe1 lib2)  # exe1 now depends on lib2 and lib1

然后你可以通过运行来构建lib1 make lib1 要么 msbuild lib1.vcxproj您可以通过为每个目标提供单独的CMakeLists.txt文件来实现相同目标 - 如果您认为值得,则由您自己决定。

如果您的项目使用导入这些目标 FIND_LIBRARY 要么 FIND_PACKAGE, 然后他们 惯于 如果它们不是最新的,那就重建一下。最后,如果您想要自动重建过时的依赖项,您需要让CMake了解依赖目标的源和规则,即CMakeLists.txt文件需要使用添加目标 ADD_LIBRARY 要么 ADD_EXECUTABLE

您不应该需要引用INSTALL目录(除了 INSTALL 我想象的命令,因为CMake将在链接目标时隐式使用libs / exes构建位置而不是安装位置。


11
2018-03-13 09:08



似乎是一个更好的解决方案。我必须将CMakeLists.txt文件放在顶层,还是可以将这样的文件放在每个可执行文件夹中?或者是否应该考虑一些“递归魔法”?谢谢! - Korchkidu
在项目的根目录中拥有主CMakeLists.txt是正常的。如果需要,可以将CMakeLists.txt文件添加到每个exe文件夹,然后只需 INCLUDE 每一个。 INCLUDE 以内联方式运行命令,因此这些从属CMakeLists.txt文件不需要完全独立(即它们不需要 PROJECT命令等),它们只是实现项目不同部分分离并保持顶级文件清洁的一种方式。每个人都可以 SET(all_exe1_files ...), ADD_EXECUTABLE(exe1 ${all_exe1_files}) 和 SET_TARGET_PROPERTIES(exe1 ...)。 - Fraser
优秀!非常感谢! - Korchkidu


在需要时独立构建每个lib和exe。

只需添加 EXCLUDE_FROM_ALL 关键字到 add_executable() 要么 add_library() 调用。

构建时,include和lib目录应引用INSTALL   目录

如果通过 referencing 你的意思是添加它 include_directories() 和 link_directories() 然后它不好。最好不要在用户系统上断言所需文件的位置。正确的方法是使用找到所需的包含和库 find_package()find_library() 要么 find_file()。如果你想使用第一个函数,你需要写 FindYourLib.cmake 并沿着库本身安装它。

构建时,将依赖项添加到其他lib,如果没有,则重建它们   最新

这是由CMake自动完成的。可以添加依赖项 add_dependencies() 功能或隐含的 target_link_libraries()


3
2018-03-13 05:56



“那么它现在很好”。这是一个错字还是什么?此外,INSTALL目录中的库是我们自己的,仅供开发人员使用。我们不会分发它们。它们静态链接到由程序包重新分配的可执行文件。因此,我们不希望在系统上真正“安装”我们的库,而是将它们分开。它更有意义吗?感谢您的回答! - Korchkidu
不会重建导入的依赖项。来自CMake的文档:“添加到IMPORTED目标的依赖关系在其位置传递,因为目标本身不构建。”也, EXCLUDE_FROM_ALL 与独立构建目标无关,它只是阻止目标构建为目标的一部分 ALL_BUILD CMake目标。最后,在你的项目中包含另一个CMake项目的正确方法是使用 INSTALL(EXPORT... 在依赖项中命令,然后简单 INCLUDE 出口 <target>.cmake 在你的文件中。跑 cmake --help-command INSTALL 详情。 - Fraser