Linux on IBM eServer zSeries: Configuring gcc as a cross-compiler

Abstract

This tip details how to configure gcc on Linux for IBM eServer zSeries to act as a cross-compiler.

For related information about this topic, refer to the following IBM Redbooks publication:
Linux on IBM eServer zSeries and S/390: Application Development, SG24-6807-00

Contents

By default, gcc compiles code for the same type of machine that it runs on. However, it may also be configured as a "cross-compiler". A cross-compiler allows you to create programs that can be run on architectures different than the one used for a compilation. Configuring a cross-compiler consists of the following steps:

  • Downloading and installing prerequisites
  • Compiling binutils
  • Installing libraries
  • Compiling the cross-compiler

The complier and utilities are in the /usr/cross-devel/ directory. To be able to use the compiler, you need a full development environment on your machine; make sure at least the following packages are present:
  • gcc-compiler and standard C/C++ development libraries
  • binutils package
  • autoconf (provides autoheader utility)
  • yacc and flex packages

Before you compile the binutils package, you must obtain the source code, so install the binutils.spm package provided by SuSE distribution. The source ball will be extracted to the /usr/src/packages/SOURCE directory. Unpack this to a temporary directory:
    bunzip2 < /usr/src/packages/SOURCES/binutils-2.11.90.0.27.tar.bz2 |tar -C /tmp -xf -

Change your working directory to the binutils source and run configure:
    cd /tmp/binutils-2.11.90.0.27
    ./configure --prefix=/usr/cross-devel --target=i386-pc-linux s390-ibm-linux
Start the compilation, and install the binaries to the /usr/cross-devel directory:
    make; mkdir /usr/cross-devel; make install

Installing libraries
In order to produce executable files, you need to install libraries precompiled for a particular architecture. Compiling glibc from source is possible, but we suggest using the precompiled version that is commonly used on Linux for i386. You can download glibc from the following site:
Look for the version closest to that installed on your platform:
    rpm -q glibc
    glibc-2.2.2-25
    rpm -q glibc-devel
    glibc-devel-2.2.2-25

In this example, we used version 2.2.2-38 (part of the SuSE Distribution for Linux on i386). We needed both glibc.rpm and glibc-devel.rpm. Include files and libraries should be installed in the directories with names that begin with compiler_prefix/architecture. In this case, we used:
    /usr/cross-devel/i386-pc-linux/include
and
    /usr/cross-devel/i386-pc-linux/lib
These library packages cannot be installed using the rpm tool (this would conflict with existing libraries). Instead, use the following procedure:
  • Create a temporary directory:
    mkdir /tmp/i386
  • Unpack libraries with cpio:
    cd /tmp/i386
    rpm2cpio ../glibc.rpm | cpio -id
    rpm2cpio ../glibc-devel.rpm | cpio -id
  • Move the include part to /usr/cross-devel/i386-pc-linux. (Note: You don’t have to create /usr/cross-devel/i386-pc-linux; it's created during installation of the binutils package.)
    cd /tmp/i386/usr
    cp -a include /usr/cross-devel/i386-pc-linux
  • Move the contents of lib and usr/lib directories to the /usr/cross-devel/i386-pc-linux/lib directory:
    cd /tmp/i386
    cp -a lib /usr/cross-devel/i386-pc-linux
    cd usr
    cp -a lib /usr/cross-devel/i386-pc-linux
  • We merged files from two directories. Now we had to fix some symbolic links in /usr/cross-devel/i386-pc-linux/lib:
    cd /usr/cross-devel/i386-pc-linux/lib
  • We need to remove the prefix ../../lib/ from symbolic links. (Note: Type in this long command carefully; it's a single command.)
    ls -l | grep ../../lib | cut -c57- | cut -d' ' -f1,3 | \
    sed 's^../../lib/^^' | \
    while read a b ; do rm -f $a ; ln -s $b $a ; done
  • Correct libc.so accordingly (this is a plain text file):
    /* GNU ld script
    Use the shared library, but some functions are only in
    the static library, so try that secondarily. */
    GROUP (
      /usr/cross-devel/i386-pc-linux/lib/libc.so.6
      /usr/cross-devel/i386-pc-linux/lib/libc_nonshared.a
    )

Compiling the cross-compiler
The gcc.spm package that comes with SuSE Linux 7.2 for zSeries contains the main source gcc-2.95.3.tar.gz and patches specific for S/390. Look for the following:
    gcc-2.95.3-s390.tar.gz
    gcc-2.95.3-s390-1.tar.gz
    gcc-2.95.3-s390-2.tar.gz
Next, we describe how to prepare the source code:
  • Unpack the main source package:
    tar -C /tmp -zxf /usr/src/packages/SOURCES/gcc-2.95.3.tar.gz
  • Unpack patches in the temporary directory:
    mkdir /tmp/gcc-patches
    cd /tmp/gcc-patches
    tar -zxf /usr/src/packages/SOURCES/gcc-2.95.3-s390.tar.gz
    tar -zxf /usr/src/packages/SOURCES/gcc-2.95.3-s390-1.tar.gz
    tar -zxf /usr/src/packages/SOURCES/gcc-2.95.3-s390-2.tar.gz
  • Apply the patches:
    cd /tmp/gcc-2.95.3
    patch -p1 < /tmp/gcc-patches/gcc-2.95.3-s390.diff
    patch -p1 < /tmp/gcc-patches/gcc-2.95.3-s390-1.diff
    patch -p1 < /tmp/gcc-patches/gcc-2.95.3-s390-2.diff
  • Configure gcc as a cross-compiler:
    ./configure --prefix=/usr/cross-devel \
    --with-headers=/usr/cross-devel/i386-pc-linux/include/ \
    --target=i386-pc-linux s390-ibm-linux
    Note: We found that the --with-headers option is essential in order to avoid specifying the -I option when working with the cross-complier later on.
  • Compile:
    make
    Note: In some configurations, the PATH_MAX constant is not correctly defined properly. If you encounter this problem, add the following lines after the include section:
    #ifndef _POSIX_PATH_MAX
    #define _POSIX_PATH_MAX 255
    #endif
  • Install package:
    make install
Using the cross-complier
Once the complier has been installed, update your PATH environment variable:
    export PATH=/usr/cross-devel/bin:$PATH

Executable files for the i386 platform are created when gcc is invoked with a proper prefix. In our example, we used the i386-pc-linux-gcc command. We suggest setting the CC variable to this command in order to instruct make as to which complier is to be used. For example, to make an executable test from source file test.c, issue the following:
    $ export CC=i386-pc-linux-gcc
    $ make test
    i386-pc-linux-gcc t.c -o t
    $ file test
    test: ELF 32-bit LSB executable, Intel 80386, version 1, dynamically linked (uses shared libs), not stripped

Special Notices

This material has not been submitted to any formal IBM test and is published AS IS. It has not been the subject of rigorous review. IBM assumes no responsibility for its accuracy or completeness. The use of this information or the implementation of any of these techniques is a client responsibility and depends upon the client's ability to evaluate and integrate them into the client's operational environment. publib-b.boulder.ibm.com

Profile

Publish Date
24 June 2002


Rating: Not yet rated


Author(s)

IBM Form Number
TIPS0005