如何从上级目录CMakeLists.txt继承路径?TPL依赖差异解惑
原因分析
1. TPL2正常编译的原因
当在PROJ2/build执行CMake时,PROJ2的CMakeLists已设置OpenCV_DIR并成功定位到OpenCV 4.4。CMake的缓存变量是全局生效的,当PROJ2通过add_subdirectory引入TPL2时,TPL2中的find_package(OpenCV)会直接复用上级已缓存的OpenCV_DIR及关联变量(如OpenCV_INCLUDE_DIRS、OpenCV_LIBS),因此无需重复设置OpenCV_DIR也能找到依赖。
2. TPL1移除set语句报错的原因
这说明PROJ1与TPL1的依赖传递存在问题,分两种可能:
- 单独编译TPL1:如果直接在
TPL1目录下执行CMake,此时没有上级项目设置OpenCV_DIR,且OpenCV未安装到系统默认路径(未执行make install),find_package无法定位到OpenCV,导致头文件找不到。 - 作为PROJ1子项目仍报错:可能是
PROJ1在引入TPL1时,未通过target_link_libraries或target_include_directories将OpenCV的依赖传递给TPL1的目标;或是TPL1的CMakeLists未正确使用上级传递的依赖变量。
实现第三方库继承上级路径的配置方法
1. 目标传递机制(推荐)
在上级项目(如PROJ1)中,找到OpenCV后,将其目标链接到TPL1的目标,依赖会自动传递:
# PROJ1的CMakeLists.txt set(OpenCV_DIR $ENV{OPENCV4_DIR}) find_package(OpenCV 4.4 REQUIRED) add_subdirectory(TPL1) # 假设TPL1生成的目标为tpl1,PROJ1的目标为proj1 target_link_libraries(proj1 PRIVATE tpl1 ${OpenCV_LIBS}) # 或直接将OpenCV依赖传递给TPL1 target_link_libraries(tpl1 PRIVATE ${OpenCV_LIBS})
此时TPL1的目标会自动继承OpenCV的头文件路径、库路径等,无需在TPL1中重复执行find_package或设置OpenCV_DIR。
2. 设置缓存变量
在上级项目中将OpenCV_DIR设为缓存变量,子项目可直接读取:
# PROJ1的CMakeLists.txt set(OpenCV_DIR $ENV{OPENCV4_DIR} CACHE PATH "Path to OpenCV 4.4 build directory") find_package(OpenCV 4.4 REQUIRED)
这样TPL1中的find_package(OpenCV)会自动使用上级缓存的OpenCV_DIR,无需手动设置。
3. 环境变量全局传递
直接在终端设置环境变量OPENCV4_DIR,所有CMake项目均可读取:
export OPENCV4_DIR=/path/to/your/opencv-4.4.0/build
设置后执行cmake和make,所有项目无需手动配置OpenCV_DIR即可找到依赖。
内容的提问来源于stack exchange,提问作者MsA
相关产品推荐
相关产品推荐

