通过CMake用MinGW优雅规范地静态链接OpenCV库

引言

本文主要是通过CMake进行优雅规范的操作,使用MinGW静态链接OpenCV库。本文给出的CMake命令和CMakeLists.txt文件,能够很好地跨平台,跨编译器,并不局限于MinGW以及OpenCV库。这套操作规范,适用于在不同的平台进行各种库的构建和链接。这才是现代CMake该有的操作。

相关工作

网上关于使用MinGW静态链接OpenCV库的文章很少。这些文章的主要问题如下。

写法很不规范,过时丑陋。使用很多的麻烦操作,比如硬编码头文件和库文件路径,使用冗长的原生编译命令,手动链接特殊的动态库,等等。这些也是网上大部分关于使用CMake构建和链接库的文章的通病。明明都使用CMake来构建OpenCV库了,却不接着使用CMake进行操作。

有的文章在内容组织上,强绑定IDE。明明几乎只是使用命令行的操作,却非要和具体的C++ IDE挂钩。

方法

首先还是通过cmake-gui,生成OpenCV的构建文件。使用cmake-gui主要是为了方便修改那些编译选项。在构建OpenCV库之前,可以考虑把CMAKE_INSTALL_PREFIX的值修改为C:/Program Files (x86)/OpenCV,或者是安装之后再手动把install文件夹放到C:/Program Files (x86)下,并改名为OpenCV。关于这点,我单独写了一篇内容具体介绍。

吐槽OpenCV对CMAKE_INSTALL_PREFIX安装路径的设置

简单来说,实际上是OpenCV的这种设置,不符合现代CMake的规范,需要自行修改。

然后是构建和安装的操作。

1
cmake --build .
1
cmake --install .

接着,在自己的项目,当然也是用CMake构建。给出CMakeLists.txt的示例写法。这样写是很规范的,完全是跨平台,跨编译器的。

CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cmake_minimum_required(VERSION 3.15)

project(myproject)

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

set(OpenCV_STATIC ON)

find_package(OpenCV CONFIG REQUIRED)

add_executable(opencv_example main.cpp)

target_link_options(opencv_example PRIVATE -static)

target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS})

可以看到,其中写了这么一句。

CMakeLists.txt
1
set(OpenCV_STATIC ON)

我同样是单独写为一篇内容来具体介绍。

在CMake设置OpenCV_STATIC选项静态链接OpenCV库

简单来说,这个是OpenCV在Windows独有的选项。

以及写了这句。

CMakeLists.txt
1
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

这个是设置在使用MSVC时的静态链接。直接这样写就行,在其他编译器上会被忽略,也就不会有问题。

接着就是在自己项目的build目录下进行操作。还是那句话,都用CMake了,在构建自己的项目的时候,为什么还要手敲g++那么一长串的命令,关于引用和链接的写法又长又丑陋。

1
cmake -G "MinGW Makefiles" ..

本文主要在说的是使用MinGW进行静态链接。实际上,使用其他的生成器,只要在相应的平台上,规范地安装了相应工具链构建的OpenCV库,操作是完全通用的。

1
cmake --build .

这样就能得到静态链接的可执行文件了,可以用objdump确认其依赖。

总体来说,操作是很规范优雅的。


通过CMake用MinGW优雅规范地静态链接OpenCV库
https://sunboyallen.github.io/cmake-mingw-opencv-static/
作者
sunboyallen
发布于
2024年8月20日
许可协议