Raspberry pi opencv 链接问题的交叉编译
Posted
技术标签:
【中文标题】Raspberry pi opencv 链接问题的交叉编译【英文标题】:Cross-Compile for Raspberry pi opencv linking problems 【发布时间】:2016-10-01 11:08:31 【问题描述】:(抱歉英语不好,我是德国人) 各位程序员, 我正在拼命尝试在我的 linux(fedora) x86_x64 笔记本电脑上为 linux(raspian) Raspberry pi 3 交叉编译一个程序(使用 OpenCV)。
我正在关注本教程 (https://solderspot.wordpress.com/2016/02/04/cross-compiling-for-raspberry-pi-part-ii/) 和一个简单的 std::cout
cmake_minimum_required (VERSION 2.8)
project (CVS)
find_package(OpenCV REQUIRED)
SET(COMPILE_DEFINITIONS -Werror)
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -std=c++11")
add_definitions(-DHOST_ROBO_DIR=/home/username/Dropbox/Roboter)
include_directories(SYSTEM $PIROOT/opt/vc/include $PIROOT/opt/vc/include/interface/vcos/pthreads $PIROOT/opt/vc/include/interface/vmcs_host/linux )
link_directories( $PIROOT/opt/vc/lib )
add_executable (CVS ../source/main.cpp)
问题来自 OpenCV... 如果我使用上面的 CMakeLists.txt,它会生成(出于显而易见的原因)许多“未定义的引用”错误,例如:“对 `cv::waitKey(int)' 的未定义引用”
如果我在 CMakeLists.txt 中添加“target_link_libraries(CVS $OpenCV_LIBS)”或“target_link_libraries(CVS -lopencv_core)”会产生以下错误: /home/username/pidev/piroot/usr/local/lib/libopencv_core.so:未定义引用 `std::__throw_out_of_range_fmt(char const*, ...)@GLIBCXX_3.4.20'
如果我用“SET(TOOLROOT $ PITOOLS/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf)" 我收到以下错误:
[username@MSI-Linux msi]$ cmake -DCMAKE_TOOLCHAIN_FILE=~/pidev/pi-toolchain.cmake .
-- The C compiler identification is GNU 4.9.3
-- The CXX compiler identification is GNU 4.9.3
-- Check for working C compiler: /home/username/pidev/pitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
-- Check for working C compiler: /home/username/pidev/pitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -- broken
CMake Error at /usr/share/cmake/Modules/CMakeTestCCompiler.cmake:61 (message):
The C compiler
"/home/username/pidev/pitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /home/username/Dropbox/Roboter/raspySync/CVS/cvs5-6/msi/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/gmake" "cmTC_b1abe/fast"
/usr/bin/gmake -f CMakeFiles/cmTC_b1abe.dir/build.make
CMakeFiles/cmTC_b1abe.dir/build
gmake[1]: Verzeichnis
„/home/username/Dropbox/Roboter/raspySync/CVS/cvs5-6/msi/CMakeFiles/CMakeTmp“
wird betreten
Building C object CMakeFiles/cmTC_b1abe.dir/testCCompiler.c.o
/home/username/pidev/pitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
--sysroot=/home/username/pidev/piroot
-Wl,-rpath-link,/home/username/pidev/piroot/opt/vc/lib
-Wl,-rpath-link,/home/username/pidev/piroot/lib/arm-linux-gnueabihf
-Wl,-rpath-link,/home/username/pidev/piroot/usr/lib/arm-linux-gnueabihf
-Wl,-rpath-link,/home/username/pidev/piroot/usr/local/lib -o
CMakeFiles/cmTC_b1abe.dir/testCCompiler.c.o -c
/home/username/Dropbox/Roboter/raspySync/CVS/cvs5-6/msi/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTC_b1abe
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_b1abe.dir/link.txt
--verbose=1
/home/username/pidev/pitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
--sysroot=/home/username/pidev/piroot
-Wl,-rpath-link,/home/username/pidev/piroot/opt/vc/lib
-Wl,-rpath-link,/home/username/pidev/piroot/lib/arm-linux-gnueabihf
-Wl,-rpath-link,/home/username/pidev/piroot/usr/lib/arm-linux-gnueabihf
-Wl,-rpath-link,/home/username/pidev/piroot/usr/local/lib
CMakeFiles/cmTC_b1abe.dir/testCCompiler.c.o -o cmTC_b1abe -rdynamic
/home/username/pidev/pitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.3/../../../../arm-linux-gnueabihf/bin/ld:
cannot find crt1.o: No such file or directory
/home/username/pidev/pitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.3/../../../../arm-linux-gnueabihf/bin/ld:
cannot find crti.o: No such file or directory
collect2: error: ld returned 1 exit status
CMakeFiles/cmTC_b1abe.dir/build.make:97: die Regel für Ziel
„cmTC_b1abe“ scheiterte
gmake[1]: *** [cmTC_b1abe] Fehler 1
gmake[1]: Verzeichnis
„/home/username/Dropbox/Roboter/raspySync/CVS/cvs5-6/msi/CMakeFiles/CMakeTmp“
wird verlassen
Makefile:126: die Regel für Ziel „cmTC_b1abe/fast“ scheiterte
gmake: *** [cmTC_b1abe/fast] Fehler 2
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:2 (project)
-- Configuring incomplete, errors occurred!
See also "/home/username/Dropbox/Roboter/raspySync/CVS/cvs5-6/msi/CMakeFiles/CMakeOutput.log".
See also "/home/username/Dropbox/Roboter/raspySync/CVS/cvs5-6/msi/CMakeFiles/CMakeError.log".
[username@MSI-Linux msi]$
如果有人能回答以下问题之一,我将不胜感激: - 如何交叉编译使用 OpenCV 命令的程序 - 为什么存在“对 `std::__throw_out_of_range_fmt(char const*, ...)@GLIBCXX_3.4.20' 的未定义引用”和“C 编译器...无法编译简单的测试程序”。 - 如果我在程序中添加这样的东西,会是坏的还是非常糟糕的风格:
namespace std
void __throw_out_of_range_fmt(char const*, ...)
std::cout << "throw out of range error\n";
这是我的 ~/pidev/pi-toolchain.cmake:
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(DEVROOT $ENVHOME/pidev)
SET(PIROOT $DEVROOT/piroot)
SET(PITOOLS $DEVROOT/pitools)
SET(TOOLROOT $PITOOLS/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64)
# specify the cross compiler
SET(CMAKE_C_COMPILER $TOOLROOT/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER $TOOLROOT/bin/arm-linux-gnueabihf-g++)
SET(CMAKE_SYSROOT $PIROOT)
SET(CMAKE_FIND_ROOT_PATH $PIROOT)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(FLAGS "-Wl,-rpath-link,$PIROOT/opt/vc/lib -Wl,-rpath-link,$PIROOT/lib/arm-linux-gnueabihf -Wl,-rpath-link,$PIROOT/usr/lib/arm-linux-gnueabihf -Wl,-rpath-link,$PIROOT/usr/local/lib")
UNSET(CMAKE_C_FLAGS CACHE)
UNSET(CMAKE_CXX_FLAGS CACHE)
SET(CMAKE_CXX_FLAGS $FLAGS CACHE STRING "" FORCE)
SET(CMAKE_C_FLAGS $FLAGS CACHE STRING "" FORCE)
【问题讨论】:
【参考方案1】:“找不到 crt1.o:没有这样的文件或目录”错误是“arm-rpi-4.9.3-linux-gnueabihf”工具链的一个已知问题,请参阅4.9 toolchain issue #50。
“`std::__throw_out_of_range_fmt(char const*, ...)@GLIBCXX_3.4.20'”错误与 gcc 4.8 有关,请参阅 std::__throw_out_of_range_fmt(char const*, …)@GLIBCXX_3.4.20'。我不太清楚为什么会发生这种情况,因为我能够使用“gcc-linaro-arm-linux-gnueabihf-raspbian-x64”-toolchain 构建 opencv。
也许你对我的做法有点运气:How do I cross compile OpenCV for the Raspberry Pi with additional modules (highgui…)
CMakeLists.txt 示例
project(Test)
cmake_minimum_required(VERSION 3.2)
set(CMAKE_CXX_STANDARD 11)
aux_source_directory(. SRC_LIST)
find_package(OpenCV REQUIRED)
add_executable($PROJECT_NAME $SRC_LIST)
target_link_libraries($PROJECT_NAME $OpenCV_LIBS)
像这样调用 cmake:
cmake -D CMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE -D PIROOT=$MOUNT_DIR -D TOOLROOT=$TOOLCHAIN ..
【讨论】:
以上是关于Raspberry pi opencv 链接问题的交叉编译的主要内容,如果未能解决你的问题,请参考以下文章
Opencv:无法打开显示:C++、Raspberry Pi 无头连接
Raspberry Pi 上的 OpenCV 人脸检测速度很慢
OpenCV VideoCapture 在 Raspberry Pi 2 上总是失败
在 Raspberry PI 上使用 Python 和 OpenCV 进行图像处理 [关闭]