January 20, 2014

The novel way to build cross compiler tools

http://www.cis.upenn.edu/~milom/cross-compile.html

The reason it is novel is because it takes the target header file and library directly without recompiling them. Therefore this approach is much simpler than the regular from scratch method.

How to Cross-Compile GCC for SPARC Solaris

Computer and Information Sciences Department
University of Pennsylvania
January 2010
To make it easier for my CIS534 students to compile code for our one and only SPARC machine (a 128-thread Niagara T2 box, generously donated by Sun Microsystems), I created a cross-compiler for GCC on x86/Linux to SPARC/Solaris. This page documents how I did it. I'm putting it on-line in case anyone else finds it helpful.

Overview

There are three steps to building the cross compiler:
  1. Specifying the configuration and paths
  2. Finding and installing the proper system header files and libraries
  3. Cross-compiling GNU binutils and GCC

Definitions and Configuration

  • The "host" is the machine on which the compiler executes (x86/Linux in my case). By default, the configure scripts will automatically figure this out.
  • The "target" is the machine on which the output binaries will execute (for SPARC/Solaris in my case, it should be sparc-sun-solaris2.10). This needs to be set explicitly. You can find out the proper target string by executing gcc -dumpmachine.
  • The "prefix" is the instalation prefix where the cross-compiler will be installed.
  • The "sysroot" is the location the cross compiler will look for header files and libraries. The sysroot directory acts as if it is the root of the system,. So, for example, header files go in $SYSROOT/usr/include/ and library files go in $SYSROOT/usr/lib/, etc.
I set these options using environment variables:
setenv TARGET sparc-sun-solaris2.10
setenv PREFIX /mnt/castor/seas_home/c/cis534/public/cross/
setenv SYSROOT $PREFIX/sysroot/
set path = ( $path $PREFIX/bin )

mkdir $PREFIX
mkdir $SYSROOT

System Headers and Libraries

To be able to build and link applications, the cross-compiler needs access to the system header files. As building the compiler also uses some of these files, installing these files needs to be done first. If you have access to the target machine, you can just copy the files into $SYSROOT. Otherwise, you'll need to download the files from the proper distribution. To copy the files, I piped tar through SSH to the SPARC machine (arachnid, in our case), as I could not find an option to get SCP to preserve symbolic links:
cd $SYSROOT
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/local/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/local/lib" | tar -xvf -
Copying the above directories worked for what I needed to do, but you might also considering copying additional headers and libraries:
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/openwin/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/dt/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/X11/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/openwin/lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/dt/lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/X11/lib" | tar -xvf -

Cross-compiling GNU binutils and GCC

Building binutils and GCC is reasonable straightforward (if everything works), by downloading, unpacking, configuring, running make, and then make install for both:
mkdir /scratch/users/build
cd /scratch/users/build

wget http://ftp.gnu.org/gnu/binutils/binutils-2.20.tar.gz
tar -xvzf binutils-2.20.tar.gz
mkdir build-binutils
cd build-binutils/
../binutils-2.20/configure -target=$TARGET --prefix=$PREFIX -with-sysroot=$SYSROOT -v
make all; make install

wget http://ftp.gnu.org/gnu/gcc/gcc-4.4.2/gcc-4.4.2.tar.gz
tar -xvzf gcc-4.4.2.tar.gz
mkdir build-gcc
cd build-gcc
../gcc-4.4.2/configure --target=$TARGET --with-gnu-as --with-gnu-ld  --prefix=$PREFIX -with-sysroot=$SYSROOT --disable-libgcj --enable-languages=c,c++ -v
make all; make install
You can delete the build directories once the make install has been completed. Also, the above config for GCC will only build C and C++, but you can remove that option if you need to build GCC with support for other languages.

Testing

This will create two sets of binaries. The directory $PREFIX/bin/ will include executables of the form: sparc-sun-solaris2.10-gcc. You should be able to use this to compile a program:
$PREFIX/bin/sparc-sun-solaris2.10-gcc hello.c -o hello
Running file hello should return something like:
ELF 32-bit MSB executable, SPARC32PLUS, V8+ Required, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Then copy hello over to the SPARC box, and see if it runs. Although it shouldn't be necessary, if it gives dynamic linking errors, you could try setting the LD_LOAD_LIBRARY environment variable.
Update (April 2010): If you're getting dynamic linking errors, particularly with C++, you may need to use the "-R" option when compiling. This option specifies a path the dynamic loader on the target to look for the libraries:
$PREFIX/bin/sparc-sun-solaris2.10-gcc -R $PREFIX/$TARGET/lib/sparcv9/ hello.c -o hello
This assumes the -R path is mounted on the target machine. If not, you may need to copy over those files and adjust the -R path accordingly.

No comments:

Post a Comment