Cross compiling for raspberryPi -- including libraries from synchronized filesystem - c

I am trying to cross compile simple project on my PC to get working on RaspberryPi. I found some tutorials on web and made cmake file. Basic cmake file work on rpi side, but cross compile additional file have some problems. Makefiles are generated properly, but invoking make throws out that it can't find
wiringPi.h library, which ofc I am using. I have synchronized /lib and /usr from rpi to my pc.
Here is my cmake for cross compilation.
#info
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
# specify the cross compilers
SET(CMAKE_C_COMPILER
/home/voodoo16/raspberryPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER
/home/voodoo16/raspberryPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /home/voodoo16/raspberryPi/fs)
# 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)
Of course I invoke cmake creation via:
cmake -DCMAKE_TOOLCHAIN_FILE=crossCompile.cmake .
Files exist in fs folder. Here is output of find:
voodoo16#tesla:[~/raspberryPi/fs]$ find -name *wiringPi*
./usr/local/include/wiringPiSPI.h
./usr/local/include/wiringPi.h
./usr/local/include/wiringPiI2C.h
./usr/local/lib/libwiringPi.so
./usr/local/lib/libwiringPi.so.2.32
./usr/local/lib/libwiringPiDev.so
./usr/local/lib/libwiringPiDev.so.2.32
./usr/lib/libwiringPi.so
./usr/lib/libwiringPiDev.so
I suppose that I'm missing some cmake command which allows to see libraries from rpi filesystem not via pc system using standard #include <lib.h>.
Best regards,
voodoo16.

You need to set CMake variable CMAKE_SYSROOT for hint compiler about cross compilation:
set(CMAKE_SYSROOT "/home/voodoo16/raspberryPi/fs")
CMake variables CMAKE_FIND_* affects only on CMake find_* commands, they don't directly hint the compiler. From the other side, CMAKE_SYSROOT variable hints for find_* commands too.

Related

cross compiling C code with external libraries

