使用CMake在特定于应用程序的子文件夹

时间:2016-07-20 21:11:19

标签: c++ opencv image-processing boost cmake

尽管对大规模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

记录目录显示了一系列用于下载依赖项的文件夹。我已经假设了一个约定,其中,并且是源代码库,并且它们的以下_build文件夹是" WHere来构建二进制文件" CMakeGui中的文件夹。

$ 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。

问题:鉴于我已经安装了#34;安装" to 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 *并将项目的随机版本安装到我的全局系统文件夹中。

1 个答案:

答案 0 :(得分:2)

如错误消息所示,CMAKE_PREFIX_PATH应设置为包的安装前缀。例如,如果使用CMake构建了包,则这是CMAKE_INSTALL_PREFIX变量的值,如果使用Autotools构建包,则这是用于配置它的--prefix选项的值,并且等等。

CMake没有搜索CMAKE_PREFIX_PATH下的每个目录。如果您在/users/foo/src安装了软件包,那么将其指定为/users/foo/src/eigen-install是没用的。

相反,您可以将所有 3d-party软件包安装到/users/foo/src/install中,并在主项目中将该路径用作 CMAKE_PREFIX_PATH