---
title: Cross Compile
taxonomy:
   category: docs
---

If you run 64bit Linux but want to compile an application and send it to
some computer running 32bit, then you need to cross compile. You might
do this because all of your 32bit machines are slow and you would rather
compile quickly on your development machine, or you might need to do it
because your 32bit machines do not have a compiler installed and you do
not want one installed, or you may be doing it to accomodate users who
do not know how to compile their own version of your app. Whatever the
reason, cross compiling is neat trick to know.


> This article is about compiling for one architecture whilst on a system of a different architecture.
> It does not [yet] cover how (at least, not exactly) to compile for a different OS entirely. The
> principles are the same but I have not had the occasion to ever compile for any OS other than the
> exact one I am compiling on, so I cannot write a good article stepping you through how it's done.
> However ,reading this might give you a good head-start in figuring it out on your own.


Let's say that we have my simple dice rolling example programme from my
[Programming
Book](http://straightedgelinux.ml/blog/python/html/index.html), but
written in C++ so that it will not run without being compiled:

   #include <iostream>
   #include <cstdlib>

   using namespace std;

   void lose (int c);
   void win (int c);
   void draw ();

   int main() {
    int i;
     do {
        cout << "Pick a number between 1 and 20: n";
        cin >> i;
        int c = rand ( ) % 21;
        if (i > 20) lose (c);
        else if (i < c ) lose (c);
        else if (i > c ) win (c);
        else draw ();
        }
    while (1==1);
    }

   void lose (int c )
    {
    cout << "You lose! Computer rolled " << c << "n";
    }

   void win (int c )
    {
    cout << "You win!! Computer rolled " << c << "n";
    }

   void draw ( )
    {
    cout << "What are the chances. You tied. Try again, I dare you! n";

    }

(Admittedly, that wersion could use a few enhancements, but in the
interest of keeping it simple, we will leave it as is.)

To compile it on your system, you could use **g++** directly:

   $ g++ dice.cpp -o dice

The compile happens, and you can run it with

   $ ./dice

We can see what kind of binary we have produced:

   $ file ./dice
   dice: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
   linked (uses shared libs), for GNU/Linux 3.10.17, not stripped

And just as importntly, what libraries it has had to link to:

   $ ldd dice

   linux-vdso.so.1 => (0x00007ffe0d1dc000)
   libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
   (0x00007fce8410e000)
   libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
   (0x00007fce83d4f000)
   libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
   (0x00007fce83a52000)
   /lib64/ld-linux-x86-64.so.2 (0x00007fce84449000)
   libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
   (0x00007fce8383c000)

Two obvious things we get from this information: the binary that you
just ran is 64bit, and it is linked to 64bit libraries.

That is what we would expect, so that's good.

That means that in order to cross compile, you need to tell **g++** to...

1.  Produce a 32bit binary, which
2.  links to 32bit libraries instead of your default 64bit libs

## Setting Up Your Dev Environment

To compile to 32bit, then, you need to have 32bit libraries and headers
installed on your system. If you run a "pure" 64bit system, then you
will have no 32bit libs or headers and will need to go get some. On
Slackware, you can do this by installing a multilib hack provided by
AlienBOB. On other systems, there may be meta packages available, or you
can just hand-pick the ones you need.

Ultimately, no matter what system you are using, you will probably end
up hand-picking 32bit libs depending on your project. Whatever your code
links to, you must have as 32bit libs on your computer.

Once that's taken care of, the compile itself is fairly simple in
theory:

   $ g++ -m32 dice.cpp -o dice32 -L /usr/lib -march=i586

Notice that you set a **-m32** flag to compile in 32bit mode. I use
**-march=i586** to further define what kind of optimisations should be made.
The other flag that you set is the path to your libraries. This is
usually **/usr/lib** although depending on how your system is set up, it
could be **/usr/lib32** or, heck, even **/opt/usr/lib** if you felt like it, so
do a proper **ls -l /** to see how things are laid out.

After the compile finishes, see proof of your build:

   $ file ./dice32
   dice: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
   dynamically linked (uses shared libs), for GNU/Linux 3.10.17, not
   stripped


And of course **ldd ./dice32** points to your 32bit libs.

And since you were able to compile it, it should also, then, run on your
system.


## Caveats

If your application is more complex than the little dice app we just
made and actually produces more than just a single binary, then you do
need to tell **gcc** what to call those files and where to save them.

Also, if the application you are compiling uses a Make file such that
you are not using **gcc** directly, then you will need to add stuff to the
Makefile, or else add stuff to the config options.

All that is the same as my example, only with more legwork.

That's all there is to it. Give it a go!

[EOF]

Made on Free Software.