Host system: x86-64 Linux, Ubuntu 20.04
Target system: aarch64 Linux, Debian 11, arm architecture: Cortex A53
I develop for an aarch64 based Linux system on matlab/simulink. This toolchain is currently worked out for Linux and Windows hosts. However due to additional IIO devices on the system it has become clear that the current approach of just hardcoding the IIO device numbers is not gonna work anymore.
Now I found libiio which works great when I compile simple programs on the target itself. However I have not managed to cross compile applications using the library.
I have been trying to cross compile the libiio library itself by making a cross compilation file:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_STAGING_PREFIX /home/maud/development/stage)
set(tools /usr/aarch64-none-linux-gnu)
set(CMAKE_C_COMPILER ${tools}/bin/aarch64-none-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/aarch64-none-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
when I run cmake ../ -DCMAKE_TOOLCHAIN_FILE=~/development/crosscomp.cmake
from the build folder that I made in the libiio folder it seems to work fine. But when I run make the issue starts.
[ 28%] Building C object CMakeFiles/iio.dir/dns_sd_avahi.c.o
Reaping winning child 0x55c895073d40 PID 36856
Live child 0x55c895073d40 (CMakeFiles/iio.dir/dns_sd_avahi.c.o) PID 36858
/home/maud/Downloads/libiio-master/dns_sd_avahi.c:24:10: fatal error: avahi-common/address.h: No such file or directory
24 | #include <avahi-common/address.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~
I get this error, I do have libavahi-common-dev and libavahi-client-dev installed.
But I think it wants aarch64 compiled versions of the dependencies.
And it makes me question whether this is even a feasible goal, whether what I'm doing is even going to get me to where I want to be.
Is it even possible to add a library like this to such a cross compiling toolchain?
I tried taking the .so file from the target, but it will complain about missing a bunch of other dependencies. And even then I will only have managed to build from a Linux host, building from a Windows host feels like it would require way more trouble but I could be wrong. I'm still learning a lot about how all this works.
I got it mostly working, I compiled the library localy on my ARM system, but I tore out a bunch of features that I didnt need anyway. this left me with a library that didnt have any external dependencies (like the previously mentioned avahi common/client and a bunch more), then referencing it in my makefile and inluding the the header file got it working.
Was also able to cross compile from my x86 based host.

How do you specify a specific compiler in for CMAKE builds in Windows

I am trying to get CMAKE to use a specific compiler when running. Specifically, I want it to use the locally installed GCC compiler. But when i try to set the CMAKE_C_COMPILER variable, it seems to fail.
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++")
cmake_minimum_required(VERSION 3.10)
PROJECT(hello C)
add_executable(hello hello.c)
UPDATE USING TOOLCHAIN
I tried to make it work using the following toolchain file, but it still chooses Visual Studio build tools.
# Toolchain File
# The target of this operating systems is
SET(CMAKE_SYSTEM_NAME Windows)
# which compilers to use for C and C++
SET(CMAKE_C_COMPILER gcc)
SET(CMAKE_CXX_COMPILER g++)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH C:/MyPrograms/MinGW/bin/ )
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
MORE UPDATES ON ISSUE
When i look at the cache file created when using the toolchain file, i find something interesting. It is trying to point to the correct compiler, but it is using the Visual Studio Generator still...
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Visual Studio 15 2017
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/
How do i deal with the generator here?
CMake is a tool that is intended for defining dependencies among the targets in your application. You define the dependencies and set the language requirements for your targets, and you ask CMake to generate files to help you build your targets. Having this in mind, please do not mess with the CMAKE_C(XX)_COMPILER variables directly in your CMakeLists.txt, but rather think of using toolchain files to define the specific compiler/linker properties. Using toolchain files, you can not only define different compiler/linker setups for your host but also do cross-compilation, in which the host and target devices are of different architecture.
EDIT. To be able to use the locally installed gcc compiler, you do not need to play with any of the (related) variables inside your CMakeLists.txt file. Instead, you should (re)define your PATH environment variable to include the corresponding (i.e., MinGW or Cygwin) binaries, and select an appropriate generator. Below is a minimal working example based on your code.
Assume that you have the following directory structure:
.
├── appveyor.yml
├── CMakeLists.txt
└── hello.c
with hello.c having the contents
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello world!\n");
return 0;
}
CMakeLists.txt having the contents
cmake_minimum_required(VERSION 3.10)
project(hello C)
add_executable(hello hello.c)
and finally, appveyor.yml having the following
image: Visual Studio 2013
environment:
matrix:
- generator: "Visual Studio 12 2013 Win64"
- generator: "MSYS Makefiles"
before_build:
- IF "%generator%"=="MSYS Makefiles" set PATH=C:\msys64\usr\bin;C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\bin;%PATH%
build_script:
- mkdir build
- cd build
- cmake -G "%generator%" ..
- cmake --build .
after_build:
- IF EXIST Debug cd Debug
- hello.exe
This example successfully builds on AppVeyor with both of the toolchains. The catch here is that when you go for MSYS Makefiles, or MinGW Makefiles for that matter, you should define your PATH variable to include the binaries to the compiler toolchain. In the above example, I simply use the default paths for AppVeyor's VMs. Another thing to note for appveyor.yml is that the Visual Studio generators use different (sub)directories for different CMAKE_BUILD_TYPEs. Hence, I first check the existence of the directory Debug, and if it exists, I change to the directory and run hello.exe.
I hope this answers your question.

Cross build third-party library locations on Linux

