Build opencv application for ARM on x86 - linux

I have problem with building aplication with opencv library for ARM.
I installed Opencv 2.4.6.1 for my pc with helping this a tutorial http://docs.opencv.org/doc/tutorials/introduction/linux_install/linux_install.html#linux-installation
After that i try build example for my pc:
gcc main.c -o main ´pkg-config --libs --clags opencv´ -lpthread
It works.
Next, i install arm-linux-gnueabihf-gcc, wrote example and tryied it. It works.
now i make opencv library for ARM
cd /opt/opencv-2.4.6.1/platforms/linux
mkdir build_hardfp
pico arm-gnueabi.toolchain.cmake
change 4.6 to 4.7.2
cd build_hardfp
cmake -DCMAKE_TOOLCHAIN_FILE=../arm-gnueabi.toolchain.cmake -DWITH_TBB=OFF -DWITH_QT=OFF -D SOFTFP=OFF -D WITH_V4L=ON -D WITH_OPENGL=ON –D CMAKE_BUILD_TYPE=RELEASE –D BUILD_SHARED_LIBS=OFF -D CMAKE_INSTALL_PREFIX=/opt/opencv-2.4.6.1/rpi ../../..
make
make install
And now my problem:
I try build my example
arm-linux-gnueabihf-gcc -o main main.c -lpthread -I/opt/opencv-2.4.6.1/rpi/include -I/opt/opencv-2.4.6.1/rpi/include/opencv -I/opt/opencv-2.4.6.1/rpi/lib -L/opt/opencv-2.4.6.1/rpi/ -lcv -lhighgui
main.c: In function ‘main’:
main.c:12:8: warning: assignment makes pointer from integer without a cast [enabled by default]
/home/honza/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcv
/home/honza/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lhighgui
collect2: error: ld returned 1 exit status
Probably i must have all the dependencies compile for ARM architecture. I think, i took care of this in previous steps, with using cmake.
Maybe i didn't set paths.
What am I doing wrong and how to fix it?

You use old names for OpenCV libraries : -lcv -lhighgui. OpenCV has new structure from 2.0 version. Use this flags : -lopencv_core -lopencv_highgui.

Related

Build a program with GLFW3 on Linux

