CMake安装的二进制文件无法链接自定义编译的OpenCV问题
问题:CMake安装后的二进制无法找到自定义编译的OpenCV库
问题详情
通过CMake构建并安装的二进制文件,依赖自定义编译的OpenCV(路径/home/user/opencv)。本地构建目录中的二进制可正常链接并运行,但安装后的版本提示找不到libopencv_core.so.406等依赖库。
最小复现示例
CMakeLists.txt:
cmake_minimum_required(VERSION 3.25) project(bad_opencv_install) list(APPEND CMAKE_PREFIX_PATH "/usr/local/cuda-11.4") set(CMAKE_CXX_STANDARD 11) set(OpenCV_DIR "$ENV{HOME}/opencv/lib/cmake/opencv4") message("OpenCV_DIR = ${OpenCV_DIR}") find_package(OpenCV 4 REQUIRED COMPONENTS cudaimgproc) add_executable(foo main.cpp) target_link_libraries(foo PUBLIC opencv_cudaimgproc) install(TARGETS foo DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/installed/)
main.cpp:
#include <iostream> #include <opencv2/cudaimgproc.hpp> int main() { cv::cuda::GpuMat mat; std::cout << "All good" << std::endl; }
现象对比
- 本地构建二进制可正常运行:
user@xd:~/bad_opencv/build$ ./foo All good - 安装后的二进制运行报错:
user@xd:~/bad_opencv/build$ ./installed/foo ./installed/foo: error while loading shared libraries: libopencv_core.so.406: cannot open shared object file: No such file or directory ldd结果显示,安装后的二进制丢失了自定义OpenCV库的路径信息。
原因分析
从构建日志中可以看到关键信息:
-- Set runtime path of "/home/user/bad_opencv/build/installed/foo" to ""
CMake默认在执行install时会清空二进制的运行时路径(RPATH),因为通常安装后的二进制会部署到系统标准路径,依赖库也在系统库目录中。但这里依赖的是自定义路径下的OpenCV,因此需要显式指定安装后的RPATH。
解决方案
以下几种方法均可解决该问题,选择适合自己的方式即可:
方法1:全局设置安装RPATH
在CMakeLists.txt中添加全局RPATH配置,所有安装的目标都会生效:
# 设置安装后的二进制要搜索的依赖库路径 set(CMAKE_INSTALL_RPATH "$ENV{HOME}/opencv/lib") # 允许运行时搜索RPATH中的路径(默认开启,可显式设置) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
方法2:针对单个目标设置安装RPATH
如果只想给特定目标设置RPATH,可通过set_target_properties或在install命令中指定:
# 方式A:通过目标属性设置 set_target_properties(foo PROPERTIES INSTALL_RPATH "$ENV{HOME}/opencv/lib") # 方式B:在install命令中直接指定 install(TARGETS foo DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/installed/ INSTALL_RPATH "$ENV{HOME}/opencv/lib")
方法3:让构建与安装阶段使用相同RPATH
如果希望本地构建的二进制和安装后的二进制使用相同的RPATH,可开启BUILD_WITH_INSTALL_RPATH:
set(BUILD_WITH_INSTALL_RPATH ON) set(CMAKE_INSTALL_RPATH "$ENV{HOME}/opencv/lib")
验证修改效果
重新执行构建安装:
mkdir build && cd build && cmake .. && make install
运行安装后的二进制,即可正常输出All good;再用ldd ./installed/foo检查,会看到libopencv_core.so.406已指向/home/user/opencv/lib/libopencv_core.so.406。
内容的提问来源于stack exchange,提问作者bremen_matt
相关产品推荐
相关产品推荐