Ive been cross compiling my unit-tests to ensure they pass on all the platforms of interest, e.g. x86-linux, win32, win64, arm-linux
they unit tests require the CUnit library
So I've had to cross compile that also for each platform
That comes with its own autoconf stuff so you can easily cross-build it by specifying --host for configure
The question I have is where is the 'correct' place to have the CUnit libs installed for the various platforms? i.e. what should I set --prefix to for configure?
My initial guess was:
/usr/local/<platform>/lib/Cunit
i.e. setting --prefix /usr/local/<platform>
e.g. --prefix /usr/local/arm-linux-gnueabihf
which on sudo make install gives you:
/usr/local/arm-linux-gnueabihf/doc/CUnit
/usr/local/arm-linux-gnueabihf/include/CUnit
/usr/local/arm-linux-gnueabihf/lib
/usr/local/arm-linux-gnueabihf/share/CUnit
Obviously, if i don't specify a prefix for configure, each platform build overwrites the prev one which is no good
to then successfully link to these platform specific libs i need to specify the relevant lib dir for each target in its own LDFLAGS in the Makefile
Is this the right approach? Have I got the dir structure/location right for this sort of cross-build stuff? I assume there must be a defacto approach but not sure what it is..
possibly configure is supposed to handle all this stuff for me? maybe I just have to set --target correctly and perhaps --enable-multilib? all with --prefix=/usr/local?
some of the error msgs i get suggest /usr/lib/gcc-cross might be involve?
From reading more about cross compilation and the Gnu configure and build system it seems that I should just be setting the --target option for the configure step
but how do you know what the target names are? are they some fragment of the cross compiler names?
The 3 cross compilers I am using are:
arm-linux-gnueabihf-gcc-4.8
i686-w64-mingw32-gcc
x86_64-w64-mingw32-gcc
allowing me to cross-compile for ARM, win32 and win64
my host is 32 bit ubuntu, which I think might be --host i386-linux, but it seems that configure should get this right as its default
This is the procedure I finally figured out and got to work:
for each of my 3 cross-build tools (arm, win32, win64) my calls to configure looked like:
./configure --host=arm-linux-gnueabihf --build=i686-pc-linux-gnu --prefix=/usr/local/arm-linux-gnueabihf
./configure --host=i686-w64-mingw32 --build=i686-pc-linux-gnu --prefix=/usr/local/i686-w64-mingw32
./configure --host=x86_64-w64-mingw32 --build=i686-pc-linux-gnu --prefix=/usr/local/x86_64-w64-mingw32
each of these was followed by make, sudo make install
prior to calling configure for the arm cross build i had to do:
ln -s /usr/bin/arm-linux-gnueabihf-gcc-4.8 /usr/bin/arm-linux-gnueabihf-gcc
this was because the compiler had -4.8 tagged on the end so configure could not correctly 'guess' the name of the compiler
this issue did not apply to either the win32 or win64 mingw compilers
Note an additional gotcha was that when subsequently trying to link to these cross compiled CUnit libs, none of the cross compilers seemed to look in /usr/local/include by default so I had to manually add:
-I/usr/local/include
for each object file build
e.g. i added /usr/local/include to INCLUDE_DIRS in my Makefile
all this finally seems to have given me correctly cross built CUnit libs and I have successfully linked to them to produce cross built unit test binaries for each of the target platforms.
not at all easy and I would venture to call the configure option settings 'counter-intuitive' - as ever it is worth taking the time to read the relevant docs - this snippet was pertinent:
There are three system names that the build knows about: the machine
you are building on (build), the machine that you are building for
(host), and the machine that GCC will produce code for (target). When
you configure GCC, you specify these with --build=, --host=, and
--target=.
Specifying the host without specifying the build should be avoided, as
configure may (and once did) assume that the host you specify is also
the build, which may not be true.
If build, host, and target are all the same, this is called a native.
If build and host are the same but target is different, this is called
a cross. If build, host, and target are all different this is called a
canadian (for obscure reasons dealing with Canada's political party
and the background of the person working on the build at that time).
If host and target are the same, but build is different, you are using
a cross-compiler to build a native for a different system. Some people
call this a host-x-host, crossed native, or cross-built native.
and also:
When people configure a project like './configure', man often meets
these three confusing options, which are more related with
cross-compilation
--host: In which system the generated program will run.
--build: In which system the program will be built.
--target: this option is only used to build a cross-compiling
toolchain. When the tool chain generates executable program, in which target
system the program will run.
An example of tslib (a mouse driver library)
'./configure --host=arm-linux --build=i686-pc-linux-gnu': the
dynamically library is built on a x86 linux computer but will be used
for a embedded arm linux system.

CMAKE cross compile libraries are not found

