免责声明:我是CMakeLists.txt的新手,我有一个有效的实施方案,希望改进和改进它,问题如下所述:
如果我希望root/sub-directories/
作为单独的子项目,可以使用其文件夹中的单个CMakeLists.txts
进行编译,我发现自己几乎可以复制几乎整个根文件CMakeLists.txt
。 。目录
我想知道是否有更好的方法来拥有一个主项目,然后是从主项目获得共享依赖项的子项目,并且可以在没有cmake
的情况下编译根CMakeLists.txt
。我的目录结构是;
CMakeLists.txt(根项目)
| __ sub_dir-1
| __ | __ CMakeLists.txt(子项目)
| __ sub_dir-2
| __ | __ CMakeLists.txt(子项目)
| __ sub_dir-3
| __ | __ CMakeLists.txt(子项目)
...
基本上,我希望能够:
cmake root/CMakeLists.txt
,它创建一个包含子项目的整个项目(我已经在子目录中使用单独的CMakeLists.txts实现了这个。 cmake root/sub-dir/CMakeLists.txt
和仅编译子项目,该子项目基本上也会找到必要的依赖项,并且可能包括.cmake
个包含或root/CMakeLists.txt
。接近这种结构的最佳方法是什么;
sub-dir/CMakeLists.txt
太多了? 感谢任何建议!谢谢。
答案 0 :(得分:13)
有一些策略可行,其中一些可以合并。
策略1:
如果您正在将Unix Makefiles
生成器与CMake一起使用,那么只需从与您要构建的子目录对应的构建输出目录中调用make
,就可以在很大程度上完成您所描述的内容。来自其他目录的目标不会被构建,除非您正在构建的子目录(或其下面的子目录)的目标需要它们。因此,当您从根目录运行CMake时,您仍然只构建所需的子目录。
优点:简单,无需更改CMakeLists.txt
个文件。
缺点:仅适用于Unix Makefiles
生成器,要求CMake处理源树的所有部分是否要构建它们。
策略2:
正如@Emil在对你的问题的评论中所提到的,你可以简单地从构建输出目录的顶层构建你想要的特定目标。这假设您知道要构建的相关目标,或者换句话说,它需要您很好地了解哪些目标由哪些子目录提供。
优点:灵活,适用于任何CMake生成器,无需更改CMakeLists.txt
文件。
缺点:需要了解每个子目录提供的内容,要求CMake处理源树的所有部分是否要构建它们。
策略3:
在顶级CMakeLists.txt
文件中,您可以根据选项变量对每个子目录进行add_subdirectory()
调用。这将允许您单独打开或关闭每个子目录的包含,使您可以精确控制构建的内容。您可以构建所有内容,只需一个子目录或一组子目录(比您的要求更灵活,但可能有用)。
有条件地包含带有选项变量的子目录通常会这样做:
option(BUILD_SUBDIR1 "Enable building subdir1" ON)
option(BUILD_SUBDIR2 "Enable building subdir2" ON)
if(BUILD_SUBDIR1)
add_subdirectory(subdir1)
endif()
if(BUILD_SUBDIR2)
add_subdirectory(subdir2)
endif()
如果某些子目录依赖于其他子目录,那么是否添加子目录的逻辑将需要考虑(即实现选项之间的依赖关系)。如果需要,这不应该很难。
优点:灵活地在一个构建中精确构建您想要的任何子目录集,CMake只需要处理您感兴趣的子目录(为大型项目树节省时间并允许您跳过有问题的部分项目树)并适用于任何CMake生成器。
缺点:如果要单独构建不同的子目录,则需要单独的构建目录。例如,您不能简单cd
到构建输出目录结构的不同部分并从那里运行构建。您仍然只有一个源树,但是您有多个构建输出树。在实践中,这可能不是一个问题,取决于您最终希望能够做什么(我经常为给定的源代码树提供多个构建目录,但这通常用于调试和发布版本而不是不同的集合CMake选项)。还需要了解子目录之间的依赖关系。需要对顶级CMakeLists.txt
文件进行温和更改。
希望上述选项之一或其中某些组合可以为您提供一些如何最终实现目标的想法。我快速浏览了你链接到的github项目中的顶级CMakeLists.txt
,看起来它已经使用了策略3中的选项,只是不能打开/关闭各个子目录。