在cmake中,如何以可伸缩的方式指定子目录的依赖关系?

时间:2012-02-25 00:11:13

标签: c++ cmake build-automation

假设源树在这个结构中:

/
 |- lib1
 |  |- src.cpp
 |  |- lib1.h
 |  |- CMakeLists.txt
 |
 |- lib2
 |  |- src.cpp
 |  |- lib2.h
 |  |- CMakeLists.txt
 |
 |- lib3
 |  |- src.cpp
 |  |- lib3.h
 |  |- CMakeLists.txt
 |
 |- app
 |  |- src.cpp
 |  |- CMakeLists.txt
 |
 |- CMakeLists.txt

假设:

  1. lib1具有函数f();
  2. lib2具有函数g(),它使用f();
  3. app / src.cpp使用函数g();
  4. 没有人使用lib3。
  5. 我想:

    1. 在app / CMakeLists.txt中,它只链接到lib2。这里的逻辑是,app / src.cpp只使用g(),所以在编写app / src.cpp时,我们不能指定对lib1的依赖,因为它是lib2的实现细节。所以根据这个逻辑,在app / CMakeLists.txt中,它不能有任何与lib1相关的东西,即lib1的include_directories,lib1的add_subdirectory,lib1的target_link_libraries等等。
    2. 由于没有人使用lib3,因此甚至不会构建它。这需要自动完成。因此,为lib1和lib2手动add_subdirectory而不是lib3不是一个聪明的方法。您可以想象,如果我们有一个非常大的源树,其中包含复杂的树结构和依赖关系,以及数百个不同子目录中的数百个可执行文件。如果我只想构建其中的几个,那么我根本不想打扰构建未使用的库。
    3. 所以我的问题是:有没有办法以可扩展的方式编写CMakeLists.txt文件以满足上述要求?如果没有,那么是否有一些类似的工具可以做到这一点?

      感谢。

1 个答案:

答案 0 :(得分:4)

对于1个问题:

lib2/CMakeLists.txt中你应该把它放在:

target_link_libraries(lib2 lib1)

在app / CMakeLists.txt中:

target_link_libraries(app lib2)

现在,如果您尝试构建应用程序,CMake将检查lib2是否是最新的,如果不是 - 重建lib1和lib2。

对于2个问题:

您可以根据add_subdirectory(lib3)变量使用if()阻止option()调用{/ p}}。

另一种方式 - 在lib3 / CMakeLists.txt中:

add_library(lib3 ${SRCS} EXCLUDE_FROM_ALL)

这会使CMake不将lib3目标添加到all目标中。如果您尝试根据它构建内容,或者手动发出make lib3,则仍会构建此目标。