从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
#include
#include
#include
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
#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
#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_armv7}cmake ${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_i386}cmake ${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 ${path}build/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