【问题标题】:Cross-compiling to Raspberry Pi, using Qt and opencv使用 Qt 和 opencv 交叉编译到 Raspberry Pi
【发布时间】:2016-01-21 11:44:45
【问题描述】:

cross-compile 到树莓派有多种方式,也有交叉编译Qtopencv 的解决方案。

但是,我找不到任何解决方案来交叉编译一个也使用 opencv 的 Qt 程序。

我在 64 位 PC 上使用 debian 尝试了以下操作:

  • 我使用 this tutorial 编译并设置 Qt 作为 ARM7 的交叉编译器。虽然它没有问题,但here is an answer 我发布了它为我解决了它。我现在可以在 Raspberry Pi 上使用图形 GUI 运行我的 Qt 程序(虽然只能全屏,但这是一个完全不同的问题)

  • 我在opencv官网关注the guide搭建opencv。它失败了No CMAKE_CXX_COMPILER could be found.

  • 1234563使用成功编译Qt:gcc-4.7-linaro-rpi-gnueabihf
  • 我指定了之前用来编译Qt的gnueabihf,作为编译器:

我创建了目录~/opt/opencv_build_arm7/,并在其中尝试了:

sudo cmake -DCMAKE_CXX_COMPILER=/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++ -DCMAKE_C_COMPILER=/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gcc -DCMAKE_TOOLCHAIN_FILE=/usr/dev/opencv/platforms/linux/arm-gnueabi.toolchain.cmake /usr/dev/opencv/

(下载的 opencv 源位于 /usr/dev/opencv/ 中,我最近使用我的 Qt 安装附带的 g++ 编译器成功地为 x64 平台编译了 opencv。)注意,&lt;user&gt; 是当前会话的用户名,以防其他初学者将来可能会尝试这些方法。

失败并出现以下错误(&lt;user&gt; 是我的用户名)

CMake 错误 /usr/share/cmake-3.0/Modules/CMakeTestCXXCompiler.cmake:54(消息): C++ 编译器
“/home//opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++” 无法编译简单的测试程序。

失败,输出如下:

更改目录:/home//temp/CMakeFiles/CMakeTmp

运行编译命令:"/usr/bin/make" "cmTryCompileExec117178613/fast"

/usr/bin/make -f CMakeFiles/cmTryCompileExec117178613.dir/build.make CMakeFiles/cmTryCompileExec117178613.dir/build

make1: 进入目录'/home//temp/CMakeFiles/CMakeTmp'

/usr/bin/cmake -E cmake_progress_report
/home//temp/CMakeFiles/CMakeTmp/CMakeFiles 1

构建 CXX 对象
CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler.cxx.o

/home//opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++ -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -o CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler。 cxx.o -c /home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx

/home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx:在 函数‘int main()’:

/home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx:4:10: 抱歉,未实现:Thumb-1 硬浮点 VFP ABI

CMakeFiles/cmTryCompileExec117178613.dir/build.make:57:配方 目标
'CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler.cxx.o' 失败

make1: ***
[CMakeFiles/cmTryCompileExec117178613.dir/testCXXCompiler.cxx.o] 错误 1

make1: 离开目录'/home//temp/CMakeFiles/CMakeTmp'

Makefile:118: 目标“cmTryCompileExec117178613/fast”的配方 失败

make: *** [cmTryCompileExec117178613/fast] 错误 2

我为编译器指定了一个绝对路径,但是即使我不指定它,只是将它添加到我的$PATH中,它仍然有同样的问题。

export PATH=$PATH:/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/

sudo cmake -DCMAKE_TOOLCHAIN_FILE=/usr/dev/opencv/platforms/linux/arm-gnueabi.toolchain.cmake /usr/dev/opencv/

如果我键入,编译器本身会正确找到

arm-linux-gnueabihf-g++ -v

找到成功:

使用内置规范。 COLLECT_GCC=./arm-linux-gnueabihf-c++ COLLECT_LTO_WRAPPER=/home/vszabi/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapper 目标:arm-linux-gnueabihf 配置: /opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/src/gcc-linaro-4.7-2012.07/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-linux-gnueabihf --prefix=/opt/dev/src/crosstool-ng/crosstool-ng- linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/install --with-sysroot=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran --enable-multilib --with-arch=armv6zk --with-tune=arm1176jzf-s --with-fpu=vfp --with-float=hard --with- pkgversion='crosstool-NG linaro-1.13.1-2012.07-20120720 - Linaro GCC 2012.07' --with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp=/opt/dev/src/crosstool-ng/crosstool-ng- linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/构建/静态 --with-mpc=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/构建/静态 --with-ppl=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/构建/静态 --with-cloog=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/构建/静态 --with-libelf=/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/构建/静态 --with-host-libstdcxx='-L/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/arm -linux-gnueabihf/build/静态/lib -lpwl' --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-gold --with-local-prefix=/opt/dev/src/crosstool-ng/ crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long 线程模型:posix gcc 版本 4.7.2 20120701(预发布)(crosstool-NG linaro-1.13.1-2012.07-20120720 - Linaro GCC 2012.07)

