如何使用 CMake 获得包含所有项目的 VS 解决方案和单个项目的解决方案

How to get a VS solution with all the projects and solutions for single projects with CMake

本文关键字:解决方案 项目 VS 单个 CMake 何使用 包含所      更新时间:2023-10-16

TL;DR 我基本上想要这个问题的模块化解决方案。不仅一个包含所有内容的解决方案,而且每个可执行文件的解决方案。


在我的问题中,我想知道如何在不同的文件夹中拆分我的CMakeLists.txt。某些文件夹包含的代码将是静态库,而某些代码将是基于这些静态库构建的可执行文件或动态库。

文件夹结构如下所示:

/path/to/base/
CMakeLists.txt
app1/
<src files for app1>
CMakeLists.txt
app2/
<src files for app2>
CMakeLists.txt
lib/
<src files for lib>
CMakeLists.txt

如果我采取在父文件夹中对我的所有库和可执行文件以及从包括所有目录中CMakeLists.txt的方法,我会遇到一个问题,即当我生成 VS 项目/解决方案时,我的每个目标的项目包含所有项目 - 不仅是我的预期目标所需的项目。

基文件夹中CMakeLists.txt的内容:

cmake_minimum_required(VERSION 3.1)
add_subdirectory(lib)
add_subdirectory(app1)
add_subdirectory(app2)

和 app1 文件夹中的CMakeLists.txt(app2 是等效的)

cmake_minimum_required(VERSION 3.1)
project(app1)
add_executable(app1 <src of app1>)
target_link_libraries(app1 lib)

和 lib 的CMakeLists.txt

add_library(lib <src of lib>)

如果我从基础对CMakeLists.txt运行 cmake,则解决方案包含所有项目。即使我只打开其中一个项目;它还包含所有内容。app1 的 VS 项目也构建了 app2 - 我不想要。

如果我只在 app1 的CMakeLists.txt上运行 cmake,我会得到一个不包含 app2 但也不包含 lib 的解决方案,因为这只提到在 cmake 文件内部链接而不是作为目标(它在基本文件中)

> CMake 将为每次调用project创建一个解决方案,然后包括当前目录及其子目录的所有目标(无论它们是在实际调用project之前还是之后定义的)。

下面是一个行为良好的 CMake 脚本应该做的事情:您希望能够在较大项目中充当其自己的子树的根的每个 CMakeList 都应以cmake_minimum_required调用开头,然后是project调用。在 CMakeList 中写入project基本上意味着: 这是一个完全独立的组件,可以独立构建,即使您从其父目录中删除所有文件也是如此。因此,为每个这样的project都有一个单独的解决方案是有意义的。

考虑到这一点,我们可以看到为什么这在您的情况下不起作用:您的应用程序不是完全独立的,它们依赖于lib。对此的解决方案是为应用程序编写构建脚本,就好像lib是作为第三方组件提供的一样,具有find_package调用和所有内容。 在复合构建中,您已经有一个lib的目标,因此find_package调用调用的脚本应该用于短路以使用该目标,并且只有在找不到现有目标时才实际清理系统。

另请阅读CMake的包装系统的工作原理,该系统提供了一些自动化来非常优雅地处理此类情况。