Error while cross compiling QT-OpenCV app for RaspberryPi2

Hello,

I was able to compile simple QT app for RaspberryPi2 in the Ubuntu environment, meaning that required settings are already set (kits, debugger, compiler etc). However when this app uses OpenCV libraries I get the error below:

/usr/local/lib/libopencv_core.so:-1: error: file not recognized: File format not recognized
error: collect2: error: ld returned 1 exit status

Here is the .pro file:

QT += core
QT -= gui

CONFIG += c++11

TARGET = untitled
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

SOURCES += main.cpp

INCLUDEPATH += /usr/local/include

LIBS += -L/usr/local/lib
LIBS += -lopencv_core
LIBS += -lopencv_imgproc
LIBS += -lopencv_highgui
LIBS += -lopencv_ml
LIBS += -lopencv_video
LIBS += -lopencv_features2d
LIBS += -lopencv_objdetect
LIBS += -lopencv_flann
LIBS += -lopencv_imgcodecs

QT Build & Run Settings:

Device Type: Generic Linux Type
Sysroot: /home/mustafa/raspi/sysroot
Compiler: /home/mustafa/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++
Debugger: /home/mustafa/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gdb
Qt version: Qt 5.6.1 (/home/mustafa/raspi/qt5/bin/qmake)
CMake Tool: System Cmake at /usr/bin/cmake

OpenCV Physical Dirs:

Ubuntu Desktop Build: /usr/local/lib
OpenCV Cross Compile Build: /home/mustafa/raspi/opencv/platforms/linux/build_hardfp/lib
RasperryPi2 Build: /home/mustafa/raspi/sysroot/usr/local/lib (Copied built opencv libs from build_hardfp above to this folder so QT can find them under usr/local/lib)

Eventhoug I cross compiled OpenCV from source for Raspberry Pi2, I can not compile a simple app for Raspberry Pi2 using OpenCV under Ubuntu.

Lastly, here is the compile output:

10:00:39: Running steps for project untitled…
10:00:39: Starting: “/usr/bin/make” clean
rm -f main.o
rm -f *~ core *.core
10:00:39: The process “/usr/bin/make” exited normally.
10:00:39: Configuration unchanged, skipping qmake step.
10:00:39: Starting: “/usr/bin/make”
/home/mustafa/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ -c -pipe -march=armv7-a -marm -mthumb-interwork -mfpu=neon-vfpv4 -mtune=cortex-a7 -mabi=aapcs-linux -mfloat-abi=hard --sysroot=/home/mustafa/raspi/sysroot -O2 -std=gnu++0x -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_CORE_LIB -I…/untitled -I. -I…/raspi/sysroot/opt/vc/include -I…/raspi/sysroot/opt/vc/include/interface/vcos -I…/raspi/sysroot/opt/vc/include/interface/vcos/pthreads -I…/raspi/sysroot/opt/vc/include/interface/vmcs_host/linux -I/usr/local/include -I…/raspi/qt5pi/include -I…/raspi/qt5pi/include/QtCore -I. -I…/raspi/qt5/mkspecs/devices/linux-rasp-pi2-g++ -o main.o …/untitled/main.cpp
/home/mustafa/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ -Wl,-rpath-link,/home/mustafa/raspi/sysroot/opt/vc/lib -Wl,-rpath-link,/home/mustafa/raspi/sysroot/usr/lib/arm-linux-gnueabihf -Wl,-rpath-link,/home/mustafa/raspi/sysroot/lib/arm-linux-gnueabihf -mfloat-abi=hard --sysroot=/home/mustafa/raspi/sysroot -Wl,-O1 -Wl,-rpath,/usr/local/qt5pi/lib -o untitled main.o -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_objdetect -lopencv_flann -lopencv_imgcodecs -L/home/mustafa/raspi/qt5pi/lib -lQt5Core -lpthread
/usr/local/lib/libopencv_core.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
make: *** [untitled] Error 1
10:00:44: The process “/usr/bin/make” exited with code 2.
Error while building/deploying project untitled (kit: qt560rpi2)
When executing step "Make"
10:00:44: Elapsed time: 00:06.

Can anyone tell me whats wrong?

What is the output of the

$ file /usr/local/lib/libopencv_core.so

command?

Secondly, what is the output of the same compilation process when you call g++ with additional -Wl,--trace parameter?

Thank you for your reply. Here is the output:

