【问题标题】:CMakeLists.txt files for multiple libraries and executables多个库和可执行文件的 CMakeLists.txt 文件
【发布时间】:2012-03-29 05:19:30
【问题描述】:

我刚开始玩 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目录; (这是个好主意吗?)
  • 构建时,将依赖项添加到其他库,如果不是最新的,则重新构建它们。

我不知道从哪里开始。请帮忙...

【问题讨论】:

  • 除了 arrowdodgers 出色的答案:构建单个库,exe 也可以通过 cd 进入该库生成的构建目录并调用 make/msbuild 来独立完成。例如。使用 Visual Studio,如果 lib/exe 有自己的 CMakeLists.txt 和 project() 命令,cmake 将为每个 lib/exe 生成一个解决方案文件

标签: cross-platform cmake cross-compiling


【解决方案1】:

您不需要单独的 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

然后,您可以通过运行 make lib1 或 msbuild lib1.vcxproj 等来构建 lib1。您可以通过为每个目标设置单独的 CMakeLists.txt 文件来实现相同的目标 - 如果您认为值得,这取决于您。

如果您的项目使用 FIND_LIBRARY 或 FIND_PACKAGE 导入这些目标,那么如果它们不是最新的,则不会重新构建。最后,如果你想自动重建过期的依赖,你需要让CMake知道依赖目标的来源和规则,即CMakeLists.txt文件需要使用ADD_LIBRARY或@添加目标987654327@.

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

【讨论】:

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

到

在需要时独立构建每个 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 并将其安装到库本身。

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

这是由 CMake 自动完成的。可以使用add_dependencies() 函数添加依赖关系,也可以使用target_link_libraries() 隐式添加依赖关系。

【讨论】:

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