|
|
# How to use gcc-multilib to cross compile software for Linux
|
|
|
|
|
|
Goal: compile a 32bits exe on running amd64 linux system.
|
|
|
|
|
|
## Install the gcc-multilib package
|
|
|
|
|
|
$ sudo apt-get install gcc-multilib
|
|
|
|
|
|
## Write a CMake toolchain file
|
|
|
|
|
|
For CMake to be able to crosscompile software, it requires you to write
|
|
|
a toolchain file, which tells CMake some information about the
|
|
|
toolchain. With the examples used above it will look like:
|
|
|
|
|
|
# the name of the target operating system
|
|
|
SET(CMAKE_SYSTEM_NAME Linux)
|
|
|
|
|
|
# which compilers to use for C and C++
|
|
|
SET(CMAKE_C_COMPILER gcc)
|
|
|
SET(CMAKE_C_FLAGS -m32)
|
|
|
SET(CMAKE_CXX_COMPILER g++)
|
|
|
SET(CMAKE_CXX_FLAGS -m32)
|
|
|
|
|
|
# here is the target environment located
|
|
|
SET(CMAKE_FIND_ROOT_PATH /usr/i486-linux-gnu )
|
|
|
|
|
|
# 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)
|
|
|
|
|
|
Save this file as Toolchain-gcc-m32.cmake to some location where you
|
|
|
will put all your toolchain files, e.g. $HOME. As you can see
|
|
|
CMAKE_FIND_ROOT_PATH is set to /usr/i486-linux-gnu, which contains
|
|
|
the libraries **and** headers installed with the toolchain.
|
|
|
|
|
|
## Build the software for Linux
|
|
|
|
|
|
Let's say you have the classical hello world software with a CMake based
|
|
|
buildsystem and want to build this for Linux using gcc -m32. main.c:
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
int main()
|
|
|
{
|
|
|
printf("Hello world\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
CMakeLists.txt:
|
|
|
|
|
|
ADD_EXECUTABLE(hello main.c)
|
|
|
|
|
|
Then run CMake on it to generate the buildfiles, the important point is
|
|
|
that you tell it to use the toolchain file you just wrote:
|
|
|
|
|
|
~/src/helloworld/ $ mkdir build
|
|
|
~/src/helloworld/ $ cd build
|
|
|
~/src/helloworld/build/ $ cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-gcc-m32.cmake -DCMAKE_INSTALL_PREFIX=/home/mathieu/gcc-m32-install ..
|
|
|
-- Configuring done
|
|
|
-- Generating done
|
|
|
-- Build files have been written to: /home/mathieu/src/helloworld/build
|
|
|
~/src/helloworld/build/ $ make
|
|
|
Scanning dependencies of target hello
|
|
|
[100%] Building C object CMakeFiles/hello.dir/main.o
|
|
|
Linking C executable hello
|
|
|
[100%] Built target hello
|
|
|
|
|
|
You can then verify:
|
|
|
|
|
|
$ file hello
|
|
|
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
|
|
|
|
|
|
In case you have a more complex application that is using let say zlib,
|
|
|
you would need first to install it:
|
|
|
|
|
|
$ apt-cross --arch i386 -i zlib1g-dev
|
|
|
|
|
|
And after compilation, you can check that you are indeed using this zlib
|
|
|
and not your system one:
|
|
|
|
|
|
```
|
|
|
$ ldd ./myapp
|
|
|
...
|
|
|
libz.so.1 => /usr/i486-linux-gnu/lib/libz.so.1 (0xf7b6b000)
|
|
|
...
|
|
|
```
|
|
|
|
|
|
----
|
|
|
This page was initially populated by conversion from its [original location](https://public.kitware.com/Wiki/CmakeGccm32) in another wiki. |