file ~/raspi/sysroot/usr/local/lib/libopencv_core.so
/home/mustafa/raspi/sysroot/usr/local/lib/libopencv_core.so: symbolic link to `libopencv_core.so.3.1’

In addition to that I used objdump:

objdump -f ~/raspi/sysroot/usr/local/lib/libopencv_core.so

/home/mustafa/raspi/sysroot/usr/local/lib/libopencv_core.so: file format elf32-little
architecture: UNKNOWN!, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00021b10

However in a native built libopencv_core.so in a raspberry pi device, output is:

objdump -f /usr/local/lib/libopencv_core.so
/usr/local/lib/libopencv_core.so: file format elf32-littlearm
architecture: arm, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00021b10

So there is a mismatch. I dont understand why ubuntu doesnt recognize it as arm, since it is copied (scp) directly from raspberry pi2 native build.

I tried cross compiling OpenCV 3.1 again but saw different errors. Firstly I couldnt generate the .cmake file because of the errors. I had to change the original file to this (changes are in black/bold):

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER /home/mustafa/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER /home/mustafa/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++)
set(CMAKE_FIND_ROOT_PATH /home/mustafa/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin)
set(GCC_COMPILER_VERSION “4.6” CACHE STRING “GCC Compiler version”)

set(FLOAT_ABI_SUFFIX “”)
if (NOT SOFTFP)
set(FLOAT_ABI_SUFFIX “hf”)
endif()

find_program(CMAKE_C_COMPILER NAMES arm-linux-gnueabi${FLOAT_ABI_SUFFIX}-gcc-${GCC_COMPILER_VERSION})
find_program(CMAKE_CXX_COMPILER NAMES arm-linux-gnueabi${FLOAT_ABI_SUFFIX}-g+±${GCC_COMPILER_VERSION})
set(ARM_LINUX_SYSROOT /usr/arm-linux-gnueabi${FLOAT_ABI_SUFFIX} CACHE PATH “ARM cross compilation system root”)

set(CMAKE_CXX_FLAGS “” CACHE STRING “c++ flags”)
set(CMAKE_C_FLAGS “” CACHE STRING “c flags”)
set(CMAKE_SHARED_LINKER_FLAGS “” CACHE STRING “shared linker flags”)
set(CMAKE_MODULE_LINKER_FLAGS “” CACHE STRING “module linker flags”)
set(CMAKE_EXE_LINKER_FLAGS “-Wl,-z,nocopyreloc” CACHE STRING “executable linker flags”)

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")

set(CMAKE_SHARED_LINKER_FLAGS “-Wl,–fix-cortex-a8 -Wl,–no-undefined -Wl,–gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${CMAKE_SHARED_LINKER_FLAGS}”)
set(CMAKE_MODULE_LINKER_FLAGS “-Wl,–fix-cortex-a8 -Wl,–no-undefined -Wl,–gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${CMAKE_MODULE_LINKER_FLAGS}”)
set(CMAKE_EXE_LINKER_FLAGS “-Wl,–fix-cortex-a8 -Wl,–no-undefined -Wl,–gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${CMAKE_EXE_LINKER_FLAGS}”)

if(USE_NEON)
message(WARNING “You use obsolete variable USE_NEON to enable NEON instruction set. Use -DENABLE_NEON=ON instead.” )
set(ENABLE_NEON TRUE)
elseif(USE_VFPV3)
message(WARNING “You use obsolete variable USE_VFPV3 to enable VFPV3 instruction set. Use -DENABLE_VFPV3=ON instead.” )
set(ENABLE_VFPV3 TRUE)
endif()

set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${ARM_LINUX_SYSROOT})

if(EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${CUDA_TOOLKIT_ROOT_DIR})
endif()

set( CMAKE_SKIP_RPATH TRUE CACHE BOOL “If set, runtime paths are not added when using shared libraries.” )
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)

macro( find_host_program )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
if( CMAKE_HOST_WIN32 )
SET( WIN32 1 )
SET( UNIX )
elseif( CMAKE_HOST_APPLE )
SET( APPLE 1 )
SET( UNIX )
endif()
find_program( ${ARGN} )
SET( WIN32 )
SET( APPLE )
SET( UNIX 1 )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
endmacro()

macro to find packages on the host OS
macro( find_host_package )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
if( CMAKE_HOST_WIN32 )
SET( WIN32 1 )
SET( UNIX )
elseif( CMAKE_HOST_APPLE )
SET( APPLE 1 )
SET( UNIX )
endif()
find_package( ${ARGN} )
SET( WIN32 )
SET( APPLE )
SET( UNIX 1 )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
endmacro()

This generates the cmake file. However when I run “make” output is:

…
– Configuring done
– Generating done
– Build files have been written to: /home/mustafa/raspi/opencv/platforms/linux/build_hardfp
mustafa@mustafa-VirtualBox:~/raspi/opencv/platforms/linux/build_hardfp$ sudo make
Scanning dependencies of target zlib
[ 0%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/adler32.c.o
[ 0%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/compress.c.o
[ 0%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/crc32.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/deflate.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/gzclose.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/gzlib.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/gzread.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/gzwrite.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/inflate.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/infback.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/inftrees.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/inffast.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/trees.c.o
[ 1%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/uncompr.c.o
[ 2%] Building C object 3rdparty/zlib/CMakeFiles/zlib.dir/zutil.c.o
Linking C static library …/lib/libzlib.a
Error running link command: No such file or directory
make[2]: *** [3rdparty/lib/libzlib.a] Error 2
make[1]: *** [3rdparty/zlib/CMakeFiles/zlib.dir/all] Error 2
make: *** [all] Error 2

It is hard to find root cause of the problem with given inputs.

I have some suggestions for your workflow:

  • don’t mix cross-compiled and native compiled libraries, especially working on eabihf ABI
  • don’t use latest version of the toolchains, especially working on eabihf ABI
  • try same process with an softfp toolchain without any extra cpu optimization flags (you need to generate whole filesystem too)
  • drop Qt part, work on a simple opencv example so you can easily try with different toolchains
  • if you’re familiar with buildroot, give it a chance, if it works try to find out differencies with your manual build setup

Thanks for the nice suggestions. I changed the cmake configuration not to use external toolchain compilers. Instead I installed arm-gnueabihf-gcc-4.8 and arm-gnueabihf-g+±4.8 using this command:

sudo apt-get install gcc-arm-linux-gnueabihf

and

sudo apt-get install g+±arm-linux-gnueabihf

It compiled successfully. However when I run objdump command with cross compiled libs it stills prints architecture as “unknown”. I was expecting “arm”. However QT did not complain this time and built the project. When I copied the built binary it also run successfully on RaspberryPi 2.

1 Like