CmakeGccm32: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
No edit summary
(Add explicit preformat markup)
Line 5: Line 5:
== Install the gcc-multilib package ==
== Install the gcc-multilib package ==


<pre>
  $ sudo apt-get install gcc-multilib
  $ sudo apt-get install gcc-multilib
</pre>


== Write a CMake toolchain file ==
== Write a CMake toolchain file ==
Line 75: Line 77:
You can then verify:
You can then verify:


<pre>
  $ file hello
  $ 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
  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:
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
  $ 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:
And after compilation, you can check that you are indeed using this zlib and not your system one:

Revision as of 18:33, 24 April 2018

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



CMake: [Welcome | Site Map]