如何针对库的一个版本制作/构建项目,但其依赖关系针对该库的不同版本?

How to make/build project against one version of a library but its dependencies against a different version of that library?

提问人:MsA 提问时间:10/14/2023 最后编辑:Christoph RackwitzMsA 更新时间:10/17/2023 访问量:52

问:

我的工作空间结构如下所示。它涉及项目、第三方库和依赖项目(以及工作区)。我还在括号内指定了它们的依赖关系,在它们旁边。PROJTPLDEP-PROJws

ws   
├── opencv34
│   ├── opencv
│   └── opencv_contrib
├── opencv44
|   ├── opencv
|   └── opencv_contrib
├── DEP-PROJ (opencv 3.4)
└── PROJ (DEP-PROJ, opencv 4.4)
    └── TPL (opencv 4.4) 

我已经用 和 命令构建了两个版本的 opencv。但是没有跑.cmake ..make -j6make install

接下来,在其CMakeLists.txt(注意)中有以下行:DEP-PROJOPENCV3_DIR

set(OpenCV_DIR $ENV{OPENCV3_DIR})
find_package(OpenCV 3.4 REQUIRED) 

在目录中执行之前,我运行 ,以便成功。cmakeDEP-PROJ/buildexport OPENCV3_DIR=/ws/opencv34/opencv/buildcmake

接下来,在其CMakeLists.txt(注意)中有以下行:PROJOPENCV4_DIR

set(OpenCV_DIR $ENV{OPENCV4_DIR})
find_package(OpenCV 4.4 REQUIRED)

接下来,在目录中执行操作之前,我运行 ,以便成功。cmakePROJ/buildexport OPENCV4_DIR=/ws/opencv34/opencv/buildcmake

在目录中执行之前,我运行 ,以便成功。cmakePROJ/buildexport OPENCV4_DIR=/ws/opencv44/opencv/buildcmake

这会导致 cmake 成功,但 make 失败并出现错误:

fatal error: opencv/cv.h: No such file or directory

似乎做内部重建.但是,CMakeLists.txt 设置为目录。这使得构建失败,出现上述错误。PROJDEP-PROJPROJOpenCV_DIRopencv44DEP-PROJ

为了避免这种情况,我跑进去.这样就可以从目录中找到 opencv 3.4 并从目录中引用 opencv 4.4,从而成功构建 .make install/ws/opencv34/opencv/buildDEP-PROJ/usrPROJ/ws/opencv44/opencv/buildPROJ

但是,我觉得解决这个问题的方法有点笨拙(在 opencv 3.4 中执行而不是在 opencv 4.4 中执行)。正确的方法是什么?如何避免在构建时重建?或者针对(而不是 opencv in )以及针对 ?make installDEP-PROJPROJ/ws/opencv34/opencv/build/usrPROJ/ws/opencv44/opencv/build

PS:我是cmake的菜鸟。

C++ cmake makefile 动态链接 cmakelists-options

评论

0赞 Christoph Rackwitz 10/14/2023
这并不是 OpenCV 所特有的。这是动态链接的普遍问题。使用静态链接,这不是问题。但是,法律问题使许多库无法静态链接。
0赞 MsA 10/14/2023
但是必须有一些 cmake 配置或其他东西,通常用于解决此类问题?
1赞 Christoph Rackwitz 10/14/2023
在不阅读整个问题的情况下,假设 A 依赖于 B 和 C2,但 B 也依赖于 C1。你是希望运行一个可以完成所有操作的单个构建,还是单独构建 B,以便您可以在 A 的构建中使用它
2赞 John Bollinger 10/15/2023
[...]也有可能并且需要交换基于 OpenCV 版本的不同数据结构。如果幸运的话,这将表现为编译时错误,但如果你运气不好,它可能会表现为神秘、奇怪的运行时行为。PROJDEP-PROJ
1赞 John Bollinger 10/16/2023
DEP-PROJ 的 CMakeLists.txt 中的硬编码路径会有所帮助[...]?-- 它可能有助于获得成功的构建。它根本无法解决双 OpenCV 依赖项的任何整体问题。CMake 的 ExternalProject_Add 模块能否帮助在构建 PROJ 时使用独立构建的 DEP-PROJ--可能不是。它可能会改变生成依赖项的性质,但不会为你提供独立的生成。

答:

1赞 Employed Russian 10/17/2023 #1

TL;DR:在 UNIX 上在同一进程中混合单个库的多个版本是行不通的,放弃吧!


您似乎正在为 UNIX 构建。

与 Windows 不同,UNIX 共享库不是自包含的,它容易受到符号插入和符号冲突的影响。

此外,OpenCV 版本 3.4 和 4.4 定义了相同的符号,并且 ABI 不兼容。

综上所述,上述两个语句意味着,如果您设法将项目与 OpenCV 的 3.4 和 4.4 版本动态链接,几乎可以保证您会遇到莫名其妙的崩溃、内存损坏等。

(如果尝试将项目与存档版本链接,则很可能会因多个符号定义而失败。