在cmake中,如何以可伸缩的方式指定子目录的依赖关系
In cmake, how to specify dependencies of subdirectories in a scalable way?
假设源树的结构如下:
/
|- 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
假设:
- lib1具有函数f()
- lib2有一个函数g(),它使用f()
- app/src.cpp使用函数g()
- 没有人使用lib3
我想要:
- 在app/CMakeLists.txt中,它只链接到lib2。这里的逻辑是,app/src.cpp只使用g(),所以在编写app/src-cpp时,我们不能指定对lib1的依赖关系,因为它是lib2的实现细节。因此,根据这个逻辑,在app/CMakeLists.txt中,它不能有任何与lib1相关的内容,即既不包含lib1的include_directions,也不包括lib1的add_subdirectory,也不包含lib2的target_link_libraries等
- 由于没有人使用lib3,它甚至不会被构建。这需要自动完成。因此,为lib1和lib2手动添加subdirectory,而不是为lib3手动添加。您可以想象,如果我们有一个非常大的源树,具有复杂的树结构和依赖关系,并且在数百个不同的子目录中有数百个可执行文件。如果我只想构建其中的几个,那么我根本不想麻烦构建未使用的库
所以我的问题是:有没有一种方法可以以可扩展的方式编写CMakeLists.txt文件来满足上述要求?如果没有,那么有没有类似的工具可以做到这一点?
谢谢。
对于1个问题:
在lib2/CMakeLists.txt
中,您应该放置以下内容:
target_link_libraries(lib2 lib1)
和应用程序内/CMakeLists.txt:
target_link_libraries(app lib2)
现在,如果您尝试构建应用程序,CMake将检查lib2是否是最新的,如果不是,则重新构建lib1和lib2。
对于2个问题:
您可以使用基于option()
变量的if()
块来保护add_subdirectory(lib3)
调用。
另一种方式-在lib3/CMakeLists.txt中:
add_library(lib3 ${SRCS} EXCLUDE_FROM_ALL)
这将使CMake不将CCD_ 5靶添加到CCD_ 6靶中。如果您试图根据该目标构建某些内容,或者手动发布make lib3
,则仍将构建该目标。
如果库属于第三方或第二方,即您不能或不想修复它们的构建方式,那么您可能更喜欢ExternalProject_Add
而不是add_subdirectory
。
ExternalProject_Add(lib1 /home/me/projects/my_project/lib1 EXCLUDE_FROM_ALL TRUE)
ExternalProject_Add(lib2 /home/me/projects/my_project/lib2 DEPENDS lib1 EXCLUDE_FROM_ALL TRUE)
ExternalProject_Add(lib3 /home/me/projects/my_project/lib3 EXCLUDE_FROM_ALL TRUE)
每个调用都会创建一个由第一个参数命名的目标。此目标可以用作依赖项。DEPENDS
关键字位于外部项目依赖项列表之前。EXCLUDE_FROM_ALL TRUE
声明默认情况下不会生成目标。
确保这些项目正确安装在可到达的位置,以便在构建后相互查看。
文档:https://cmake.org/cmake/help/latest/module/ExternalProject.html
相关文章:
- 如何在c++中为模板函数实例创建快捷方式
- 在c代码之间共享数据的最佳方式
- 在C++中将函数压缩为两种方式
- 以螺旋方式打印矩阵的程序.(工作不好)
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 创建引用向量的优雅方式
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 不同/较旧的处理器运行c++代码的方式是否不同
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 重载方法的方式会在使用临时调用时生成编译器错误
- 在reactor中存储eventHandlers的最佳方式是什么
- 如何以优化的方式同时迭代两个间距不相等的数组
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 为什么C++有不同的变量初始化方式?
- 在cmake中,如何以可伸缩的方式指定子目录的依赖关系
- 为什么在c++中用shell链接查找快捷方式的目标路径时,它指的是windowsinstaller文件夹