-- 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 . $ 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"