Building a Linux Hosted Cross Compiler for Solaris 2.6
By Erik Welsh
08.09.2000
Overview:
- Download source files
- Configure environment variables
- Compile and install executables
- Binutils
- GCC
- GDB
- Test cross compiler
- Remove unneeded files (optional)
Versions of software and download site:
GCC: 2.95.2 ftp://ftp.gnu.org/pub/gnu/gcc/
Binutils: 2.9.1 ftp://ftp.gnu.org/pub/gnu/binutils/
GDB: 5.0 ftp://ftp.gnu.org/pub/gnu/gdb/
Pre-Requisites:
1) Download GCC, Binutils and GDB
2) Find needed Solaris header files and librares
(See "Needed Header Files and Libraries" (near the end of this document)
and the file Required-headers for more information)
3) Make sure there is at least 400 MB of free disk space
4) Read the Notes section for assumptions that have been made
Procedure:
Building a cross compiler can be a tricky procedure and a little hard
to understand for the first time builder. First, the host is the machine
on which the compiler is being built and the target is the machine for
which the compiler will produce executables.
1) Unpack all the downloaded files in a directory which will now be know
as $src.
$ export src=/home/foo/
Therefore your source directory should look like this:
[ewelsh@smelt source]$ ls
binutils-2.9.1 gcc-2.95.2 gdb-5.0
2) Make build directories in $src:
mkdir build-binutils build-gcc build-gdb build-install
3) Now configure enviroment variables:
host=i686-pc-linux-gnu (machine on which you are building)
target=sparc-sun-solaris2.6 (machine for which you wish to build)
prefix=$src/build-install (directory in which you wish the
cross compiler to be installed)
headers=/bar (directory into which you copied the
system header files)
libs=/foo-bar (directory into which you copied the
system library files)
Note: There is a certian order in which the components of the cross compiler
need to be built. Binutils must be built first because GCC has libraries
that must use tools configured for cross compilation. Also, the
cross-compiler is needed to build the debugger, gdb, so it must be built
second. Finally, the debugger must be built. So here are the steps to go
through in order:
4) In the directory $src:
$ cd build-binutils
$ ../binutils-2.9.1/configure --host=$host --target=$target \
--with-headers=$headers --with-libs=$libs --prefix=$prefix -v
$ make all | tee &> make.log
(this is so you have a log of the build process. All errors will be
printed on the command line)
$ make install | tee &> install.log
(this is so you have a log of the install process)
5) In the directory $src:
$ cd build-gcc
$ ../gcc-2.95.2/confgure --host=$host --target=$target \
--with-headers=$headers --with-libs=$libs --with-gnu-as --with-gnu-ld \
--prefix=$prefix -v
$ export PATH=$PATH:$prefix/bin
$ make all | tee &> make.log
$ make install | tee &> install.log
6) In the directory $src:
$ cd build-gdb
$ ../gdb-5.0/configure --host=$host --target=$target \
--with-headers=$headers --with-libs=$libs --prefix=$prefix -v
$ make all | tee &> make.log
$ make install | tee &> install.log
7) Testing:
To test I have written a couple of hello world programs that test both
the gcc, and the dynamic linking capabilities of the cross compiler.
(See "For Hello World" below)
8) Removing unneeded files:
After you are finished testing you can remove the directories:
$src/build-binutils
$src/build-gcc
$src/build-gdb
$src/binutils-2.9.1
$src/gcc-2.95.2
$src/gdb-5.0
All you need is the $src/build-install directory with all the compiler
executables.
For Hello World:
1) Makefile:
# You must specify the absolute pathname of the new cross compiler since the
# the path is such that it will find the native version of gcc before the
# cross compiled version.
#
# Note on makefiles: there must be a tab before each command that will be
# executed, such as $(CC) $(POS_OPT) -o print.o -c print.c, not spaces.
#
#CC=gcc
SRC=/home/foo
CC=$(SRC)/build-install/bin/sparc-sun-solaris2.6-gcc
CFLAGS= -g -Wall
POS_OPT = -fpic
SHARE_OPT = -shared
OBJS = main.o
OBJS2 = main2.o
all: hello_world hello_world2
hello_world:
$(CC) $(POS_OPT) -o print.o -c print.c
$(CC) $(SHARE_OPT) -o libprint.so print.o
$(CC) -o main.o -c main.c
$(CC) -o $@ main.o -L. -lprint
export LD_LIBRARY_PATH=.
hello_world2:
$(CC) -o main2.o -c main2.c
$(CC) -o $@ $(CFLAGS) $(OBJS2)
.c.o:
$(CC) -c $(CFLAGS) $<
clean:
rm -f *.o *~ hello_world hello_world2 lib*.so
2) main.c
void print(char *argv );
int main() {
print("Hello World");
}
3) print.c
#include
#include
void print(char *argv ) {
printf(argv);
printf("\n");
}
4) main2.c
#include
#include
void print(char *argv ) {
printf(argv);
printf("\n");
}
int main() {
print("Hello World");
}
5) Run: make all from the command line
6) ftp to a sparc-sun-solaris2.6 machine. In binary mode
put hello_world, hello_world2, and libprint.so
7) ssh to the sparc-sun-solaris2.6 machine.
from the same directory in which you put the files:
chmod 755 hello_world hello_world2 libprint.so
export PATH=$PATH:.
export LD_LIBRARY_PATH:.
hello_world
hello_world2
both should print out "Hello World" on the command line otherwise there
is a problem (see Troubleshooting)
Troubleshooting:
1) The most common problem which I ran into was that during the build
process I would get a "No such file or directory" error. This was
usually because I did not have a system header file which GCC required.
This is solved by going to a sparc machine, then finding and copying
over the needed file.
2) Another problem I ran into was when the build process for GCC could
not find "sparc-sun-solaris2.6-ar." This means that the PATH variable
was not set to include the new executables produced in the binutils build.
3) If you ever run into an error in which you don't understand what is
happening, you can always use the command truss, or strace, to get a
list of the system calls to see in which directories the system is looking.
First of all, it is useful to try to run the command on the target
machine to see what is happening in the system calls. Then when you run
it on the build machine, you can see where the differences are and possibly
see what caused the error. Note: the build process changes environment
variables and those changes are lost outside the build process. It is
always usful to look through the make files to see how the evnvironment is
configured.
4) For many questions see: http://www.objsw.com/CrossGCC/
or check out other links from Cross-Compiling-bookmarks.html
5) There is also a newsgroup for cross-compilation questions:
To subscribe to the list, send a message to:
crossgcc-subscribe@sourceware.cygnus.com
Most of these header files can be found in /usr/include or
/usr/local/include.
Most of the libraries can be found in /usr/lib or
/usr/local/lib
Useful Unix commands:
truss (or strace)
- truss (or strace) executes the specified command and
produces a trace of the system calls it performs, the signals
it receives, and the machine faults it incurs. Each line of
the trace output reports either the fault or signal name or
the system call name with its arguments and return value(s).
System call arguments are displayed symbolically when possible
using defines from relevant system headers; for any pathname
pointer argument, the pointed-to string is displayed.
gunzip
tar
ftp
References:
See Cross-Compiling-bookmarks.html
Notes:
First, I am assuming that you do not have root access and that you do not
want the cross compiler installed in the directory /usr/local/
If you have root access or want to install the cross compiler in the
default directory:
1) In steps 4-6: when running the configure script, i.e. $ ../*/configure,
leave off the --prefix option.
2) In steps 4-6: before you run the command:
$ make install | tee &> install.log
you must first su to root so that you have root access to install the
binary files.
This document is the process I went through to build a linux -> solaris
cross compiler. Many of the instructions in this document are general
enough that they can be extended to build any cross compiler. However, there
are some special cases, such as building a cross compiler for win32 or OS/2.
For these cases, please see the Cross-Compiling-bookmarks.html because it has
many helpful links about building a cross compiler for those platforms.
For any questions or comments please feel free to e-mail me:
welsh@rice.edu
(I will be at this address until the start of Q4 2002)
Example:
Here is an example from a build that I made that was successful:
After unpacking all the source files in $src/
[ewelsh@smelt source]$ mkdir build-binutils
[ewelsh@smelt source]$ mkdir build-gcc
[ewelsh@smelt source]$ mkdir build-install
[ewelsh@smelt source]$ mkdir build-gdb
[ewelsh@smelt source]$ cd build-binutils/
../binutils-2.9.1/configure --host=i686-pc-linux-gnu --target=sparc-sun-solaris2
.6 --with-headers=/data/builds/ewelsh/headers/solaris2/include --with-libs=/data
/builds/ewelsh/headers/solaris2/lib --prefix=/data/builds/ewelsh/source/build-in
stall -v
[ewelsh@smelt build-binutils]$ make all | tee &> make.log
[ewelsh@smelt build-binutils]$ make install | tee &> install.log
../gcc-2.95.2/configure --target=sparc-sun-solaris2.6 --with-headers=/data/buil
ds/ewelsh/headers/solaris2/include --with-libs=/data/builds/ewelsh/headers/sola
ris2/lib --with-gnu-as --with-gnu-ld --prefix=/data/builds/ewelsh/source/build-
install -v
export PATH=$PATH:/data/builds/ewelsh/source/build-install/bin/
[ewelsh@smelt build-gcc]$ make all | tee &> make.log
[ewelsh@smelt build-gcc]$ make install | tee &> install.log
../gdb-5.0/configure --host=i686-pc-linux-gnu --target=sparc-sun-solaris2.6 --wi
th-headers=/data/builds/ewelsh/headers/solaris2/include --with-libs=/data/builds
/ewelsh/headers/solaris2/lib --prefix=/data/builds/ewelsh/source/build-install -
v
[ewelsh@smelt build-gdb]$ make all | tee &> make.log
[ewelsh@smelt build-gdb]$ make install | tee &> install.log