c++ - 如何使用捆绑的依赖项构建静态库 - CMake

标签 c++ opencv cmake static-libraries

我目前正在使用 CMake 创建一个静态库,它利用了 OpenCV 4 中的一些静态库(core imgcodecs video highgui imgproc)。我的意图是能够将所有必需的 OpenCV 静态库捆绑到我自己的库中,以便我可以将它作为一个库进行分发。此外,我希望我的库的用户不必在他们的系统上安装 OpenCV 4(但不要介意用户是否必须使用 apt-get install 进行简单安装)。我知道有用于捆绑静态库的工具(例如使用 ar for linux)。 但是,我真正遇到问题的地方是 OpenCV 的所有依赖项(例如 libjpeg、libpng 等)。我不一定介意这些库是否与我的库捆绑在一起或动态链接,因为它们相对容易安装(可以使用 sudo apt-get install 安装,而 opencv4 需要从源代码构建)。

执行此操作的最佳方法是什么? 这是我当前的 CMakeLists.txt 它目前正在工作,但那是因为我正在使用 find_package(OpenCV REQUIRED) (这违背了我想要做的事情的目的)。当我删除该行时,链接器提示无法找到 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.a 的项目。然后我使用这个库并最终从 OpenCV 库中提取符号 (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_* 库的每个依赖项并手动链接它们?再一次,这是假设使用 libmyproject.a 的人不能使用 find_package(OpenCV REQUIRED) 因为它不会被定义,因为他们没有在他们的机器上安装 OpenCV。

最佳答案

首先,不要使用超旧过时的版本2.8CMake .
CMake 3.x功能强大得多,而且使用起来非常简单。
现代 CMake 的一些技巧。

  • 不要使用 file(GLOB) , 请参阅 here为什么会这样。
  • 不要使用目录范围指令,而是使用目标指令,例如target_include_directoriesinclude_directories .
  • 不要使用像${<PACKAGE_NAME>_LIBRARIES} 这样的字符串变量 ,而是使用目标,例如<Package_NAME>::lib
  • 当使用目标而不是字符串变量时,该目标的所有属性(包括LINK_INTERFACE)将在调用 target_link_libraries 时填充到库/可执行文件中,所以不再include_directories , link_directories

我的项目

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
)

我的项目驱动程序

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
)

关于c++ - 如何使用捆绑的依赖项构建静态库 - CMake,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56814304/

相关文章:

c++ - 适合屏幕的静态数组

c++ - 带有异步 C++ 驱动程序的 SQL/NoSQL 数据库管理系统

python - 检查图像是否包含蓝色像素

arrays - OpenCV中使用的原始十六进制数据

python - opencv python : mat data type = 17 is not supported

c++ - 我在 C++ 中是什么意思?

c++ - 在 C++ 中读取包含 é 等特殊字符的 ISO-8859 类型文件

c++ - 如何在cmake中链接winsock?

cmake ExternalProject_Add 如何下载 URL 非 tar 文件?

c++ - 如何告诉 CMake 在 Windows 上使用 Clang?