-- Originaly from my old wiki at BiffEngineering.com
HowToSetupCrossCompileEnvironment
From Biff Engineering
This How To will cover setting up a cross compile environment using
crosstool-NG, Scratchbox2 and QEmu and Debootstrap (We'll be making an
Embedded ARM Debian install). Also this tutorial is done under the
assumption you are running Ubuntu as your Host System. Not much should
change other than how you get the packages.
*Note:* I am currently retracing my steps through this How To since I
needed to build a new development environment for a new project. There
may be some changes occuring so while this message is here be aware that
not everything might be working properly.
*Note:* I've found, atleast for the embedded arm system I use, that
debian supports libc 2.7 (lenny) or eglibc 2.11 (squeeze). Neither of
those two are available with the latest version of crosstool-ng. Once I
get my system up and running I'll make a change to show how to revert
back to use 2.7.
Contents
* 1 Cross Compilers <#Cross_Compilers>
o 1.1 Required Packages <#Required_Packages>
o 1.2 Download <#Download>
o 1.3 Setup/Install Crosstool-NG <#Setup.2FInstall_Crosstool-NG>
o 1.4 Build Cross Compiler <#Build_Cross_Compiler>
* 2 Cross Compiler Jail <#Cross_Compiler_Jail>
o 2.1 Directory Structure <#Directory_Structure>
o 2.2 Debootstrap <#Debootstrap>
o 2.3 Scratchbox <#Scratchbox>
+ 2.3.1 Required Packages <#Required_Packages_2>
+ 2.3.2 Build Scratchbox2 <#Build_Scratchbox2>
o 2.4 QEmu <#QEmu>
+ 2.4.1 Download/Install <#Download.2FInstall>
o 2.5 Setup Environments <#Setup_Environments>
o 2.6 Welcome to Jail <#Welcome_to_Jail>
* 3 Cross Compiled Libraries <#Cross_Compiled_Libraries>
o 3.1 Required Packages <#Required_Packages_3>
o 3.2 Configuration <#Configuration>
o 3.3 Install a Package <#Install_a_Package>
o 3.4 Test a Package <#Test_a_Package>
Cross Compilers
The basis of all cross compiler environments is the cross compiler
itself. Back in the day people use to have to build cross compilers and
all the prerequisites by hand, compilers to build compilers and
everything else. Crosstool-NG is a project that has simplified the whole
process.
Required Packages
The following is a list of required packages needed to build your cross
compilers:
* mercurial
* bison
* flex
* texinfo
* automake
* libtool
* build-essential
* libncurses-dev
$ sudo apt-get install mercurial bison flex texinfo libtool build-essential libncurses-dev
Download
You can download via source control or the latest release from here
<
http://ymorin.is-a-geek.org/download/crosstool-ng/>.
$ mkdir -p ~/x-tools/src
$ cd x-tools/src
$ hg clone
http://ymorin.is-a-geek.org/hg/crosstool-ng
Setup/Install Crosstool-NG
The next step is to build and install the crosstool-ng package.
$ mkdir ~/x-tools/crosstool-ng
$ cd ~/x-tools/src/crosstool-ng-1.4.2
$ ./configure --prefix=$HOME/x-tools/crosstool-ng
$ make
$ make install
Next we need to edit your path so that we can run the executables we
just installed, add the following line to the end of the file.
*~/.bashrc*
export PATH=$HOME/x-tools/crosstool-ng/bin:$PATH
Close your console window and open a new one to reload your PATH variable.
Build Cross Compiler
The last step is to build your cross compiler. We need to create the
directory where our compilers will be installed
$ mkdir -p ~/x-tools/arm-unknown-gnueabi
Now we will enter the configuration stage of Crosstool-NG. This setup is
similar to the *menuconfig* setup used when building the Linux Kernel.
$ cd ~/x-tools/arm-unknown-gnueabi
$ ct-ng menuconfig
At this point its up to you to select what options you want. Most
everything in the menu structure has a help section which explains what
the option does and why you might want it.
Once you have completed your configuration you just have one more
command and you'll be on your way to building your cross compiler:
$ ct-ng build
Cross Compiler Jail
Now that we have our cross compiler built we need to create and
environment in which we can do our development and utilize these
compilers without all the hassle of having to call them out directly.
Directory Structure
The first step in creating the cross compiler jail is the directory
structure. Since we will be using scratchbox2 we'll start with the
directory sbox2 and go from there.
* *sbox2*
o *bin* (Contains all binaries need for environment)
+ *qemu* (QEmu binaries)
o *rootfs* (Contains root file systems for different architectures
+ *armel* (Embedded ARM RootFS)
o *src* (Source code for scratchbox)
So lets create the directories.
$ mkdir -p ~/sbox2 ~/sbox2/bin/qemu \
~/sbox2/rootfs/armel ~/sbox2/src
Debootstrap
A prerequisite for Scratchbox2 is a working root file system. Debian
provides a nice utility for installing all the base deb files needed for
a root file system.
$ sudo apt-get install debootstrap
The next step is to run it. The man pages provide a list of all the
parameters but the following will most likely be what you'll need.
$ sudo debootstrap --verbose --arch armel --foreign lenny \
$HOME/sbox2/rootfs/armel
http://ftp.at.debian.org/debian
Scratchbox
Scratchbox2 is a fully functioning "jail" which allows you to build
applications and run them as if you were running on your target
hardware. Rather than having to invoke an emulator every time you wanted
to run something, entering into "Scratchbox" is the only step needed.
Required Packages
The following is a list of packages needed to install scratchbox onto
your system.
* autoconf
* autogen
* automake
* autotools-dev
* binutils
* fakeroot
* gcc-3.4 (Qemu)
* git-core
* g++
* libsdl1.2-dev (Quemu)
* make
* sbrsh
* subversion (Qemu)
All the packages with the label (Qemu) are needed for building QEmu. We
are just speeding up the process by doing them all now.
$ sudo apt-get install autoconf autogen \
automake autotools-dev binutils fakeroot \
gcc-3.4 git-core g++ libsdl1.2-dev make \
sbrsh subversion
Since we will be building QEmu by hand we will want to remove any
existing version that may be installed. Sorry folks.
$ sudo apt-get --purge remove qemu
Build Scratchbox2
The next step is to download the latest version of Scratchbox and build
it. For this we will be using GIT to pull the latest version from source
control.
*Note:* The Scratchbox2 project has been given to Nokia for future
development so the location of the Git Repo has changed. If this is your
first time through this How To just follow the URL bellow.
$ cd ~/sbox2/src
$ git clone git://gitorious.org/scratchbox2/scratchbox2.git
$ cd sbox2
$ git checkout 2.1 -b devel_env
$ ./autogen.sh
$ ./configure --prefix=$HOME/sbox2/bin/scratchbox
$ make install
Now we have a few configuration options we need to add to finalize the
build.
We need to define the architecture of the host system. Edit the file
*sbox2/bin/scratchbox/bin/sb2-build-libtool* There is a line that runs
the configure scripts, add the followin as a parameter:
--host=i386
The next configuration option tells Scratchbox not to add it's own
binaries and libraries into the system. This causes some problems so we
will remove it. Edit the file *sbox2/bin/scratchbox/bin/sb2-init* and
remove the line from the SBOX_EXTRA_CROSS_COMPILER_ARGS variable.
-Wno-poison-system-directories
*Note:* Running through these steps right now it looks as if this option
has been removed from Scratchbox already. If you have it remove it, if
not no worries.
QEmu
The next part of your environment is the emulator. QEmu is used by
Scratchbox so we will install that.
Download/Install
We will download the latest version of QEmu from source control. QEmu
has switched to Git for the source code management so if this is not
your first time through make sure you follow the next steps carefully.
$ cd ~/sbox2/src
$ git clone git://git.savannah.nongnu.org/qemu.git
$ cd qemu
$ git checkout v0.13.0-rc1 -b devel_env
Now that we have downloaded the source code, we need to make a few
modifications. *Note:* These modifications are specific to the embedded
ARM; if you are using a different target architecture you can skip this
step.
Edit the file *qemu/trunk/linux-user/syscall_defs.h* and change the
following line:
abi_ulong st_blocks; /* Number 512-byte blocks allocated. */
abi_ulong __pad4; /* future possible st_blocks high bits */
to this:
#ifndef TARGET_WORDS_BIGENDIAN
abi_ulong st_blocks; /* Number 512-byte blocks allocated. */
abi_ulong __pad4; /* future possible st_blocks high bits */
#else
abi_ulong __pad4; /* future possible st_blocks high bits */
abi_ulong st_blocks; /* Number 512-byte blocks allocated. */
#endif
Now that we have made our modifications for our specific development
environment we can check in these changes locally. When we upgrade QEmu
this will help us make these modifications quickly.
$ git add .
$ git commit -a -m "Development Environment Modifications"
All we have left to do is build and install.
$ ./configure --prefix=$HOME/sbox2/bin/qemu
$ make
$ make install
Setup Environments
Now that we have built our cross compilers (using crosstool-NG), our
jail (Scratchbox2) and our emulator (QEmu), we just need to setup our
Host System environment variables and we are good.
Edit your bashrc file and add the following line at the end:
export PATH=$PATH:$HOME/x-tools/arm-unknown-gnu-linux/bin:$HOME/sbox2/bin/scratchbox/bin:$HOME/sbox2/bin/qemu/bin
Close your terminal and open a new one to load this new export rule.
Now we are ready to start up our Jail. First we need to initialize it.
The initialization of Scratchbox requires you to be located in the
directory of your base root filesystem.
$ cd ~/sbox2/rootfs/armel
$ sb2-init armel $HOME/sbox2/bin/arm-unknown-gnu-linux/bin/arm-unknown-linux-gnueabi-gcc
Now we are ready to test out our jail.
Welcome to Jail
To enter Scratchbox type *sb2*. You should see your prompt change to the
target we have just created.
Lets create a test binary and see how it works.
$ echo 'int main() { return 0; }' > test.c
$ gcc test.c
$ file a.out
a.out: ELF 32-bit LSB executable, ARM, version 1
(SYSV), dynamically linked (uses shared libs),
for GNU/Linux 2.6.26, not stripped
*Note:* On some systems there is a problem when running your binary. If
you receive an error staying that mmap is causing a problem there is a
simple fix. Edit */etc/sysctl.conf* and add the following line to the end:
vm.mmap_min_addr = 4096
Reboot and all should work.
Cross Compiled Libraries
This section will cover how to get all those development packages cross
compiled to build all your new applications.
Required Packages
Since we are building a Debian-Based Distribution for our target
hardware we can use a tool called apt-cross to download and install all
the cross compiled development libraries we need. So lets start by
installing the tool
$ sudo apt-get install apt-cross
Configuration
The next step is to setup a directory where all your cross compiled
development libraries will be installed. By doing this we can keep our
host system libraries and our cross compile libraries separate.
$ sudo mkdir -p /usr/cross-pkg
Next edit the file */etc/dpkg-cross/cross-compile* making the following
entry:
crossbase = /usr/cross-pkg
Now whenever you install a package via apt-cross it will be installed in
our special directory dependent on their architecture:
/usr/cross-pkg/arm-linux-gnueabi/
Install a Package
Now that all the configuration is complete we can update our packages
list and install a development library.
First update the package list
$ sudo apt-cross -a armel -S lenny -m \
http://ftp.at.debian.org/debian -u
The arguments for this command define the architecture (-a), the version
of debian (-S) and the mirror (-m) and tells apt-cross to update (-u).
Next we will install a development package. For this example, I'll be
installing the ADAPTIVE Communication Environment (ACE) library as it is
a nice API for making easily portable cross-platform applications.
$ sudo apt-cross -a armel -S lenny -m \
http://ftp.at.debian.org/debian -i libace-dev
As you will see, a number of additional libraries will be installed onto
your system including libc and the gcc-base packages. As with the normal
apt tools, apt-cross will help maintain all the required packages for
whatever you are installing.
Test a Package
Development library package is installed, lets test it.
Here is a little Hello World program using the ACE library we installed:
*test.cpp*
#include "ace/Log_Msg.h"
int main()
{
ACE_DEBUG((LM_INFO, ACE_TEXT("Hello World\n")));
return 0;
}
Lets compile it. Make sure you are logged into Scratchbox at this time:
[SB2 simple armel] $ g++ -c -I/usr/cross-pkg/arm-linux-gnueabi/include -o test.o test.cpp
[SB2 simple armel] $ g++ -lACE -L/usr/cross-pkg/arm-linux-gnueabi/lib test.o -o test
Since our cross compiled shared libraries are located in a directory
external from Scratchbox we need to tell the system where they are
located when running the test program. Later we will add this in to
Scratchbox's configuration so that we don't need to add the extra
environment variable when we run code.
[SB2 simple armel] $ LD_LIBRARY_PATH=/usr/cross-pkg/arm-linux-gnueabi/lib:$LD_LIBRARY_PATH ./test
Hello World
[SB2 simple armel] $
Our new development library is not linked to our binary and we can run
the code. As you can see when you check the file its an ARM binary.
[SB2 simple armel] $ file ./test
/test: ELF 32-bit LSB executable, ARM, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.26, not stripped
You are now ready to write code! Just remember what development
libraries you have installed. You'll need to have the runtime versions
installed on your target when you want to run the code natively.
Retrieved from
"
http://biffengineering.com/wiki/index.php?title=HowToSetupCrossCompileEnvironment"