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

Needed Header Files and Libraries:

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