c++ - 使用CMake在特定于应用程序的子文件夹中查找依赖项

标签 c++ opencv image-processing boost cmake

尽管对大型C++应用程序进行了多年编码,但我不了解find_package在中等大小的CMake项目中应该如何工作,我想自己将源代码构建为依赖包,而不仅仅是依赖大型系统例如opencv,pcl或boost安装在系统文件夹中的某个位置。我不敢相信我是世界上唯一发布过多个OpenCV和其他开源应用程序,在大型游戏项目上使用过NAnt和SCons等元构建系统的人,但是了解有关CMake的工作原理的最基本知识,或找到回答这些问题的教程。

过去,我基本上是通过手动设置所有foo_DIR值来解决不必要的find_package的问题,因为CMake会抱怨直到获得工作文件夹。

我想举一个我现在正在研究的简单示例,非常希望有人可以解释我做错了什么。

首先,一些假设:
我想通过CMakeGUI为MacOS和Windows都构建所有东西。 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_install文件夹中

“获取目录”显示了一系列用于下载依赖项的文件夹。我假设有一个约定,其中和是源存储库,它们后面的_build文件夹是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中找到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。但是我很想了解我想(当然并不少见)用例想要控制我的项目依赖关系而不是仅仅使用sudo port install *并将随机版本的项目安装到我的全局系统文件夹中的情况,对于find_package我缺少什么。

最佳答案

如错误消息所述,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。

关于c++ - 使用CMake在特定于应用程序的子文件夹中查找依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38490911/

相关文章:

python - OpenCV DestroyWindow 在 Ubuntu 上不工作。如何正确关闭窗口?

python - 在 Raspberry PI 上构建时出现 OpenCV 错误

language-agnostic - 如何找到方形图案角的像素坐标?

c++ - 在 C++ 中返回一个大数

c++ - 位模式匹配和替换

c++ - std::back_inserter 在旧的 GCC 上需要 const_reference。为什么?

c++ - 将 MATLAB 代码转换为 OpenCV C++

c++ - 如何为类重载运算符 +()

c++ - CUDA侵 eclipse 算法

c++ - OpenCV 中的 Matlab Conv2 等效项