使用cmake创建主项目和子项目,并能够单独编译它们

时间:2016-03-01 20:26:40

标签: cmake

免责声明:我是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(子项目)
...

基本上,我希望能够:

  1. cmake root/CMakeLists.txt,它创建一个包含子项目的整个项目(我已经在子目录中使用单独的CMakeLists.txts实现了这个。
  2. cmake root/sub-dir/CMakeLists.txt编译子项目,该子项目基本上也会找到必要的依赖项,并且可能包括.cmake个包含或root/CMakeLists.txt 。接近这种结构的最佳方法是什么;

    • 同时保留了能够将其编译为整个项目的第一个要点。
    • 使用冗余代码也不会拥挤 sub-dir/CMakeLists.txt太多了?
  3. 感谢任何建议!谢谢。

1 个答案:

答案 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中的选项,只是不能打开/关闭各个子目录。