多平台编译OpenCV 4.6.0源码操作步骤
Posted fengbingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多平台编译OpenCV 4.6.0源码操作步骤相关的知识,希望对你有一定的参考价值。
从https://github.com/opencv/opencv/releases/tag/4.6.0 下载源码opencv-4.6.0.tar.gz,解压缩。
多平台包括Windows 10、Linux(Ubuntu 16.04、Ubuntu 18.04)、MacOS、android、ios、Wasm(WebAssembly)、嵌入式设备,以及它们不同的配置,如Ubuntu上不同的gcc版本,MacOS上不同的xcode版本。
将不同平台的编译命令全部写在一个shell脚本build.sh里,此脚本与OpenCV的主CMakeLists.txt在同一个目录下,外层通过输入一个参数来控制编译哪个平台哪个配置的库,如linux-x86_64-gcc5_4,命名组成方式为:platform-arch-toolchain,platform可为winodws、linux、osx(即MacOS)、andorid、ios、wasm;arch可为x86、x86_64、armv7、aarch64(arm64);toolchain可为gcc5.4、gcc8.2、clang-r23b、vs2015等。
编译前的说明:
(1).除特殊平台如Wasm、iOS只有静态库外,其它平台既包括动态库也包括静态库。
(2).除Windows外,其它平台只有Release库。
(3).为保证调用OpenCV接口时各平台结果的一致性,这里图像编解码库如libpng等不使用系统库中的,均使用OpenCV中自带的版本即3rdparty目录下的。
(4).为保证各平台结果一致(精度对齐),也关闭了OpenCV中的加速选项,如SIMD、OpenMP等,尽量只走普通C++实现部分。
(5).关闭了多线程:即设置WITH_PTHREADS_PF为OFF,设置OPENCV_DISABLE_THREAD_SUPPORT为ON后,当通过VideoCapture读取视频文件时,会有Warning:Corrupt JPEG data: premature end of data segment
(6).有些OpenCV的选项在多平台上是通用的,这里将它们放在了一起,如下:其中将外部的输入参数传给了PLATFORM_ARCH_TOOLCHAIN,用于不同的平台在CMakeList.txt中做的差异处理,设置OPENCV_DISABLE_THREAD_SUPPORT为ON,将不会编译objdetect模块
common_options="-DCMAKE_BUILD_TYPE=RELEASE \\
-DPLATFORM_ARCH_TOOLCHAIN=$1 \\
-DCMAKE_CXX_FLAGS=-fPIC \\
-DCMAKE_C_FLAGS=-fPIC \\
-DBUILD_EXAMPLES=OFF \\
-DBUILD_opencv_apps=OFF \\
-DBUILD_PERF_TESTS=OFF \\
-DBUILD_TESTS=OFF \\
-DBUILD_JAVA=OFF \\
-DBUILD_OBJC=OFF \\
-DBUILD_KOTLIN_EXTENSIONS=OFF \\
-DBUILD_opencv_gapi=OFF \\
-DOPENCV_FORCE_3RDPARTY_BUILD=ON \\
-DENABLE_PIC=ON \\
-DWITH_1394=OFF \\
-DWITH_EIGEN=OFF \\
-DWITH_ARAVIS=OFF \\
-DWITH_ARITH_DEC=ON \\
-DWITH_ARITH_ENC=ON \\
-DWITH_CLP=OFF \\
-DWITH_CUBLAS=OFF \\
-DWITH_CUDA=OFF \\
-DWITH_CUFFT=OFF \\
-DWITH_FFMPEG=OFF \\
-DWITH_GSTREAMER=OFF \\
-DWITH_GSTREAMER_0_10=OFF \\
-DWITH_HALIDE=OFF \\
-DWITH_HPX=OFF \\
-DWITH_IMGCODEC_HDR=ON \\
-DWITH_IMGCODEC_PXM=ON \\
-DWITH_IMGCODEC_SUNRASTER=ON \\
-DWITH_INF_ENGINE=OFF \\
-DWITH_IPP=OFF \\
-DWITH_ITT=OFF \\
-DWITH_OPENVINO=OFF \\
-DWITH_JASPER=ON \\
-DWITH_JPEG=ON \\
-DWITH_PNG=ON \\
-DWITH_TIFF=ON \\
-DWITH_WEBP=ON \\
-DWITH_LAPACK=OFF \\
-DWITH_PTHREADS_PF=OFF \\
-DOPENCV_DISABLE_THREAD_SUPPORT=ON \\
-DWITH_LIBREALSENSE=OFF \\
-DWITH_MSMF_DXVA=OFF \\
-DWITH_NVCUVID=OFF \\
-DWITH_OPENCL=OFF \\
-DWITH_OPENCLAMDBLAS=OFF \\
-DWITH_OPENCLAMDFFT=OFF \\
-DWITH_OPENCL_SVM=OFF \\
-DWITH_OPENCL_D3D11_NV=OFF \\
-DWITH_VA=OFF \\
-DWITH_VA_INTEL=OFF \\
-DWITH_OPENEXR=OFF \\
-DWITH_OPENGL=OFF \\
-DWITH_OPENMP=OFF \\
-DWITH_OPENNNI=OFF \\
-DWITH_OPENNNI2=OFF \\
-DWITH_OPENVX=OFF \\
-DWITH_PROTOBUF=OFF \\
-DWITH_PVAPI=OFF \\
-DWITH_QT=OFF \\
-DWITH_QUIRC=OFF \\
-DWITH_TBB=OFF \\
-DWITH_VULKAN=OFF \\
-DWITH_XIMEA=OFF \\
-DWITH_VTK=OFF \\
-DWITH_CPUFEATURES=OFF \\
-DENABLE_NEON=OFF \\
-DCPU_BASELINE=OFF \\
-DCV_ENABLE_INTRINSICS=OFF \\
-DCV_DISABLE_OPTIMIZATION=ON \\
-DINSTALL_C_EXAMPLES=OFF \\
-DINSTALL_PYTHON_EXAMPLES=OFF"
(7).因为编译的既有动态库又有静态库,这里定义了两个变量,如下:编译完的库存放在与build.sh同一目录下,动态库目录结构为install/$1/$dir_name_dynamic,静态库目录结构为install/$1/$dir_name_static
dir_name_dynamic="shared"
dir_name_static="static"
(8).因为会有很多不同的toolchain,它们存放在公共的目录下,如/usr/local/toolchains,这里定义了一个变量,用于指定公共目录,如下:
toolchains_path="/usr/local/toolchains"
1. Linux:Ubuntu 16.04、Ubuntu 18.04
调整源码:
(1).因为是在linux 64位机上编译linux x86的库,调整主CMakeLists.txt文件,对CMAKE_C_FLAGS和CMAKE_CXX_FLAGS追加-m32选项。
(2).用海思arm-himix100-linux工具链编译时,需调整主CMakeLists.txt文件,增加一个变量:add_definitions(-DLINUX_ARMV7_HIMIX100=1),此变量应用在后面介绍的extend_std_funcs.hpp文件中,否则编译时会error,类似于android gcc,如:error: 'cbrt' is not a member of 'std'。因为在海思arm-himix100-linux工具链中并没有找到仅在此工具链中适用的预定义宏,因此增加了LINUX_ARMV7_HIMIX100。在后面项目中使用此opencv库时,也需要在那个项目的CMakeLists.txt中添加:add_definitions(-DLINUX_ARMV7_HIMIX100=1)
(3).用海思arm-himix200-linux工具链编译时,需调整主CMakeLists.txt文件,增加一个变量:add_definitions(-DLINUX_ARMV7_HIMIX200=1),此变量在modules/core/include/opencv2/core/detail/exception_ptr.hpp中使用,当定义此变量时,强制添加#undef CV__EXCEPTION_PTR,否则编译库时会报error,如error: ‘std::exception_ptr’ has not been declared。因为在海思arm-himix200-linux工具链中并没有找到仅在此工具链中适用的预定义宏,因此增加了LINUX_ARMV7_HIMIX200。在后面项目中使用此opencv库时,也需要在那个项目的CMakeLists.txt中添加:add_definitions(-DLINUX_ARMV7_HIMIX200=1)
(4).使用QNX工具链编译时,在modules/calib3d/src/usac.hpp中,添加宏定义,如下,否则会报error,如:error: 'M_SQRT2' was not declared in this scope
#ifdef __QNX__
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
#define M_PI 3.14159265358979323846 /* pi */
#endif
编译:
(1).编译linux-x86_64-gcc系列,如linux-x86_64-gcc5_4,则编译命令如下:
if [ $1 == "linux-x86_64-gcc5_4" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/gcc-5.4/bin/gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/gcc-5.4/bin/g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/gcc-5.4/bin/gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/gcc-5.4/bin/g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(2).编译linux-x86-gcc4_9,编译命令如下:
elif [ $1 == "linux-x86-gcc4_9" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/usr/bin/gcc-4.9 \\
-DCMAKE_CXX_COMPILER=/usr/bin/g++-4.9 \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/usr/bin/gcc-4.9 \\
-DCMAKE_CXX_COMPILER=/usr/bin/g++-4.9 \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(3).使用海思的工具链arm-himix100-linux,编译命令如下:
elif [ $1 == "linux-armv7-himix100" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix100-linux/bin/arm-himix100-linux-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix100-linux/bin/arm-himix100-linux-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix100-linux/bin/arm-himix100-linux-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix100-linux/bin/arm-himix100-linux-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(4).使用海思的工具链arm-himix200-linux,编译命令如下:
elif [ $1 == "linux-armv7-himix200" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix200-linux/bin/arm-himix200-linux-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix200-linux/bin/arm-himix200-linux-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix200-linux/bin/arm-himix200-linux-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/hisi-linux/x86-arm/arm-himix200-linux/bin/arm-himix200-linux-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(5).使用海思的工具链aarch64-hi3559a-linux,编译命令如下:关闭了webp,否则会有error: "internal compiler erro"错误,解决此问题可能需要升级gcc版本
elif [ $1 == "linux-aarch64-hi3559a" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/hisi-linux/aarch64-hi3559a-linux/bin/aarch64-linux-gnu-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/hisi-linux/aarch64-hi3559a-linux/bin/aarch64-linux-gnu-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DWITH_WEBP=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/hisi-linux/aarch64-hi3559a-linux/bin/aarch64-linux-gnu-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/hisi-linux/aarch64-hi3559a-linux/bin/aarch64-linux-gnu-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DWITH_WEBP=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(6).使用QNX工具链,编译命令如下:编译动态库时关闭OPENCV_ENABLE_MEMALIGN,关闭静态库时关闭OPENCV_ENABLE_MEMALIGN和WITH_ADE
elif [ $1 == "linux-aarch64-qnx" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
source $toolchains_path/qnx700/qnxsdp-env.sh
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/qnx700/host/linux/x86_64/usr/bin/aarch64-unknown-nto-qnx7.0.0-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/qnx700/host/linux/x86_64/usr/bin/aarch64-unknown-nto-qnx7.0.0-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DOPENCV_ENABLE_MEMALIGN=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
source $toolchains_path/qnx700/qnxsdp-env.sh
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=$toolchains_path/qnx700/host/linux/x86_64/usr/bin/aarch64-unknown-nto-qnx7.0.0-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/qnx700/host/linux/x86_64/usr/bin/aarch64-unknown-nto-qnx7.0.0-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DOPENCV_ENABLE_MEMALIGN=OFF \\
-DWITH_ADE=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
2. Android:在Ubuntu 16.04上交叉编译
调整源码:
(1).调整3rdparty/libpng/pngpriv.h:在第137行增加:#define PNG_ARM_NEON_OPT 0,强制关闭NEON,否则在编译imgcodecs模块时会报undefined symbol的error,如ld: error: undefined symbol: png_riffle_palette_neon,这是因为我们前面在编译OpenCV时设置关闭了加速。
(2).调整cmake/OpenCVUtils.cmake:增加函数modify_android_link_deps,并在函数ocv_target_link_libraries内增加对modify_android_link_deps的调用:否则在编译android时会查找rt库,错误信息如下:ld: error: unable to find library -lrt,但是在android上是不需要rt库,这里通过判断是不是编译的android的库,若是,则将link_deps中的rt替换为log,log库在android是需要的
function(modify_android_link_deps link_deps)
set(new_link_deps "")
foreach(dep $$link_deps)
if("$dep" STREQUAL "rt")
list(APPEND new_link_deps "log")
else()
list(APPEND new_link_deps "$dep")
endif()
endforeach()
set($link_deps $new_link_deps PARENT_SCOPE)
endfunction()
function(ocv_target_link_libraries target)
set(LINK_DEPS $ARGN)
string(FIND $PLATFORM_ARCH_TOOLCHAIN "android" compare_var)
if($compare_var GREATER_EQUAL 0)
modify_android_link_deps(LINK_DEPS)
endif()
_ocv_fix_target(target)
set(LINK_MODE "PRIVATE")
# ......
endfunction()
(3).使用gcc而不是clang编译android库时,会报一些error,如error: 'cbrt' is not a member of 'std'类似错误,这是因为android gcc缺少一些std函数的实现,这里新增加一个modules/core/include/opencv2/core/extend_std_funcs.hpp文件,仅用于实现满足在android gcc下缺少的这些std函数,并将此函数在当前目录的base.hpp文件中include它
#ifndef EXTEND_STD_FUNCS_HPP
#define EXTEND_STD_FUNCS_HPP
#if (defined(__ANDROID__) && defined(__GNUC__) && !defined(__clang__)) || defined(LINUX_ARMV7_HIMIX100)
#include <stdlib.h>
#include <cmath>
#include <string>
#include <sstream>
namespace std
#if defined(__arm__) || defined(__i386__)
inline int sign(double val)
return (double(0) < val) - (val < double(0));
inline double cbrt(double x)
if (sign(x) == 0) return 0.;
return sign(x) > 0 ? std::pow(x, double(1/3.)) : -std::pow(std::fabs(x), double(1/3.));
inline double copysign(double mag, double sgn)
if (sign(sgn) == 0) return mag;
return sign(sgn) > 0 ? std::fabs(mag) : -std::fabs(mag);
#endif
#if (defined(__ANDROID__) && defined(__GNUC__) && !defined(__clang__))
inline unsigned long long stoull(const std::string& str, std::size_t* pos = nullptr, int base = 10)
(void)(pos);
char* pEnd = nullptr;
return strtoull(str.data(), &pEnd, base);
inline std::string to_string(int value)
std::ostringstream os;
os << value ;
return os.str();
#endif
// namespace std
#endif
#endif // EXTEND_STD_FUNCS_HPP
(4).编译android x86 gcc时,调整主CMakeLists.txt文件,对CMAKE_C_FLAGS和CMAKE_CXX_FLAGS追加-m32选项。
(5).编译android x86 clang时,调整主CMakeLists.txt文件,对CMAKE_C_FLAGS和CMAKE_CXX_FLAGS追加-m32选项。
编译:
(1).编译android-armv7-clang系列,如andorid-armv7-clang-r23b,则编译命令如下:
elif [ $1 == "android-armv7-clang-r23b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="armeabi-v7a" \\
-DANDROID_ARM_MODE="arm" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="armeabi-v7a" \\
-DANDROID_ARM_MODE="arm" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(2).编译android-aarch64-clang系列,如android-aarch64-clang-r23b,则编译命令如下:
elif [ $1 == "android-aarch64-clang-r23b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="arm64-v8a" \\
-DANDROID_ARM_MODE="arm64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="arm64-v8a" \\
-DANDROID_ARM_MODE="arm64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(3).编译android-x86-clang系列,如android-x86-clang-r23b,则编译命令如下:
elif [ $1 == "android-x86-clang-r23b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/i686-linux-android21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/i686-linux-android21-clang++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/i686-linux-android21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/i686-linux-android21-clang++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(4).编译android-x86_64-clang系列,如android-x86_64-clang-r23b,则编译命令如下:
elif [ $1 == "android-x86_64-clang-r23b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86_64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86_64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="clang" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r23b/clang/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(5).编译android-armv7-gcc-r14b,编译命令如下:
elif [ $1 == "android-armv7-gcc-r14b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="armeabi-v7a" \\
-DANDROID_ARM_MODE="arm" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-armv7/bin/arm-linux-androideabi-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-armv7/bin/arm-linux-androideabi-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="armeabi-v7a" \\
-DANDROID_ARM_MODE="arm" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-armv7/bin/arm-linux-androideabi-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-armv7/bin/arm-linux-androideabi-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(6).编译android-aarch64-gcc-r14b,编译命令如下:
elif [ $1 == "android-aarch64-gcc-r14b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="arm64-v8a" \\
-DANDROID_ARM_MODE="arm64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-aarch64/bin/aarch64-linux-android-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-aarch64/bin/aarch64-linux-android-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="arm64-v8a" \\
-DANDROID_ARM_MODE="arm64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-aarch64/bin/aarch64-linux-android-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-aarch64/bin/aarch64-linux-android-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(7).编译android-x86-gcc-r14b,编译命令如下:
elif [ $1 == "android-x86-gcc-r14b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86/bin/i686-linux-android-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86/bin/i686-linux-android-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86/bin/i686-linux-android-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86/bin/i686-linux-android-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(8).编译android-x86_64-gcc-r14b,编译命令如下:
elif [ $1 == "android-x86_64-gcc-r14b" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86_64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86_64/bin/x86_64-linux-android-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86_64/bin/x86_64-linux-android-g++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DANDROID_ABI="x86_64" \\
-DANDROID_PLATFORM="android-21" \\
-DANDROID_TOOLCHAIN="gcc" \\
-DCPU_BASELINE_DISABLE=ON \\
-DCMAKE_C_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86_64/bin/x86_64-linux-android-gcc \\
-DCMAKE_CXX_COMPILER=$toolchains_path/android-ndk-r14b/gcc/android-21/android-x86_64/bin/x86_64-linux-android-g++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_GTK=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
3. Wasm:在Ubuntu 16.04上交叉编译
通用项定义:
wasm_common_options="--cmake_option=-DCMAKE_BUILD_TYPE=RELEASE \\
--cmake_option=-DCMAKE_CXX_FLAGS=-fPIC \\
--cmake_option=-DCMAKE_C_FLAGS=-fPIC \\
--cmake_option=-DPLATFORM_ARCH_TOOLCHAIN=$1 \\
--cmake_option=-DBUILD_SHARED_LIBS=OFF \\
--cmake_option=-DBUILD_PROTOBUF=OFF \\
--cmake_option=-DBUILD_ZLIB=ON \\
--cmake_option=-DBUILD_opencv_apps=OFF \\
--cmake_option=-DBUILD_opencv_gapi=OFF \\
--cmake_option=-DBUILD_opencv_highgui=ON \\
--cmake_option=-DBUILD_opencv_imgcodecs=ON \\
--cmake_option=-DBUILD_opencv_photo=ON \\
--cmake_option=-DBUILD_opencv_stitching=ON \\
--cmake_option=-DBUILD_opencv_dnn=OFF \\
--cmake_option=-DBUILD_opencv_objdetect=OFF \\
--cmake_option=-DBUILD_opencv_ts=OFF \\
--cmake_option=-DBUILD_opencv_ml=ON \\
--cmake_option=-DBUILD_opencv_videoio=ON \\
--cmake_option=-DOPENCV_FORCE_3RDPARTY_BUILD=ON \\
--cmake_option=-DBUILD_JASPER=ON \\
--cmake_option=-DBUILD_JPEG=ON \\
--cmake_option=-DBUILD_PNG=ON \\
--cmake_option=-DBUILD_TIFF=ON \\
--cmake_option=-DBUILD_WEBP=ON"
依赖项:本机需安装emcmake;本机需安装python3,版本要求>=3.2
调整源码:
(1).编译x86时,调整主CMakeLists.txt文件,对CMAKE_C_FLAGS和CMAKE_CXX_FLAGS追加-m32选项。
编译:
(1).编译wasm-x86,编译命令如下:
elif [ $1 == "wasm-x86" ]; then
echo "#### build static libraries ..."
rm -rf *
TARGET_COMPILER_VERSION=1.39.20
emcmake \\
python3 ../platforms/js/build_js.py . \\
--emscripten_dir=$toolchains_path/emsdk-$TARGET_COMPILER_VERSION/upstream/emscripten/ \\
$wasm_common_options \\
--cmake_option="-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static"
emmake make install
(2).编译wasm-x86_64,编译命令如下:
elif [ $1 == "wasm-x86_64" ]; then
echo "#### build static libraries ..."
rm -rf *
TARGET_COMPILER_VERSION=1.39.20
emcmake \\
python3 ../platforms/js/build_js.py . \\
--emscripten_dir=$toolchains_path/emsdk-$TARGET_COMPILER_VERSION/upstream/emscripten/ \\
$wasm_common_options \\
--cmake_option="-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static"
emmake make install
4. Windows 10:
cmake/OpenCVCRTLinkage.cmake中,默认动态库是MD,静态库是MT,这里作了调整,无论是动态库还是静态库都可以指定是MD还是MT。为了让windows 10编译的库可以在windows xp上运行,这里指定了v140_xp选项。
基于windows的通用项定义如下:
msvc_mt_common_options="-DCMAKE_CXX_FLAGS=/DWIN32 /D_WINDOWS /W3 /GR /EHsc \\
-DCMAKE_CXX_FLAGS_DEBUG=/MTd /Zi /Ob0 /Od /RTC1 \\
-DCMAKE_CXX_FLAGS_RELEASE=/MT /O2 /Ob2 /DNDEBUG \\
-DCMAKE_CXX_FLAGS_MINSIZEREL=/MT /O1 /Ob1 /DNDEBUG \\
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=/MT /Zi /O2 /Ob1 /DNDEBUG \\
-DCMAKE_C_FLAGS=/DWIN32 /D_WINDOWS /W3 \\
-DCMAKE_C_FLAGS_DEBUG=/MTd /Zi /Ob0 /Od /RTC1 \\
-DCMAKE_C_FLAGS_RELEASE=/MT /O2 /Ob2 /DNDEBUG \\
-DCMAKE_C_FLAGS_MINSIZEREL=/MT /O1 /Ob1 /DNDEBUG \\
-DCMAKE_C_FLAGS_RELWITHDEBINFO=/MT /Zi /O2 /Ob1 /DNDEBUG \\
-DWITH_ADE=OFF \\
-DWITH_MSMF=OFF \\
-DBUILD_opencv_dnn=OFF"
msvc_md_common_options="-DCMAKE_CXX_FLAGS=/DWIN32 /D_WINDOWS /W3 /GR /EHsc \\
-DCMAKE_CXX_FLAGS_DEBUG=/MDd /Zi /Ob0 /Od /RTC1 \\
-DCMAKE_CXX_FLAGS_RELEASE=/MD /O2 /Ob2 /DNDEBUG \\
-DCMAKE_CXX_FLAGS_MINSIZEREL=/MD /O1 /Ob1 /DNDEBUG \\
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=/MD /Zi /O2 /Ob1 /DNDEBUG \\
-DCMAKE_C_FLAGS=/DWIN32 /D_WINDOWS /W3 \\
-DCMAKE_C_FLAGS_DEBUG=/MDd /Zi /Ob0 /Od /RTC1 \\
-DCMAKE_C_FLAGS_RELEASE=/MD /O2 /Ob2 /DNDEBUG \\
-DCMAKE_C_FLAGS_MINSIZEREL=/MD /O1 /Ob1 /DNDEBUG \\
-DCMAKE_C_FLAGS_RELWITHDEBINFO=/MD /Zi /O2 /Ob1 /DNDEBUG \\
-DWITH_ADE=OFF \\
-DWITH_MSMF=OFF \\
-DBUILD_opencv_dnn=OFF"
调整源码:
(1).关闭python的支持,否则会报error:ImportError: No module named numpy.distutils,调整主CMakeLists.txt,将
# --- Python Support ---
if(NOT IOS)
include(cmake/OpenCVDetectPython.cmake)
endif()
调整为:
# --- Python Support ---
if((NOT IOS) AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio"))
include(cmake/OpenCVDetectPython.cmake)
endif()
(2).由于增加了v140_xp选项,需关闭FLS的支持,否则会报error:fatal error C1083: Cannot open include file: 'fibersapi.h': No such file or directory,调整主CMakeLists.txt,设置变量ST_COMPATIBLE_XP,如下:
if($PLATFORM_ARCH_TOOLCHAIN STREQUAL "windows-x86-vs2015" OR $PLATFORM_ARCH_TOOLCHAIN STREQUAL "windows-x86_64-vs2015")
add_definitions(-DST_COMPATIBLE_XP)
endif()
调整modules/core/src/system.cpp,强制关闭FLS,如下
#if (_WIN32_WINNT >= 0x0602)
#include <synchapi.h>
#endif
#ifdef ST_COMPATIBLE_XP
#define CV_DISABLE_FLS // force close FLS when use v140_xp
#endif
#if ((_WIN32_WINNT >= 0x0600) && !defined(CV_DISABLE_FLS)) || defined(CV_FORCE_FLS)
#include <fibersapi.h>
#define CV_USE_FLS
#endif
(3).由于动态库和静态库都需要同时支持MD和MT,这里在build.sh中定义ST_FORCE_MSVC_USE_MT和ST_FORCE_MSVC_USE_MD用来指定是编译MD模式还是MT模式,调整cmake/OpenCVRTLinkage.cmake,将原来的if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)调整为
if((NOT ST_FORCE_MSVC_USE_MD) AND ((NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT) OR ST_FORCE_MSVC_USE_MT))
编译:
(1).编译windows-x86_64-vs系列,如windows-x86_64-vs2015,则编译命令如下:
elif [ $1 == "windows-x86_64-vs2015" ]; then
echo "#### build mt dynamic libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config debug
echo "#### build mt dynamic libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config release
echo "#### build mt static libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config debug
echo "#### build mt static libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config release
echo "#### build md dynamic libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config debug
echo "#### build md dynamic libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config release
echo "#### build md static libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config debug
echo "#### build md static libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A x64 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config release
(2).编译windows-x86-vs系列,如windows-x86_64-vs2015,则编译命令如下:
elif [ $1 == "windows-x86-vs2015" ]; then
echo "#### build mt dynamic libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config debug
echo "#### build mt dynamic libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config release
echo "#### build mt static libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config debug
echo "#### build mt static libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_mt_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MT=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/mt \\
..
cmake --build . --target install --config release
echo "#### build md dynamic libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config debug
echo "#### build md dynamic libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config release
echo "#### build md static libraries debug ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Debug \\
-DCMAKE_CONFIGURATION_TYPES=Debug \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config debug
echo "#### build md static libraries release ..."
rm -rf *
cmake \\
-G"Visual Studio 14 2015" -A Win32 -T v140_xp \\
$common_options \\
$msvc_md_common_options \\
-DCMAKE_BUILD_TYPE=Release \\
-DCMAKE_CONFIGURATION_TYPES=Release \\
-DST_FORCE_MSVC_USE_MD=1 \\
-DBUILD_SHARED_LIBS=OFF \\
-DCMAKE_INSTALL_PREFIX=../install/$1/md \\
..
cmake --build . --target install --config release
5. MacOS:
调整源码:
(1).调整主CMakeLists.txt,强制使HAVE_PTHREAD不生效,否则报error:CMake Error at CMakeLists.txt:Thread execution might be in use in some component,在build.sh中定义ST_FORCE_XCODE_CLOSE_GCD,然后将CMakeLists.txt中的
else())
set(HAVE_PTHREAD 1)
endif()
调整为:
elseif(NOT ST_FORCE_XCODE_CLOSE_GCD)
set(HAVE_PTHREAD 1)
endif()
(2).调整主CMakeLists.txt,强制使list(REMOVE_ITEM OPENCV_LINKER_LIBS pthread)不生效,否则报error:CMake Error at CMakeLists.txt: (list):list sub-command REMOVE_ITEM requires list to be present,将CMakeLists.txt中的
if (OPENCV_DISABLE_THREAD_SUPPORT)
list(REMOVE_ITEM OPENCV_LINKER_LIBS pthread)
endif()
调整为:
if (OPENCV_DISABLE_THREAD_SUPPORT AND NOT ST_FORCE_XCODE_CLOSE_GCD)
list(REMOVE_ITEM OPENCV_LINKER_LIBS pthread)
endif()
(3).调整cmake/OpenCVFindFrameworks.cmake,强制使HAVE_GCD不生效,否则报error:CMake Error at CMakeLists.txt: (message): Not all parallel frameworks have been disabled (using GCD),将OpenCVFindFrameworks.cmake中的
if(APPLE AND NOT HAVE_TBB)
set(HAVE_GCD 1)
else()
调整为:
if(APPLE AND NOT HAVE_TBB AND NOT ST_FORCE_XCODE_CLOSE_GCD)
set(HAVE_GCD 1)
else()
(4).编译osx x86的库时调整主CMakeLists.txt文件,对CMAKE_C_FLAGS和CMAKE_CXX_FLAGS追加-m32选项。
编译:
(1).编译osx-x86_64-xcode系列,如osx-x86_64-xcode12,则编译命令如下:
elif [ $1 == "osx-x86_64-xcode12" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc \\
-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_ADE=OFF \\
-DST_FORCE_XCODE_CLOSE_GCD=1 \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc \\
-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_ADE=OFF \\
-DST_FORCE_XCODE_CLOSE_GCD=1 \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(2).编译osx-x86-xcode系列,如osx-x86-xcode12,则编译命令如下:
elif [ $1 == "osx-x86-xcode12" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc \\
-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_ADE=OFF \\
-DST_FORCE_XCODE_CLOSE_GCD=1 \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc \\
-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_ADE=OFF \\
-DST_FORCE_XCODE_CLOSE_GCD=1 \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
(3).编译osx-aarch64-xcode系列,如osx-aarch64-xcode12,则编译命令如下:Apple M1
elif [ $1 == "osx-aarch64-xcode12" ]; then
echo "#### build dynamic libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc \\
-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ \\
-DBUILD_SHARED_LIBS=ON \\
-DWITH_ADE=OFF \\
-DST_FORCE_XCODE_CLOSE_GCD=1 \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_dynamic \\
..
make -j8
make install
echo "#### build static libraries ..."
rm -rf *
cmake \\
$common_options \\
-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc \\
-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ \\
-DBUILD_SHARED_LIBS=OFF \\
-DWITH_ADE=OFF \\
-DST_FORCE_XCODE_CLOSE_GCD=1 \\
-DCMAKE_INSTALL_PREFIX=../install/$1/$dir_name_static \\
..
make -j8
make install
6. iOS
基于iOS的通用项定义如下:
ios_common_options="--without world --without gapi --without dnn --without objdetect --without objc --without ts \\
--disable 1394 --disable EIGEN --disable CUDA --disable FFMPEG --disable IPP --disable ITT --disable LAPACK \\
--disable LIBREALSENSE --disable NVCUVID --disable OPENCL --disable OPENEXR --disable OPENGL --disable OPENMP \\
--disable OPENVX --disable PROTOBUF --disable QT --disable TBB --disable ADE --disable QUIRC"
调整源码:主要调整platforms/ios/build_framework.py
(1).调整platforms/ios/build_framework.py,在_build函数内的cmake_flags = []后添加一句,否则在主CMakeLists.txt里会报error:CMake Error at CMakeLists.txt: (if): Unknown arguments specified,因为PLATFORM_ARCH_TOOLCHAIN变量没有被定义
cmake_flags.append("-DPLATFORM_ARCH_TOOLCHAIN=ios")
(2).调整platforms/ios/build_framework.py,对于--iphoneos_archs和--iphonesimulator_archs选项,如果不显示指定则会被赋予默认值,这里调整为--iphoneos_archs和--iphonesimulator_archs每次仅支持一种指定
# iphoneos_archs = None
# if args.iphoneos_archs:
# iphoneos_archs = args.iphoneos_archs.split(',')
# elif not args.build_only_specified_archs:
# # Supply defaults
# iphoneos_archs = ["armv7", "armv7s", "arm64"]
# print('Using iPhoneOS ARCHS=' + str(iphoneos_archs))
# iphonesimulator_archs = None
# if args.iphonesimulator_archs:
# iphonesimulator_archs = args.iphonesimulator_archs.split(',')
# elif not args.build_only_specified_archs:
# # Supply defaults
# iphonesimulator_archs = ["i386", "x86_64"]
# print('Using iPhoneSimulator ARCHS=' + str(iphonesimulator_archs))
if args.iphoneos_archs is None and args.iphonesimulator_archs is None:
print_error("--iphoneos_archs and --iphonesimulator_archs are undefined; nothing will be built.")
sys.exit(1)
if args.iphoneos_archs and args.iphonesimulator_archs:
print_error("one of --iphoneos_archs and --iphonesimulator_archs must be specified.")
sys.exit(1)
iphoneos_archs = None
if args.iphoneos_archs:
iphoneos_archs = args.iphoneos_archs.split(',')
print('Using iPhoneOS ARCHS=' + str(iphoneos_archs))
iphonesimulator_archs = None
if args.iphonesimulator_archs:
iphonesimulator_archs = args.iphonesimulator_archs.split(',')
print('Using iPhoneSimulator ARCHS=' + str(iphonesimulator_archs))
编译:
(1).编译ios_os-universal-xcode系列,如ios_os-universal-xcode12,真机,则编译命令如下:编译完后,会分别有基于armv7和arm64两套库,可以通过libtool将armv7和arm64整合成一套库
elif [ $1 == "ios_os-universal-xcode12" ]; then
echo "#### build static libraries ..."
rm -rf *
python ../platforms/ios/build_framework.py ../install/$1 --iphoneos_archs armv7,arm64 $ios_common_options
echo "#### CreateUniversalBinary ..."
path=../install/$1/
path_armv7=build/build-armv7-iphoneos/install/lib/
path_arm64=build/build-arm64-iphoneos/install/lib/
prefix_3rdparty=3rdparty/lib
prefix_modules=libopencv_
suffix=.a
name_3rd_libs=("libpng" "libwebp" "zlib" "libjpeg-turbo")
name_module_libs=("photo" "videoio" "calib3d" "features2d" "core" "imgcodecs" "highgui" "video" "ml" "stitching" "flann" "imgproc")
mkdir -p $path$dir_name_static/lib/3rdparty
mkdir -p $path$dir_name_static/lib
for val in $name_3rd_libs[@]; do
name_armv7_lib="$path$path_armv7$prefix_3rdparty$val$suffix"
name_arm64_lib="$path$path_arm64$prefix_3rdparty$val$suffix"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static $name_armv7_lib $name_arm64_lib -o $path$dir_name_static/lib/$prefix_3rdparty$val$suffix
done
for val in $name_module_libs[@]; do
name_armv7_lib="$path$path_armv7$prefix_modules$val$suffix"
name_arm64_lib="$path$path_arm64$prefix_modules$val$suffix"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static $name_armv7_lib $name_arm64_lib -o $path$dir_name_static/lib/$prefix_modules$val$suffix
done
cp -a $path$path_armv7../include $path$dir_name_static/
cp -a $path$path_armv7../share $path$dir_name_static/
cp -a $path$path_armv7cmake $path$dir_name_static/lib/
(2).编译ios_sim-universal-xcode系列,如ios_sim-universal-xcode12,模拟器(simulator),则编译命令如下:编译完后,会分别有基于i386和x86_64两套库,可以通过libtool将i386和x86_64整合成一套库
elif [ $1 == "ios_sim-universal-xcode12" ]; then
echo "#### build static libraries ..."
rm -rf *
python ../platforms/ios/build_framework.py ../install/$1 --iphonesimulator_archs i386,x86_64 $ios_common_options
echo "#### CreateUniversalBinary ..."
path=../install/$1/
path_i386=build/build-i386-iphonesimulator/install/lib/
path_x86_64=build/build-x86_64-iphonesimulator/install/lib/
prefix_3rdparty=3rdparty/lib
prefix_modules=libopencv_
suffix=.a
name_3rd_libs=("libpng" "libwebp" "zlib" "libjpeg-turbo")
name_module_libs=("photo" "videoio" "calib3d" "features2d" "core" "imgcodecs" "highgui" "video" "ml" "stitching" "flann" "imgproc")
mkdir -p $path$dir_name_static/lib/3rdparty
mkdir -p $path$dir_name_static/lib
for val in $name_3rd_libs[@]; do
name_i386_lib="$path$path_i386$prefix_3rdparty$val$suffix"
name_x86_64_lib="$path$path_x86_64$prefix_3rdparty$val$suffix"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static $name_i386_lib $name_x86_64_lib -o $path$dir_name_static/lib/$prefix_3rdparty$val$suffix
done
for val in $name_module_libs[@]; do
name_i386_lib="$path$path_i386$prefix_modules$val$suffix"
name_x86_64_lib="$path$path_x86_64$prefix_modules$val$suffix"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static $name_i386_lib $name_x86_64_lib -o $path$dir_name_static/lib/$prefix_modules$val$suffix
done
cp -a $path$path_i386../include $path$dir_name_static/
cp -a $path$path_i386../share $path$dir_name_static/
cp -a $path$path_i386cmake $path$dir_name_static/lib/
(3).编译ios_sim-aarch64-xcode系列,如ios_sim-aarch64-xcode12,模拟器(simulator),则编译命令如下:Apple M1
elif [ $1 == "ios_sim-aarch64-xcode12" ]; then
echo "#### build static libraries ..."
rm -rf *
python ../platforms/ios/build_framework.py ../install/$1 --iphonesimulator_archs arm64 $ios_common_options
path=../install/$1/
mkdir -p $path$dir_name_static
cp -a $pathbuild/build-arm64-iphonesimulator/install/ $path$dir_name_static/
7. 项目中使用OpenCV
(1).项目test中加入对OpenCV的支持,则CMakeLists.txt应包括类似语句:
FIND_PACKAGE(OpenCV)
INCLUDE_DIRECTORIES($OpenCV_INCLUDE_DIRS)
MESSAGE("#### opencv include dirs: $OpenCV_INCLUDE_DIRS")
MESSAGE("#### opencv libs: $OpenCV_LIBS")
TARGET_LINK_LIBRARIES(test $OpenCV_LIBS)
(2).cmake时应使用OpenCV_DIR指定opencv中OpenCVConfig.cmake文件路径,如linux-x86_64-gcc5_4,这样主机上可以同时包含多个版本的opencv,通过OpenCV_DIR来指定使用哪个版本
cmake -DOpenCV_DIR=/usr/local/toolchains/opencv/4.6.0/linux-x86_64-gcc5_4/shared/lib/cmake/opencv4/ ..
(3).因为opencv中编译选项较多,可通过调用cv::getBuildInformation()函数来查看编译opencv时开启了哪些选项.
8. 因为编译的平台、架构较多,有时需要了解某个编译器(preprocessor)定义支持的宏,可通过执行如下命令获取,如/usr/bin/gcc和/usr/bin/g++
echo | /usr/bin/gcc -dM -E -
echo | /usr/bin/g++ -dM -E -x c++ -
GitHub:https://github.com/fengbingchun/OpenCV_Test
以上是关于多平台编译OpenCV 4.6.0源码操作步骤的主要内容,如果未能解决你的问题,请参考以下文章
Ubuntu 20.04下搭建C++ & OpenCV 4.6.0 & cmake编译