CmakeGccm32: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
(Add explicit preformat markup)
(Replace content with link to new CMake community wiki)
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
= How to use gcc-multilib to cross compile software for Linux =
{{CMake/Template/Moved}}


Goal: compile a 32bits exe on running amd64 linux system.
This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/cross_compiling/Gccm32 here].
 
== Install the gcc-multilib package ==
 
<pre>
$ sudo apt-get install gcc-multilib
</pre>
 
== 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:
<pre>
# 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)
</pre>
 
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:
<pre>
#include <stdio.h>
 
int main()
{
  printf("Hello world\n");
  return 0;
}
</pre>
 
CMakeLists.txt:
<pre>
ADD_EXECUTABLE(hello main.c)
</pre>
 
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:
<pre>
~/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
</pre>
 
You can then verify:
 
<pre>
$ 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
</pre>
 
In case you have a more complex application that is using let say zlib, you would need first to install it:
 
<pre>
$ apt-cross --arch i386 -i zlib1g-dev
</pre>
 
And after compilation, you can check that you are indeed using this zlib and not your system one:
 
<pre>
$ ldd ./myapp
...
libz.so.1 => /usr/i486-linux-gnu/lib/libz.so.1 (0xf7b6b000)
...
</pre>
 
{{CMake/Template/Footer}}

Latest revision as of 15:41, 30 April 2018


The CMake community Wiki has moved to the Kitware GitLab Instance.

This page has moved here.