如何使用捆绑依赖项-CMAKE构建静态库

How to build static library with bundled dependencies - CMake

本文关键字:-CMAKE 构建 静态 依赖 何使用      更新时间:2023-10-16

我当前正在使用cmake创建一个静态库,该库利用了OpenCV 4(Core imgcodecs Video Highgui imgproc(中的一些静态库。我的目的是能够将所有必需的OpenCV静态库捆绑到我自己的库中,以便我可以将其分配为一个库。此外,我希望库的用户不必在其系统上安装OpenCV 4(但不介意用户是否必须使用APT-GET安装进行简单安装(。我知道有一些工具可以捆绑静态库(例如将AR用于Linux(。但是,我真正遇到的问题是OpenCV的所有依赖性(例如Libjpeg,libpng等(。我不一定要介意这些库是否与我的或动态链接,因为它们相对容易安装(可以使用sudo apt-get安装安装,而opencv4则需要从源来构建(。

>

这样做的最佳方法是什么?这是我目前的cmakelists.txt它目前正在工作,但这是因为我使用的是find_package(需要OPENCV((这打破了我要做的事情的目的(。当我删除该行时,链接器抱怨无法找到OpenCV依赖项。

cmake_minimum_required(VERSION 2.8)
project(myproject)
set(CMAKE_CXX_STANDARD 14)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
find_package(OpenMP REQUIRED)
find_package(OpenCV REQUIRED)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
list(APPEND LINKER_LIBS opencv_core opencv_highgui opencv_video opencv_imgcodecs libmxnet.so libncnn.a nlohmann_json::nlohmann_json)
file(GLOB SRC${CMAKE_CURRENT_LIST_DIR}/src/*.cpp${CMAKE_CURRENT_LIST_DIR}/main.cpp)
add_library(myproject ${SRC})
target_link_libraries(myproject ${LINKER_LIBS} ${OpenMP_CXX_FLAGS})

详细说明我的问题。我构建了生成libmyproject的项目。然后,我拿走这个库,最终将从opencv libs提取符号(libopencv_core.a libopencv_highgui.a libopencv_imgcodecs.a libopencv_video.a(这就是为什么在下面的示例中我链接libopencv_*(。然后,我在一个新项目中使用我的库,cmakelists.txt如下所示:

cmake_minimum_required(VERSION 2.8)
project(myproject-driver)
set(CMAKE_CXX_STANDARD 14)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
find_package(OpenMP REQUIRED)
add_executable(myproject-driver main.cpp)
target_link_libraries(myproject-driver myproject libncnn.a ${OpenMP_CXX_FLAGS} libmxnet.so libopencv_core.a  libopencv_highgui.a  libopencv_imgcodecs.a  libopencv_video.a)

构建这会产生以下错误:

Linking CXX executable myproject-driver
/usr/bin/ld: /home/nchafni/Cyrus/myproject/lib/libopencv_imgcodecs.a(grfmt_jpeg.cpp.o): undefined reference to symbol 'jpeg_default_qtables@@LIBJPEG_8.0'
//usr/lib/x86_64-linux-gnu/libjpeg.so.8: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

我该如何解决。是否有一些CMAKE命令可以将所有这些依赖关系链接给我?我是否需要手动跟踪这些libopencv_* libs的每个依赖性并手动链接?再一次,这是假设使用libmyproject的人无法使用 find_package(OpenCV REQUIRED),因为它不会被定义,因为他们尚未在计算机上安装openCV。

首先,不要使用CMake的超级旧版本和过时的版本2.8
CMake 3.x强大得多,使用非常简单。
现代cmake

的一些技巧
  • 不要使用file(GLOB),请参阅此处。
  • 请勿使用目录宽指令,而是使用 target 指令,例如。target_include_directoriesinclude_directories
  • 不要使用字符串变量喜欢${<PACKAGE_NAME>_LIBRARIES},而是使用 targets ,例如。<Package_NAME>::lib
  • 使用 targets 而不是字符串变量,该目标的所有属性(包括 link_interface (调用target_link_libraries时,可以填充到库/可执行文件,因此不再有include_directorieslink_directories等。

myproject

cmake_minimum_required(VERSION 3.14)
project(myproject)
set(CMAKE_CXX_STANDARD 14)
find_package(OpenMP REQUIRED)
find_package(OpenCV REQUIRED)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
set(SOURCES ...) # list all the source files here
add_library(myproject ${SOURCES})
target_include_directories(myproject PUBLIC # give it a scope
                           ${CMAKE_CURRENT_LIST_DIR}/include
)
target_link_libraries(myproject PUBLIC # give it a scope
                      opencv_core # using the target, you will get all LINK_LIBRARIES
                      opencv_highgui 
                      opencv_video 
                      opencv_imgcodecs 
                      libmxnet.so  # where is this coming from?
                      libncnn.a # where is this coming from?
                      nlohmann_json::nlohmann_json 
                      OpenMP::OpenMP_CXX ## linking against a target, CXX_FLAGS will be populated automatically
)

myprojec-driver

cmake_minimum_required(VERSION 3.14)
project(myproject-driver)
set(CMAKE_CXX_STANDARD 14)
add_executable(myproject-driver main.cpp)
target_link_libraries(myproject-driver PUBLIC # give it a scope
                      myproject # gets all dependencies through the LINK_INTERFACE
)