【发布时间】:2016-07-20 21:11:19
【问题描述】:
尽管多年编写大型 C++ 应用程序,我不明白 find_package 应该如何在中型 CMake 项目中工作,假设我想自己构建依赖包的源而不是简单地依赖在诸如 opencv、pcl 或 boost 之类的大型系统上安装在系统文件夹中的某处。我不敢相信我是世界上唯一一个发布过多个 OpenCV 和其他开源应用程序、在大型游戏项目中使用元构建系统(如 NAnt 和 SCons)的人,但我不能了解有关 CMake 工作原理的最基本知识或查找回答这些问题的教程。
过去,我基本上是通过手动设置所有 foo_DIR 值来解决不理解 find_package 的问题,因为 CMake 会抱怨,直到我得到一个工作文件夹。
我想通过一个我现在正在研究的简单示例来运行,并非常希望有人能解释我做错了什么。
首先,一些假设: 我想为 MacOS 和 Windows 构建所有东西,最好是通过 CMakeGUI。 MacOS 应该构建 XCodeProjects,Windows 应该构建 Visual Studio 解决方案。
有依赖的地方,我想自己编译,所以我有调试符号,可以修改依赖源(或者至少调试进去。) 不将预构建的二进制文件安装到系统文件夹中,即在 mac 上不使用 sudo port install opencv/pcl 等。 我有多个项目,并且更喜欢将一个项目及其依赖项保存在一个文件夹中。 出于具体示例的目的,假设我正在构建这个项目,尽管它是一个任意选择来说明我所遭受的过程和困惑:
https://github.com/krips89/opendetection
这列出了依赖项,我特意在此处重新排序,以便我可以按顺序排列它们,如下所示:
find_package(OpenCV REQUIRED)
find_package(Eigen REQUIRED)
find_package(Boost 1.40 COMPONENTS program_options REQUIRED )
find_package(PCL REQUIRED)
find_package(VTK REQUIRED)
我希望将所有这些依赖项下载并配置在单个路径中(假设为 Windows 上的 c:\src 和 Mac 上的 ~\src),而不是系统路径。假设实际文件夹是该项目的子文件夹,而不是所有项目的子文件夹。这也应该允许在同一台计算机上并行安装多个项目。
一步一个脚印:
(1) 我从https://github.com/opencv/opencv 克隆openCV,同步到标签3.1,配置到opencv_build 文件夹中,构建并安装到opencv_install 中。我已经这样做了很多次,这很简单。 (2) 同上,但对于 eigen(虽然为 eigen 构建实际上并没有做任何事情,因为它是一个模板库。我安装到一个文件夹 eigen_install
Taking 目录显示了一系列用于下载依赖项的文件夹。我假设了一个约定 where 和 是源代码库,它们下面的 _build 文件夹是 CMakeGui 中的“WHere to build the binaries”文件夹。
$ ls
boost_1_40_0 opencv opendetection_build
eigen opencv-build opendetection_data
eigen_build opencv_contrib pcl
eigen_install opendetection
到目前为止一切顺利,现在让我们尝试配置 opendetection 并在 opendetection_build 中生成解决方案,并在 ~/src 文件夹中找到 pendetection 的依赖项,即前两个依赖项,我希望在 opencv-build 和 eigen-build 文件夹中找到 opencv 和 eigen。
OpenCV 立即失败,正如预期的那样:
Could not find a package configuration file provided by "OpenCV" with any of the following names:
OpenCVConfig.cmake
opencv-config.cmake
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set "OpenCV_DIR" to a directory containing one of the above files. If "OpenCV" provides a separate development package or SDK, be sure it has been installed.
很好,因为我想明确告诉 CMake 在我的 ~/src 文件夹下查找依赖包。问题:使用 CMAKE_PREFIX_PATH=/users/foo/src 是否是完成我想要的推荐方式 - 在特定路径下查找所有子包?
之后,CMake 找到 OpenCV(良好),并设置 OpenCV_DIR = /Users/foo/src/opencv-build。
问题:鉴于我已经对 opencv-install 进行了“安装”(使用 CMAKE_INSTALL_PREFIX 并构建 OpenCV 的安装目标,它不应该在 opencv-install 文件夹中找到 OpenCV 而不是 opencv-build 吗?
继续 eigen,我已经配置并构建了 eigen,并将其安装到 ~/src/eigen-install,因为它是 CMAKE_PREFIX_PATH (~/src) 的子文件夹,我可能希望找到它。但似乎并非如此。有人可以向我解释我不明白的地方吗?特别是考虑到模板库中的 Eigen,并且在 CMAKE_PREFIX_PATH 下至少有三个文件夹(eigen、eigen_build 和 eigen_install),我认为 CMake 会在其中找到一些东西,我想我一定是在这里做错了。我从过去的经验中知道,我可以在 CMakeGUI 中手动设置 EIGEN_INCLUDE_DIR,然后继续破解,但这似乎是错误的。
我非常愿意为未来像我一样愚蠢的人写一个网页来解释这一点,如果还没有的话,虽然我不明白如何使用 CMake 进行基本项目配置和生成显然如此对每个人都很明显,但对我来说却很不透明。我实际上已经使用 CMake 几年了,通常只是手动设置 Boost_INCLUDE_Dir、Foo_INCLUDE_PATH 等,但显然这不是正确的解决方案。通常,在花费几天时间通过各种包通过手动设置 INCLUDE PATHS、LIBRARY PATHS 和其他选项来生成解决方案后,我只是处理解决方案,不再接触 CMake。但是我很想了解我对 find_package 的遗漏,因为我想要控制我的项目依赖项的(当然并不少见)用例,而不仅仅是使用 sudo port install * 并将随机版本的项目安装到我的全局系统文件夹中。
【问题讨论】:
标签: c++ opencv image-processing boost cmake