【发布时间】:2023-03-07 15:43:02
【问题描述】:
我的项目结构如下:
- CMakeLists.txt // [1]
D Dependencies
-- CMakeLists.txt // [2]
D MySubProject
-- CMakeLists.txt // [3]
[1] 是我的主要 cmake 文件,我在其中明确定义了使用 project(..) 定义的项目,并使用 add_subdirectory(..) 添加了directoires Dependencies 和 MySubProject。
[2] 是一个 cmake 文件,我没有使用 project(..) 显式创建项目。在这里,我只是设置了我的依赖项,例如对于 OpenCV 调用:
find_package(OpenCV REQUIRED)
[3] 是一个 cmake 文件,我在其中明确定义了一个带有 project(..) 的子项目。此子项目链接到 OpenCV 依赖项:
project(MySubProject)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(MySubProject main.cpp)
target_link_libraries(MySubProject ${OpenCV_LIBS})
我遇到的问题是在 [3] 中我无法访问 [2] 的结果,例如OpenCV_LIBS 或 OpenCV_INCLUDE_DIRS。如果我将以下行添加到 [2]
set(OpenCV_LIBS ${OpenCV_LIBS} CACHE STRING "")
set(OpenCV_INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS} CACHE STRING "")
我可以在 [3] 中访问它们,但 OpenCV_LIBS 的内容看起来像
opencv_world.lib
这不适用于我的 OpenCV 3.0 和 MSVC 11 2012 设置。库名称缺少版本后缀。如果我直接调用 [3] 中的 find_package(OpenCV REQUIRED) 命令,OpenCV_LIBS 看起来是正确的,即:
opencv_world330.lib
当我在 [2] 中调用 find_package(..) 并通过将结果变量设置在缓存中使其成为全局变量时,我如何才能获得正确的 OpenCV_LIBS 后缀?
【问题讨论】:
-
换句话说,受
find_package()调用影响的变量集取决于调用发生的目录,不是吗?看起来很奇怪。OpenCV_INCLUDE_DIRS的内容也变了吗? OpenCV 是否安装在项目外部? -
您可以通过添加 -C 将 CMakeCache.txt 文件传递给其他项目的 CMake 运行。这可能是一种解决方法。
-
@Tsyvarev 不,不完全是。我的印象不是目录而是 CMakeLists.txt 的内容有影响。如果它包含一个项目和一个目标定义,则 find_package 命令的行为与仅包含 find_* 命令的 CMakeLists.txt 的行为不同。顺便说一句,OpenCV_INCLUDE_DIRS 的内容没有改变。我使用 Windows x64 的可下载二进制版本。
-
@usr1234567 虽然我不喜欢使用变通方法,但感谢您的提示!也许我遵循了错误的策略,但是将 find_package 调用集中在一个更大的项目中而不是在每个使用相同依赖项的子项目中进行一个相同的 find_package 调用不是更好的方法吗?
-
isn't it a better way to centralize the find_package calls in a greater project- 是的,实际上这将是最佳选择。如果您想将所有依赖项组织到自己的文件中,您可以通过include()包含此文件(在顶级CMakeLists.txt中)。与add_subdirectory()不同,include()不会引入新变量的作用域,因此find_package()设置的所有变量都将在您的项目中全局可见。