I know this question has been asked many times before but I have been trying to get this working for days and none of the current answers solve my problem. I'd appreciate not being linked to this post: How to build & install GLFW 3 and use it in a Linux project Most of the answers I have seen redirect there but I have gone through it thoroughly and am still having problems.
I am running Linux Mint 17.1.
I have downloaded and built GLFW 3.1.1:
*Downloaded source; extracted; terminal to extract directory*
cmake .
make install
I have also downloaded the example program at http://www.glfw.org/docs/3.0/quick.html#quick_example
I am using the following build commands:
g++ -std=c++11 -c HelloGLFW.cpp
g++ HelloGLFW.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi
The program compiles fine but when I try to link it I get these errors:
//usr/local/lib/libglfw3.a(x11_init.c.o): In function `initExtensions':
x11_init.c:(.text+0x1aeb): undefined reference to `XineramaQueryExtension'
x11_init.c:(.text+0x1b05): undefined reference to `XineramaIsActive'
//usr/local/lib/libglfw3.a(x11_init.c.o): In function `_glfwCreateCursor':
x11_init.c:(.text+0x21f9): undefined reference to `XcursorImageCreate'
x11_init.c:(.text+0x22d0): undefined reference to `XcursorImageLoadCursor'
x11_init.c:(.text+0x22e0): undefined reference to `XcursorImageDestroy'
//usr/local/lib/libglfw3.a(x11_monitor.c.o): In function `_glfwPlatformGetMonitors':
x11_monitor.c:(.text+0x6e9): undefined reference to `XineramaQueryScreens'
collect2: error: ld returned 1 exit status
I have also gone through the instructions on the GLFW website but they seem to be quite lacking for Linux. I have gotten it working on Linux before but that was a year ago and I can't replicate it.
Can someone please let me know all the steps required to build a program with GLFW3 on Linux (including all dependencies required)?
When glfw3 was installed using cmake a file glfw3.pc was created along with it. This is a pkg-config file and lists what libraries are required for linking.
For me this file was located in /usr/local/lib/pkgconfig
The command I used to successfully build the program with was:
g++ HelloGLFW.cpp -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread
The GLFW site does list details at http://www.glfw.org/docs/latest/build.html#build_link_pkgconfig but it's a bit unclear what to look for if you aren't that familiar with Linux systems.
Specificity the instructions list this command for compiling with the static glfw3 library:
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --static --libs glfw3`
and with the dynamic glfw3 library:
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3`

configure test with static lib

I am trying to cross compile libpng for RaspberryPi on Ubuntu 14.04 (x_64) with zlib
but configure fails with
configure:11400: arm-linux-gnueabihf-gcc -o conftest -g -O2 -I/home/user/RPI_DEV/lib/include conftest.c -lz -lm >&5
/home/user/RPI_DEV/xtools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz
collect2: error: ld returned 1 exit status
configure:11400: $? = 1
configure: failed program was:
....
Because I am using toolchain for arm, arm-ld cant find zlib.
Is there any option for configure not to compile with shared lib but to try with static lib (eg. -static -lz).
Command is
./configure --enable-static=true --enable-shared=false --with-zlib-include="/home/user/RPI_DEV/lib/include" --with-zlib-lib="/home/user/RPI_DEV/lib/lib" LDFLGS="-L/home/user/RPI_DEV/lib/lib" CPPFLAGS="-I/home/user/RPI_DEV/lib/include" -enable-static --host=arm-linux-gnueabihf --prefix=/home/user/RPI_DEV/lib --exec-prefix=/home/user/RPI_DEV/lib
You need to cross build and install zlib into your toolchain before trying to use it in another project.
What you are doing might work but only if you spell LDFLAGS correctly:
LDFLGS="-L/home/user/RPI_DEV/lib/lib"
Note the missing 'A'. I don't know why your second attempt worked, given you had the same misspelling; possibly you had a correct LDFLAGS in your environment?
Anyway there should be a Ubuntu cross-development guide somewhere that explains how to do this. It's slightly off topic but for Gentoo you use 'crossdev' to install the toolchain then a crossdev specific version of the normal package installation mechanism ([host]-emerge) to install zlib into the toolchain.
Also, the arguments --with-zlib-include and --with-zlib-lib are not supported by any current version of libpng I can find. If you are cross-compiling libpng for an RPi (or, indeed, any ARM system) you should be using the latest version of 1.6 that you can find.
Unless someone solves this the RIGHT way, this is hack I've done.
Open configure.ac file
Find and comment out line
AC_CHECK_LIB(z, zlibVersion, , AC_ERROR([zlib not installed]))
Configure will pass wihout check for zlib and then add zlib by hand
LDFLGS="-L/home/user/RPI_DEV/lib/lib -L/home/user/RPI_DEV/lib/lib/libz.a"
Run autoconf
Run ./configure ...

crt1.o error in mips cross compiler

I would like to generate MIPS binaries using gcc on an x86 machine. In order to install MIPS cross-compiler I followed the directions on this page. I could install gcc and binutils successfully. I tried to to compile a simple hello world program using the cross compiler.
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 hi.c
I got the following error.
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crt1.o: No such file or directory
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crti.o: No such file or directory
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find -lc
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crtn.o: No such file or directory
collect2: error: ld returned 1 exit status
I did some research online to figure out what the problem was, and changed the command I used to the following.
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -B/usr/lib/i386-linux-gnu -mips1 hi.c
Now I get this error message:
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: /usr/lib/i386-linux-gnu/crt1.o: Relocations in generic ELF (EM: 3)
/usr/lib/i386-linux-gnu/crt1.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
I am not sure what the problem is. The only thing I can think of is the "--without-headers" option passed to configure program when building gcc. Configure command for gcc given on the linux-mips page is as below.
% ../gcc-3.8.2/configure --target=$TARGET --prefix=$PREFIX \
--enable-languages=c --without-headers \
--with-gnu-ld --with-gnu-as \
--disable-shared --disable-threads \
--disable-libmudflap --disable-libgomp \
--disable-libssp --disable-libquadmath \
--disable-libatomic
I would appreciate some help. The system on which I generated the cross compiler uses gcc4.7.2-5. I used the sources for gcc-4.8.2 and binutils-2.24 to generate the cross compiler.
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 hi.c
Add a SYSROOT to the compile command. It should look similar to:
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 --sysroot=/opt/cross/... hi.c
The SYSROOT will provide the header and library path automatically (rather than adding -I and -L individually).
You will know when you have a SYSROOT because there will be a bin/, include/ and lib/ in the path used. For example, here's a SYSROOT for arm-linux-gnueabi (i.e., arm-linux-gnueabi-gcc and arm-linux-gnueabi-g++):
$ ls /usr/arm-linux-gnueabi
bin include lib
So, in this example, you would use --sysroot=/usr/arm-linux-gnueabi.
If you need help with locating a SYSROOT, then perform a find:
$ find /usr -name crt1.o
/usr/arm-linux-gnueabi/lib/crt1.o
/usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o
/usr/lib/x86_64-linux-gnu/crt1.o
In your case, you would probably search from /opt/cross. Obviously, you would want the one for the target (arm-linux-gnueabi), and not the ones for the host (x86_64-linux-gnu).
Adding --sysroot= would resolve this issue.
As you are cross-compiling you shouldn't select just any other folder which has crt1.o or crtX.o as your sysroot directory. It could be your host-machine's files. (Which if you are running on a x86, it would be for x86). Again it varies from 32bit and 64bit.
With newer version's of GCC toolchain, you need to have a sdk part of it which has the appropriate sysroot and crt1.o. This should go with your ABI and your target architecture.

undefined reference when cross-compiling for ARM with static OpenCV libraries

I'm trying to compile a simple test program using static OpenCV libraries that have been compiled using an ARM compiler. But when I try to compile it with the command
$arm-linux-gnueabihf-g++ `pkg-config --static opencv` -I/usr/local/include -L<path to static libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2
This gives
/tmp/ccxNeUbK.o: In function main':
ARMtest2.cpp:(.text+0x8a): undefined reference tocv::Mat::ones(int, int, int)'
/tmp/ccxNeUbK.o: In function cv::Mat::~Mat()':
ARMtest2.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x20): undefined reference tocv::fastFree(void*)'
/tmp/ccxNeUbK.o: In function cv::Mat::release()':
ARMtest2.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x30): undefined reference tocv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
The code itself is just some simple test code that prints a Mat type variable.
I compiled the static OpenCV library with cmake-gui. I selected UNIX Makefile and then selected 'specify options for cross-compiling' where I gave the path to the ARM (arm-linux-gnueabihf) gcc and g++ compiler. Then I unticked BUILD_SHARED_LIB so it compiled static libraries. It seemed to compile fine without errors. After that I did make & sudo make install.
I also tried it with shared libraries and that worked fine on the ARM board (once I copied the libraries to the board and exported the library path).
The static .a files landed nicely in the build folder. Apparently it can also find it when I -L link to it. I have tried reversing the order of the libraries, but to no avail.
So I'm a bit at a loss what is going wrong.
I solved it. Using the normal --static pkg-config command to compile with OpenCV libraries;
`pkg-config --libs --static opencv`
Of course I installed the static libraries also to the folder /usr/local/lib where libraries get installed first. But still i don't know what I missed in the command line I tried to use. I had a look in the config file /usr/local/lib/pkgconfig/opencv.pc
Here is whats in it:
# Package Information for pkg-config
prefix=/usr/local
exec_prefix=${prefix}
libdir=
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include
Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.4.9
Libs: ${exec_prefix}/lib/libopencv_calib3d.so ${exec_prefix}/lib/libopencv_contrib.so ${exec_prefix}/lib/libopencv_core.so ${exec_prefix}/lib/libopencv_features2d.so ${exec_prefix}/lib/libopencv_flann.so ${exec_prefix}/lib/libopencv_gpu.so ${exec_prefix}/lib/libopencv_highgui.so ${exec_prefix}/lib/libopencv_imgproc.so ${exec_prefix}/lib/libopencv_legacy.so ${exec_prefix}/lib/libopencv_ml.so ${exec_prefix}/lib/libopencv_nonfree.so ${exec_prefix}/lib/libopencv_objdetect.so ${exec_prefix}/lib/libopencv_ocl.so ${exec_prefix}/lib/libopencv_photo.so ${exec_prefix}/lib/libopencv_stitching.so ${exec_prefix}/lib/libopencv_superres.so ${exec_prefix}/lib/libopencv_ts.a ${exec_prefix}/lib/libopencv_video.so ${exec_prefix}/lib/libopencv_videostab.so -lrt -lpthread -lm -ldl
Cflags: -I${includedir_old} -I${includedir_new}
I believe this is what is being called with the pkg-config <--something_or_other> opencv line.
And saw some other things that probably get linked when compiling -lrt -lpthread -lm -ldl Not really sure though as I tried it ina normal command line and I apparently still missed somethings.
But it worked, so didn't really bother too much with it much further :)
In your command:
*$arm-linux-gnueabihf-g++ `pkg-config --static opencv` -I/usr/local/include -L<path to static libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2*
The cflags was missing.
Try with:
$arm-linux-gnueabihf-g++ `pkg-config --cflags --static opencv` -I/usr/local/include -L<path to static cross-compiled libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2
Assuming here that your cross-compiled headers are saved in /usr/local/include (as you specified).

Incompatible libc.so.6 Found During Cross-Compilation of Qt5 OpenGL Test for i.MX6

I'm trying to cross-compile Qt5 for the Freescale i.MX6 processor. I've already built an image using the latest Yocto package.
Before compilation of qtbase, a test for OpenGL functionality is first ran by compiling an some OpenGL code. However, during this test the compiler complains that an incompatible libc.so.6 is found.
I've discovered in another post (which I can't find at the moment), that such an error occurs because /lib/libc.so.6 is actually a symbolic link which points to the actual shared object file. However, the compiler does not use the shared object file pointed to by libc.so.6, instead trying to link to the symbolic link itself, thus the compatibility issue.
Here is the output when the configure script is ran:
OpenGL ES 2.x auto-detection... ()
/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/bin/armv7a-vfp-neon-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++ -c -pipe -mfloat-abi=softfp -O2 -O2 -march=armv7-a -mfpu=neon -DLINUX=1 -DEGL_API_FB=1 -Wall -W -fPIE -I../../../mkspecs/devices/linux-imx6-g++ -I. -I/home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint/usr/include -o opengles2.o opengles2.cpp
/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/bin/armv7a-vfp-neon-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++ -Wl,-rpath-link,/home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint/usr/lib -Wl,-O1 -o opengles2 opengles2.o -L/home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint/usr/lib -lGLESv2 -lEGL -lGAL
/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/libexec/armv7a-vfp-neon-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.7.2/ld: skipping incompatible /lib/libc.so.6 when searching for /lib/libc.so.6
/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/libexec/armv7a-vfp-neon-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.7.2/ld: cannot find /lib/libc.so.6
/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/libexec/armv7a-vfp-neon-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.7.2/ld: skipping incompatible /usr/lib/libc_nonshared.a when searching for /usr/lib/libc_nonshared.a
/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/libexec/armv7a-vfp-neon-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.7.2/ld: cannot find /usr/lib/libc_nonshared.a
/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/libexec/armv7a-vfp-neon-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.7.2/ld: cannot find /lib/ld-linux.so.3
collect2: error: ld returned 1 exit status
gmake: *** [opengles2] Error 1
OpenGL ES 2.x disabled.
The OpenGL ES 2.0 functionality test failed!
Here is the script I used to supply the proper options to the configure script:
#!/bin/sh
./configure -v -opensource -confirm-license -no-pch -opengl es2 \
-make libs -device imx6 \
-make examples -make demos \
-device-option CROSS_COMPILE=/home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/bin/armv7a-vfp-neon-poky-linux-gnueabi/arm-poky-linux-gnueabi- \
-sysroot /home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint -no-gcc-sysroot \
-prefix /opt/qt5
At the moment, I'm considering just renaming the actual shared object file to libc.so.6, but that doesn't seem like a good way to fix things.
It seems that you are compiling against the wrong libc. The location of the correct libc should be: /home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint/lib/ Can you check that? Run in that folder:
file libc.so.6
Have a look if the architecture is fine. I do not have the sources in front of me, so please give feedback if things are going wrong.
Your application is compiled in a chroot environment (see man chroot). The folder /home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint acts as the new rootfolder for your application. This is configured in the -sysroot option of your configure script. This is not valid for gcc, because the -no-gcc-sysroot is on. So the linker is looking to your native /lib/ folder to find the libraries. They are not there of course.
So, can you try the following things:
1) remove the -no-gcc-sysroot option in the configure script. Configure again and try to make.
2) This can possibly fail because the compiler does not find back it's own components. Please mount the directory of the compiler into your chroot enviroment. Run the next commands:
mkdir /home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint/usr/bin -p
mount --bind /home/Desktop/poky-dylan-9.0.0/build/tmp/sysroots/x86_64-linux/usr/bin/ /home/Desktop/poky-dylan-9.0.0/build/tmp/deploy/images/mountpoint/usr/bin
Configure again and try again to make.
3) If it still is not working, the cross-compiler is not set properly. Change into the configure script argument list the CROSS_COMPILE argument:
CROSS_COMPILE=/usr/bin/armv7a-vfp-neon-poky-linux-gnueabi/arm-poky-linux-gnueabi-
I wish you good luck. Let me know if it is working or not.

Resources