I'm having strange problems with my cmake cross-compiler projects.
My own libraries are found but not the (system) libraries from my toolchain.
Previously I was using KDevelop on debian squeeze machine.
now on my new machine with debian wheezy the configuring fails.
It does not find the system libraries like m or pthread.
On my old machine the following was working perfectly, but I do not remember that I did something special to make this work.
Here is one of my CMakeLists.txt files
cmake_minimum_required(VERSION 2.8)
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 2.6.36.4)
SET(CMAKE_C_COMPILER arm-angstrom-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER arm-angstrom-linux-gnueabi-g++)
include_directories(../include
../../../sample/include)
project(testmain)
add_executable(testmain
some_c-source-file.c)
set(CMAKE_LIBRARY_PATH ../lib/arm-26/lib
../../../sample/lib/arm-26/lib)
find_library(LIBS_TEST NAMES akku)
find_library(LIBS_M NAMES m)
find_library(LIBS_PTHREAD NAMES pthread )
target_link_libraries(akkumain
${LIBS_TEST}
${LIBS_M}
${LIBS_PTHREAD})
set(CMAKE_C_FLAGS "-Wall -Werror")
set(CMAKE_C_FLAGS_DEBUG "-g3 -O2 -rdynamic")
set(CMAKE_C_FLAGS_RELEASE "-g0 -O0")
set(CMAKE_CXX_FLAGS "-Wall -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O2 -rdynamic")
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O0")
This is the message displayed when trying to compile using KDevelop: (to repeat myself: this was working on my old machine)
/home/user/testmain/build> /usr/bin/cmake -DCMAKE_BUILD_TYPE=Debug /home/user/testmain/
-- The C compiler identification is GNU 4.3.3
-- The CXX compiler identification is GNU 4.3.3
-- Check for working C compiler: /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-gcc
-- Check for working C compiler: /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-g++
-- Check for working CXX compiler: /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIBS_M
linked by target "akkumain" in directory /home/user/testmain
LIBS_PTHREAD
linked by target "akkumain" in directory /home/user/testmain
So LIBS_TEST is found. But not libm or libpthread.
I tried this with different projects: All of my libraries are found, but none of the "system" libraries.
I already tried different things like
set(CMAKE_FIND_LIBRARY_PREFIXES lib )
set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
and some more things I do not remember.
The only thing what IS WORKING is when I specify the directory manually:
find_library(ASTLIBS_M NAMES m PATHS /usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/lib)
After specifying this to my CMakeLists.txt the library is found and I can compile my project without any errors.
BUT: This is not what I want, because I have a LOT of projects and many libraries and I don't want to edit all my CMakeLists.txt... :(
Does anybody know what made my old machine find the system-libs without specifying anything special inside my IDE/CMake files?
Edit:
I just noticed for one of my executables that on Linker stage it throws some errors that it cannot find some symbols from glibc - seems there is something more wrong with my debian wheezy system. - I hope I can figure it out...
Edit:
Maybe I should give a short summary: My code compiles well, but all libraries from my toolchain are not found, but if I add the path to the libs of my toolchain manually it compiles but fails on linker stage.
Have you ever tried using a toolchain file? I also cross-compile to ARM and AVR a LOT and it works very well with no hassle (I also use KDevelop and it works beautifully along with CMake). The main point is specifying the path to your toolchain root filesystem through the CMAKE_FIND_ROOT_PATH variable. Try putting all this in a file, which I usually name after the architecture I'm cross-compiling to (in this case I called it arm-unknown-linux-gnueabi.cmake):
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Linux)
# which C and C++ compiler to use
SET(CMAKE_C_COMPILER arm-unknown-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER arm-unknown-linux-gnueabi-g++)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /home/claudio/TS-7400/rootfs)
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
Note the variables CMAKE_FIND_ROOT_PATH_MODE_xxx variables control where CMake will look for binaries, libraries and header files. I usually set PROGRAM to NEVER so it never uses binaries from your cross-architecture root filesystem, since they will not run on your host machine anyway. For libraries and header files BOTH means it will search first your specified ROOT_PATH and then if it doesn't find something it will go through your host machine system dirs.
That way, whenever you want to cross-compile a project all you have to do is to create a build directory (so it doesn't mix your sources with files created during build) and then run cmake from there specifying the toolchain file you want to use (I'm supposing your CMakeLists.txt is together with your toolchain file on the same dir your sources are located - project_sources_dir in my example):
cd project_sources_dir
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../arm-unknown-linux-gnueabi.cmake ..
The whole point of using a toolchain file is that, if you want to compile the exact same project for your host machine, you don't have to change a single line in your CMakeLists.txt. Just run cmake without specifying the toolchain file:
cd project_sources_dir
mkdir build
cd build
cmake ..
and your project is ready for compiling native for your host machine instead. If all that isn't enough, you can look for more details here on CMake Cross Compiling
There are certain default paths where CMake's find_library module searches. If your system libs on your old machine happen to be located in one such place, they will be found without any additional work needing to be done.
However, as your new machine's path to these libs seems to be "/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/lib", you'll need to tell CMake about this.
One such way, is as you have shown (adding the path explicitly). But in this case, the path is probably specific to just that machine - so you'd be better to only set that path when you invoke CMake on that machine. You can add it to CMAKE_PREFIX_PATH for example:
cmake . -DCMAKE_PREFIX_PATH=/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr
(Note: the path in this case get "lib" appended when find_library is called).
Or if you only want to affect the find_library search paths, and not all find_xxx modules, set CMAKE_LIBRARY_PATH
cmake . -DCMAKE_LIBRARY_PATH=/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi/usr/lib

