• 自己编译 ARM 版 opencvmobile 解决编译器版本导致的 `undefined reference to std::__cxx11::basic_stringstream` 问题


    起因

    因项目需要在 arm 版中进行简单的图形运算,于是打算直接用 opencv-mobile 仓库预编译好的 opencv-mobile-4.5.4-armlinux.zip。但果然因为生产环境依赖的编译器版本太旧,在编译过程遇到了因为 ABI 接口导致的错误:

    undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
    undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> > const&)
    ...
    

    尝试直接使用 -D _GLIBCXX_USE_CXX11_ABI=0,无效
    搜索一圈无果,(#20 #25 #27)

    于是决定自己编译一遍,解决问题,顺便编写这个文档,方便后人查阅。

    arm-linux-gnueabihf 编译步骤

    1. 前置步骤,在 Linux 中安装好 CMake,arm-linux-gnueabihf 工具链

    2. clone https://github.com/nihui/opencv-mobile

    3. 进入 clone 所在文件夹

      1. 下载 opencv 4.5.4

      2. 解压到 opencv-4.5.4 文件夹内,并进入该文件夹

        wget -q https://github.com/opencv/opencv/archive/4.5.4.zip -O opencv-4.5.4.zip
        unzip -q opencv-4.5.4.zip
        cd opencv-4.5.4
        

      此时,文件夹结构如图所示:
      image-20220518152817266

    4. 编译

      1. 可选配置步骤,下面的指令都在 opencv-4.5.4 文件夹中执行

        1. strip zlib dependency and use stb-based highgui implementation (optional)

          patch -p1 -i ../opencv-4.5.4-no-zlib.patch
          truncate -s 0 cmake/OpenCVFindLibsGrfmt.cmake
          rm -rf modules/gapi
          rm -rf modules/highgui
          cp -r ../highgui modules/
          
        2. patch opencv source for no-rtti build (optional)

          patch -p1 -i ../opencv-4.5.4-no-rtti.patch
          
        3. apply your opencv options to opencv4_cmake_options.txt

          opencv4_cmake_options.txt 文件在 /opencv-mobile/opencv4_cmake_options.txt

      2. 依次执行指令进行编译

        mkdir build-arm-linux-gnueabihf && cd build-arm-linux-gnueabihf
        cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchains/arm-linux-gnueabihf.toolchain.cmake \
                -DCMAKE_C_FLAGS="-fno-rtti -fno-exceptions" -DCMAKE_CXX_FLAGS="-fno-rtti -fno-exceptions" \
                -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release `cat ../../opencv4_cmake_options.txt` -DBUILD_opencv_world=OFF ..
        cmake --build . -j 2
        cmake --build . --target install
        
    5. 编译完成

      1. 输出位于 ./build-arm-linux-gnueabihf/install 中
      2. 把 install 移动到合适位置,如 /thirdpart/opencv4.5.4/my-gnueabihf/
    6. 使用编译好的库

      main.cpp

      #include <opencv2/opencv.hpp>
      #include <iostream>
      int main()
      {
          cv::Mat mat = cv::Mat::zeros(256,256, CV_8UC1);
          {
              cv::rectangle(mat, cv::Rect(40, 45, 51, 65), cv::Scalar(255), -1, cv::LINE_8, 0);//绘制填充矩形
              cv::rectangle(mat, cv::Rect(180, 180, 85, 21), cv::Scalar(255), -1, cv::LINE_8, 0);//绘制填充矩形
              std::cout << "mat.rows = " << mat.rows << std::endl;
              std::cout << "mat.cols = " << mat.cols << std::endl;
          }
          return 0;
      }
      

      demo makefile

      # 改成你的路径
      OPENCV_DIR := /thirdpart/opencv4.5.4/my-gnueabihf/
      THIRD_PART_INCLUDE := -I$(OPENCV_DIR)include/opencv4 -I$(OPENCV_DIR)include/opencv4/opencv2
      THIRD_PART_LIBRARY := $(OPENCV_DIR)lib/libopencv_highgui.a $(OPENCV_DIR)lib/libopencv_features2d.a $(OPENCV_DIR)lib/libopencv_imgproc.a $(OPENCV_DIR)lib/libopencv_photo.a $(OPENCV_DIR)lib/libopencv_video.a $(OPENCV_DIR)lib/libopencv_core.a
      
      TARGET = Test_OpenCV_Mobile
      START:
          @echo START
          rm -rf $(TARGET)
          arm-linux-gnueabihf-g++ -O2 -std=c++11 -lpthread -fopenmp -ldl $(CFLAGS) $(THIRD_PART_INCLUDE) -o $(TARGET) ./main.cpp $(THIRD_PART_LIBRARY)
      
      .PHONY:clean
      
      clean:
          rm -rf $(BINDIR)
      

      image-20220518155708643

      demo CMakeLists.txt

      cmake_minimum_required(VERSION 3.20)
      
      set (ARM_LINUX_GCC_PATH /usr/local/arm/gcc-linaro-5.3.1-2016.05-i686_arm-linux-gnueabihf/bin/) # 改成你的路径
      set (CMAKE_C_COMPILER ${ARM_LINUX_GCC_PATH}arm-linux-gnueabihf-gcc)
      set (CMAKE_CXX_COMPILER ${ARM_LINUX_GCC_PATH}arm-linux-gnueabihf-g++)
      
      project(Test_OpenCV_Mobile)
      set(CMAKE_CXX_STANDARD 11)
      set(OpenCV_DIR "/thirdpart/opencv4.5.4/my-gnueabihf/lib/cmake/opencv4") # 改成你的路径
      find_package(OpenCV REQUIRED)
      FIND_PACKAGE(OpenMP REQUIRED)
      add_executable(Test_OpenCV_Mobile main.cpp)
      target_link_libraries(Test_OpenCV_Mobile pthread)
      target_link_libraries(Test_OpenCV_Mobile dl)
      target_link_libraries(Test_OpenCV_Mobile -fopenmp)
      target_link_libraries(Test_OpenCV_Mobile ${OpenCV_LIBS})
      

      image-20220518160849421

      运行结果
      image-20220518154610943


    最后在末尾推荐使用,PRemoteM 来打开 SSH、SFTP、RDP 远程会话。

  • 相关阅读:
    PYTHON简介
    zabbix4.0搭建2
    zabbix4.0搭建1
    zabbix监控
    Linux中vim编辑命令
    零基础逆向工程25_C++_02_类的成员权限_虚函数_模板
    零基础逆向工程24_C++_01_类_this指针_继承本质_多层继承
    零基础逆向工程23_PE结构07_重定位表_IAT表(待补充)
    零基础逆向工程22_PE结构06_导入表
    零基础逆向工程21_PE结构05_数据目录表_导出表
  • 原文地址:https://www.cnblogs.com/singlex/p/16285234.html
Copyright © 2020-2023  润新知