接下来我可以尝试什么? 使用 opencv/platforms/linux/arm-gnueabi.toolchain.cmake 打开 gui 版本的 cmake 显示的选项很少(只有 ARM_LINUX_SYSROOT、CMAKE_BUILD_TYPE、CMAKE_CONFIGURATION_TYPES、CMAKE_INSTALL_PREFIX、GCC_COMPILER_VERSION 和 LIBRARY_OUTPUT_PATH_ROOT,但没有使用 BUILD_opencv_xyz我可以禁用单个包),比我为 x86 或 x64 平台构建 opencv 时的 case 少得多。

我担心搜索不同的编译器可能会导致 Qt 出现问题,因为据我所知,要使 opencv 在 Qt 中工作,它必须使用与用于构建Qt 库并构建我的程序。每当我过去尝试它时没有注意这三件事(Qt libs,opencv,我的程序)需要使用相同的编译器进行编译,我总是在我包含任何opencv头文件时或者每当我遇到奇怪的崩溃从opencv调用任何函数。

【问题讨论】:

    标签: c++ qt opencv arm cross-compiling


    【解决方案1】:

    http://docs.opencv.org/doc/tutorials/introduction/crosscompilation/arm_crosscompile_with_cmake.html 上的教程似乎错误或过时。

    下载opencv 3.0的源码,树莓派的opencv/platforms/linux/arm-gnueabi.toolchain.cmake好像配置不够。

    配置

    访问arm-linux-gnueabihf工具链创建者的workgroup page,看来要支持Raspberry Pi中的ARM7,必须将以下选项传递给编译器:-mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4

    所以,我们必须编辑opencv/platforms/linux/arm-gnueabi.toolchain.cmake 文件并更改

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
    set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
    

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4")
    set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4")
    

    再次运行cmake,配置成功!

    制作

    在构建过程中,如果出现如下错误

    CMakeFiles/opencv_core.dir/src/rand.cpp.o:重定位 R_ARM_THM_MOVW_ABS_NC 对 `a local symbol' 不能在以下情况下使用 制作共享对象;使用 -fPIC 重新编译 CMakeFiles/opencv_core.dir/src/rand.cpp.o:无法读取符号:坏 价值

    只需将-fPIC 标志添加到cmake 文件中的CMAKE_C_FLAGSCMAKE_CXX_FLAGS 并再次运行make。

    部署

    使用Qt Creator进行部署,只需在你的.pro文件中设置头文件和库即可,例如:

    INCLUDEPATH += <your build dir>/install/include/opencv2/
    INCLUDEPATH += <your build dir>/install/include/
    LIBS += -L  "<your build dir>/install/lib/"
    LIBS += -lopencv_calib3d
    LIBS += -lopencv_core
    #... and so on
    

    您还必须将已编译的库(在 &lt;your build dir&gt;/install/lib/ 中找到)复制到 Raspberry Pi。使用 U 盘可能会弄乱符号链接,因此我建议使用 scp 来复制文件。

    如果您对 Linux 比较陌生(就像我自己一样),请不要忘记可执行文件不会像在 Windows 中那样自动在自己的文件夹中查找动态库。

    因此,您应该将库复制到通常会搜索它们的位置(例如 /usr/local/bin)或相应地更新您的 LD_LIBRARY_PATH

    为了进行快速而肮脏的测试,以查看一切是否正常,您可以将库复制到部署可执行文件的同一文件夹中,然后使用运行它

    $ LD_LIBRARY_PATH=. ./your_program
    

    测试

    Opencv 现在应该可以在 Raspberry Pi 上的 Qt 程序中运行了。

    除非我的 google-fu 很弱,否则这可能是第一个记录在案的在 Raspberry Pi 上运行带有 opencv 的 Qt GUI 应用程序的案例。 :)

    但是,请注意,窗口管理可能仍然存在一些问题。 尝试打开一个 opencv 窗口,例如,cv::namedWindow("image"); 可能会失败并出现以下错误:

    OpenCV 错误:未指定错误(该功能未实现。 使用 Windows、GTK+ 2.x 或 Carbon 支持重建库。如果你 在 Ubuntu 或 Debian 上,安装 libgtk2.0-dev 和 pkg-config,然后 在 cvNamedWindow 文件中重新运行 cmake 或配置脚本) /usr/dev/opencv/modules/highgui/src/window.cpp,第 516 行终止 在抛出 'cv::Exception' what() 的实例后调用: /usr/dev/opencv/modules/highgui/src/window.cpp:516:错误:(-2) 功能未实现。使用 Windows、GTK+ 重建库 2.x 或碳支持。如果您在 Ubuntu 或 Debian 上,请安装 libgtk2.0-dev 和 pkg-config,然后重新运行 cmake 或配置脚本 函数 cvNamedWindow

    我想我们应该按照它说的去做,但是cvNamedWindow 在 Qt GUI 应用程序中不是很有用,因为它通常只用于调试。因此,如果图像必须显示在您的应用程序中,将其转换为 QImage 可能比打开独立窗口更好。

    但是,其他一切似乎都正常,我成功地在 Raspberry Pi 上运行了复杂的图像匹配算法。

    (...如果我找到在窗口中运行 Qt 应用程序并使用 cvNamedWindow 的好的解决方案,将会更新)

    【讨论】:

    • 感谢您提供此解决方案。我按照您的建议更改了 cmake 标志,并成功生成了文件!
    猜你喜欢
    • 2021-12-17
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 2018-08-13
    相关资源
    最近更新 更多