Trouble cross compiling OpenCV for ARM9 Montavista Linux

I'm trying to cross-compile the OpenCV library for using it on an embedded system running Montavista Linux(the system has an ARM926 processor). I've managed to configure and generate the makefiles; the sources are built OK, including the 3rd party libraries. The trouble comes at link time. For some reason libtool picks some libraries from the host system (libjpeg, libtiff, libpng) and tries to link them against the ARM9 object files(which evidently is wrong). The error I get is
/usr/lib/libpng12.so: could not read symbols: File in wrong format.
I couldn't and I still can't figure out what exactly is wrong with my setup(I even tried to build the library directly on the ARM9 system but unfortunately it has a very small amount of RAM and gcc chokes). I also modified the LD_LIBRARY_PATH envvar to contain the target's system libraries and exported it before running configure and make.
Below is what I pass to configure:
LDFLAGS="-L/opt/Montavista/pro/devkit/arm/v5t_le/target/usr/lib" CFLAGS="-I/opt
/Montavista/pro/devkit/arm/v5t_le/target/usr/include -fsigned-char -march=armv5te
-mtune=arm926ej-s -ffast-math -fomit-frame-pointer -funroll-loops" CC=/opt/Montavista
/pro/devkit/arm/v5t_le/bin/arm_v5t_le-gcc CXXFLAGS="-fsigned-char -march=armv5te
-mtune=arm926ej-s -ffast-math -fomit-frame-pointer -funroll-loops" CXX=/opt/Montavista
/pro/devkit/arm/v5t_le/bin/arm_v5t_le-g++ ./configure --host=armv5tl-montavista-linux-
gnueabi --without-gtk --without-v4l --without-carbon --without-quicktime --without-
1394libs --without-ffmpeg --without-imageio --without-python --without-swig --enable-
static --enable-shared --disable-apps --prefix=/home/dev/Development/lib
I found this question on SO but unfortunately it does not provide a solution for me.
I'm using gcc version 4.2.0 (MontaVista 4.2.0-16.0.32.0801914 2008-08-30) on Montavista Linux for ARM(Leopard board powered by a TI DM365), OpenCV 2.0.0. My host system is Ubuntu 10.4.
Any pointers on how to tackle this issue would be of very much help.
Thanks
[UPDATE][SOLVED]: The autotools based method of generating the makefiles for OpenCV 2.0.0 seems to be broken when trying cross-compiling(or for some odd reason it did not work for me). I used the CMake GUI and specified a proper toolchain.cmake file and everything went smooth. See the answer below.
Procedure for cross-compiling OpenCV 2.0 for ARM using CMake GUI
Requirements
OpenCV 2.0 source tarball
CodeSourcery ARM cross-compiler v2009q1 or v2010.09(both tested)
Ubuntu 10.10/11.04 host machine
CMake >= v2.6 with CMake GUI
Steps
Unpack somewhere on your host machine the OpenCV tarball; cd to that location and create a build directory
Open the CMake GUI. Select:
Where is the source code:==path to the folder you unpacked the OpenCV tarball
Where to build the binaries:==path to the build folder you created in the first step
Add a new entry named COMPILER_ROOT as a path entry and set its value to the path of your cross compiler e.g. /opt/CodeSourcery/Sourcery_G++_Lite/bin
Set CMAKE_TOOLCHAIN_FILE to the path of your toolchain file on your host machine; example toolchain.cmake:
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# specify the cross compiler
set(COMPILER_ROOT /opt/CodeSourcery/Sourcery_G++_Lite/bin)
set(CMAKE_C_COMPILER ${COMPILER_ROOT}/arm-none-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_ROOT}/arm-none-linux-gnueabi-g++)
# specify how to set the CMake compilation flags
# CPP
SET(CMAKE_CXX_FLAGS $ENV{CXX_FLAGS} CACHE FORCE "")
SET(CMAKE_CXX_FLAGS_DEBUG $ENV{CXX_FLAGS_DEBUG} CACHE FORCE "")
SET(CMAKE_CXX_FLAGS_RELEASE $ENV{CXX_FLAGS_RELEASE} CACHE FORCE "")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO $ENV{CXX_FLAGS_RELWITHDEBINFO} CACHE FORCE "")
SET(CMAKE_CXX_LINK_FLAGS $ENV{CMAKE_EXE_LINKER_FLAGS} CACHE FORCE "")
SET(CMAKE_C_LINK_FLAGS $ENV{CMAKE_EXE_LINKER_FLAGS} CACHE FORCE "")
SET(CMAKE_CXX_LINK_FLAGS_RELEASE $ENV{CMAKE_EXE_LINKER_FLAGS} CACHE FORCE "")
SET(CMAKE_CXX_LINK_FLAGS_DEBUG $ENV{CMAKE_EXE_LINKER_FLAGS} CACHE FORCE "")
# C
#SET(CMAKE_C_FLAGS $ENV{C_FLAGS} CACHE FORCE "")
SET(CMAKE_C_FLAGS_DEBUG $ENV{C_FLAGS_DEBUG} CACHE FORCE "")
SET(CMAKE_C_FLAGS_RELEASE $ENV{C_FLAGS_RELEASE} CACHE FORCE "")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO $ENV{C_FLAGS_RELWITHDEBINFO} CACHE FORCE "")
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH ${COMPILER_ROOT})
# 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)
Tweak other settings to your needs e.g.EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH CMAKE_BUILD_TYPE CMAKE_CFLAGS_DEBUG CMAKE_CFLAGS_RELEASE, third party libraries you want to build with etc.
Press Configure then Generate; check for eventual errors(everything should run smoothly but you never know)
If everything went OK in the generation phase then cd to the build folder, type make then sit back and relax until the build process is done
It seems you are using an old version of OpenCv since it still uses the .configure mechanism. This is good in a sense, because CMake is not known to be cross-compilation friendly.
LDFLAGS="-L/opt/Montavista/pro/devkit/arm/v5t_le/target/usr/lib"
This is were the linker will look for libraries. It should be enough. Are you sure the libraries needed by OpenCV are in this PATH ?
A first Hack would be to rename the libraries in /usr/lib, so that the linker don't find them, and see if it find the target libraries. This is ugly, maybe more than ugly. Don't do it. Yet.
A second solution is to do native compilation. But it an emulated ARM box, not on real, slow and memory poor hardware. I have no experience either with this kind of cross-compile method, but here is a link to get you started.
EDIT
Wait !!, Which version of OpenCV are you using ? I thought OpenCV was not using .configure et al. ? There is probably a more elegant solution using .configure flags. Or maybe non optionnal libraries are somehow hardcoded.
Interestingly I'm currently trying to get version 2.1.0 to build for ARM. It relies on cmake which is a real pain to try to get ready for cross-compiling. There's no way to specify what toolchain to use, I have to spot the variable names for all binutils, hoping not to forget any. There are still a bunch of magically defined variables that prevent it from building, I'm giving up right now. I'm still seeing some -march=i686 magically appended and some libs referenced from my build system. What a mess !
Maybe when I have time I'll try to downgrade to an older version making use of more standard tools, but cmake clearly complicates the situation here.

Resources