编译依赖OpenCV的C++共享库,无需分发OpenCV的方法
将OpenCV静态库打包进自定义Windows DLL的解决方案
问题描述
我是C++编译流程及CMake的新手,正在尝试把自己的程序编译成依赖OpenCV的Windows共享库(.dll)。目前已经把OpenCV编译成静态库集合(.lib),并做了这些配置:
- 将OpenCV构建文件夹路径加入环境变量并更新了系统Path
- 在Visual Studio里配置了附加包含目录
但我知道,因为我编译的是动态链接库,OpenCV的.lib文件得随我的库一起分发。想问问有没有办法把OpenCV库直接打包到我的库里面,不用打包完整的OpenCV源代码?我当前的CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.9) set(CMAKE_CXX_STANDARD 17) PROJECT(MySharedLibrary DESCRIPTION "My Shared Library") find_package(OpenCV REQUIRED) link_directories(${OpenCV_LIBS}) include_directories( ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/src ${OpenCV_INCLUDE_DIRS} ) file(GLOB all_FILES "${PROJECT_SOURCE_DIR}/include/*.hpp" "${PROJECT_SOURCE_DIR}/src/program.cpp" ) ###### LIBRARY COMPILATION ###### add_library(MySharedLibrary SHARED ${all_FILES}) target_link_libraries(MySharedLibrary ${OpenCV_LIBS} "-static")
解决方案
要把OpenCV静态库直接整合到你的DLL里,不用额外分发OpenCV的.lib文件,只需调整CMake配置,确保静态链接生效:
1. 修正后的CMakeLists.txt
cmake_minimum_required(VERSION 3.9) set(CMAKE_CXX_STANDARD 17) # 核心配置:告诉CMake优先使用OpenCV静态库 set(OpenCV_STATIC ON) PROJECT(MySharedLibrary DESCRIPTION "My Shared Library") find_package(OpenCV REQUIRED) # 移除多余的link_directories,find_package已自动处理库路径 # link_directories(${OpenCV_LIBS}) # 改用目标级别的包含目录,更符合现代CMake规范 target_include_directories(MySharedLibrary PRIVATE ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/src PUBLIC ${OpenCV_INCLUDE_DIRS} ) file(GLOB all_FILES "${PROJECT_SOURCE_DIR}/include/*.hpp" "${PROJECT_SOURCE_DIR}/src/program.cpp" ) ###### LIBRARY COMPILATION ###### add_library(MySharedLibrary SHARED ${all_FILES}) # 确保-static参数作用于OpenCV库链接 target_link_libraries(MySharedLibrary PRIVATE ${OpenCV_LIBS} -static)
2. 关键配置解析
set(OpenCV_STATIC ON):这是最关键的一步,让find_package优先查找OpenCV的静态库版本,而非动态库的导入库。- 移除
link_directories:find_package(OpenCV REQUIRED)已经自动处理了库的路径,手动指定反而可能导致冲突。 target_include_directories替代include_directories:全局的include_directories会污染所有目标,目标级别的配置更清晰,只对当前库生效。-static参数位置:放在${OpenCV_LIBS}之后,确保这个静态链接参数只作用于OpenCV库的链接过程。
3. 编译注意事项
- 确认你编译OpenCV时开启了
BUILD_SHARED_LIBS=OFF,生成的是静态库。如果之前编译的是动态库,需要重新编译OpenCV的静态版本。 - 编译完成后,生成的
MySharedLibrary.dll会包含所有依赖的OpenCV代码,无需额外分发OpenCV的.lib或.dll文件。 - 静态链接会增大DLL体积,这是正常现象,因为所有用到的OpenCV模块代码都被打包进了你的DLL。
4. Visual Studio配置说明
既然用CMake管理构建,就不需要手动在Visual Studio里配置附加包含目录了——CMake会自动生成正确的项目文件,包含所有必要的路径和链接设置。
内容的提问来源于stack exchange,提问作者Sam B
相关产品推荐
相关产品推荐

