Tux
Communication
Mailing lists
Documentation
User Manual
Target board info.
Target chip info.
Support
Linux support
Bugzilla
Downloads
STLinux
Updates
Search
Google


The web
stlinux.com
Getting Started
Cross compilation with Autoconf/Libtool
ST Logo
Previous   Contents   Next

Introduction

Cross compiling for LinuxSH programs that use the Autoconf/Libtool system can be a little tricky because package authors don't always consider the issues involved in cross-development and the resulting configure script and Makefiles are often not suited to be used in a mixed environment.

I often found useful to collect all the commands and environment variables needed to reach a successful configuration in a simple shell script for future reference. This shell script may also form the base of the SPEC file needed to build an RPM version of the package. In the following sections I will show examples of commands or definitions that will go into this script.

Configuration

The configure script has a number of default command-line options that are available regardless of the package and some of them are meant to support cross-compilation. The availability of such options does not mean that the specific package can be easily cross-compiled without some tweaking of the whole process.

The configure script is generated automatically by the package maintainer using the Autoconf system. The recent release of Autoconf 2.5x changed the meaning of some of the options. To discover which version of Autoconf generated the configure script, run it with the --version option:

$ ./configure --version
configure generated by autoconf version 2.13

The most important options are:

--build
This option defines the architecture of the computer where you are building the program. It is usually an Intel PC running Linux. In this case the argument of the option should be something like: i686-pc-linux-gnu.
--build="i686-pc-linux-gnu"
If the program has a config.guess script available in its top-level directory, its output should be used to get the exact definition:
--build="`./config.guess`"
This solution is the preferred one. The example assumes that you are configuring the package from its top level directory.
--host
This option defines the architecture of the system that will host the program once compiled. This is more generally known as the target architecture but in Autoconf lingo this name can be misleading and host must be used. (See next option.)
For LinuxSH the definition string will be: sh4-linux.
--host="sh4-linux"
--target
This option should only be used when building development tools like compilers, assemblers and linkers, e.g. Gcc or Binutils. Normal programs should not use it. It defines the microprocessor architecture for which code will be generated by the tool.
--prefix
This is used to define the final installation directory for the package. Note that this is where the program will find itself when running on the actual target. It is not the directory where you are installing it on your host machine. In order to install the software on the development host, the prefix variable will be overridden at install time on the make command line.
--prefix="/usr"

Environment variables

Configure behavior is often controlled by setting some environment variables. The following variables should always be defined (the examples are in Bourne shell syntax):

CROSS_COMPILE
This is sometimes used by configure to detect a cross development environment. It is not needed by configure scripts generated by Autoconf 2.5x.
export CROSS_COMPILE=1
CC and CXX
These are used to define the C and C++ compiler commands. For the SH cross development environment they usually are sh4-linux-gcc and sh4-linux-g++.
export CC="sh4-linux-gcc"
export CXX="sh4-linux-g++"

Some other environment variables will be needed according to the particular package being built.

Invoking configure

Before proceeding any further, run configure --help to see all the available options and check the dependencies of the package by reading the documentation: it is very important that all the required libraries are already in place. If some of them are also available on the development host as part of your linux distribution, be aware that later in the process you may discover that these are the ones being used and not those from your cross development environment.

Some packages compile and run small test programs at configure time to test the availability or the presence of some features in other software. These programs won't run on your host when cross compiling so these tests must be disabled. The configure options that control this behavior often end with the string test. Here is an example from gdk-pixbuf:

--disable-glibtest

This behavior is also controlled by the --host and --build options in scripts generated by Autoconf 2.5x. Supplying both options puts the script in cross-compile mode and disables all tests that require compiling and running a small test program. Note that this mode does not disable the tests that are controlled by command-line options like --disable-glibtest.

Use all the available options of this kind but remember that you then have to be sure that the correct versions of the required packages are already installed.

Some recent libraries come with a configuration script whose name ends in -config like gtk-config. Its purpose is, when invoked with the --cflags and--libs options, to print the correct compiler options that must be used by programs using that library.

The cross development versions of these programs should not usually be available on the path, otherwise it wouldn't be possible to compile normal applications on the host computer. The best way to let configure find and use the ones provided by the cross development package is setting some environment variables to the full path of the SH version. Here is an example for a program that needs gtk-config:

export GTK_CONFIG="/opt/STM/ST40Linux-1.0/devkit/sh4/sh4-linux/bin/gtk-config"

The variable name is always the name of the program in upper case with an underscore replacing the hyphen.

If, instead, you are building a library that will install a -config script check what it prints when invoked using the --cflags and --libs options. The paths must point to your target environment. This is what the SH version of glib-config prints (line wrapped for readability):

$ /opt/STM/ST40Linux-1.0/devkit/sh4/sh4-linux/bin/glib-config --cflags
-I/opt/STM/ST40Linux-1.0/devkit/sh4/sh4-linux/include/glib-1.2
-I/opt/STM/ST40Linux-1.0/devkit/sh4/sh4-linux/lib/glib/include

This command is part of the development environment belonging to the host and shouldn't be installed on the target. This is why the directories it prints should be relative to the development host and not to the embedded target. As the output strings are built at compile time using the argument of the --prefix option, you need to change them before installing the script

The best way to change these directories is by using a simple sed script (the example assumes a package configured for /usr) (backslash added for readability):

$ mv gdk-pixbuf-config gdk-pixbuf-config.orig
$ sed -e "s#/usr#/opt/STM/ST40Linux-1.0/devkit/sh4/sh4-linux#g" \
  < gdk-pixbuf-config.orig > gdk-pixbuf-config

Libtool

Quoting from the user manual:

In the past, if a source code package developer wanted to take advantage of the power of shared libraries, he needed to write custom support code for each platform on which his package ran. He also had to design a configuration interface so that the package installer could choose what sort of libraries were built.

GNU Libtool simplifies the developer's job by encapsulating both the platform-specific dependencies, and the user interface, in a single script. GNU Libtool is designed so that the complete functionality of each host type is available via a generic interface, but nasty quirks are hidden from the programmer.

Well, nasty quirks are a little more visible when cross compiling.

If the package you are cross compiling uses the libtool script to build a library, you need to rebuild it using the ltconfig command from the package itself if available. The libtool script must be rebuilt with knowledge of the target architecture. This can be achieved with the following script (Bourne shell syntax):

#! /bin/sh
 
PREFIX=$1
 
export CC="${PREFIX}-gcc"
export LD="${PREFIX}-ld"
export NM="${PREFIX}-nm -B"
export AR="${PREFIX}-ar"
export RANLIB="${PREFIX}-ranlib"
export LN_S="ln -s"
export CFLAGS="-g -O2"
 
echo "Rebuilding libtool for \"$PREFIX\" ..."
./ltconfig --cache-file="./config.cache" --with-gcc --with-gnu-ld --no-verify \
           ./ltmain.sh $PREFIX
echo "Done."

Call it makelibtool and invoke it with a single argument: the name of the target architecture as in:

$ makelibtool sh-linux-gnu
Rebuilding libtool for "sh-linux-gnu" ...
Done.

The variable definitions and the ltconfig command can also be embedded in a larger script that takes care of the configuration process. The CFLAGS varible defined in this script is only the default value used by libtool. This will be overridden by the definition seen by configure. If you are embedding these commands in a larger Bourne shell script, you can redefine CFLAGS for the ltconfig invocation only in this way:

$ CFLAGS="-g -O2"  ./ltconfig --cache-file="./config.cache" ...

If the ltconfig command should not be present if the configuration scripts have been generated by Autoconf 2.5x. In this case the same configure will generate a new libtool command.

X11

The use of X11 can be controlled using the --x-includes and --x-libraries options as in:

--x-includes="/opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/X11R6/include"
--x-libraries="/opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/X11R6/lib"

Where /opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/X11R6 is the full path to the SH version of X11.

Compilation

Once configure has run without errors, you can finally build the package. But just typing make isn't enough: some old packages need the compilers to be specified again on the make command line as in:

make CC="sh4-linux-gcc" CXX="sh4-linux-g++"

If you need to define some other preprocessor symbols, you can define them at compile time adding them to the AM_CPPFLAGS variable on the make command line:

make AM_CPPFLAGS="-DSTDC_HEADERS"

Hints and tips

Here are some hints and tips about the whole process:

  1. During its tests configure writes a detailed log of all its activity in the file config.log. If you find yourself in troubles, this is the first place to look for errors.
  2. When configure runs, it first checks if a file called config.cache is available in the current directory. If it is, the file is loaded before all the tests are executed, preloading many autoconf variables with the cached values.

    If configure is guessing something wrong and you can't find a way to change its behavior, you can edit the config.cache file deleting everything but the variable definition that needs to be changed. The next time configure is run, it will skip the faulty test loading your custom defined value from the cache file.

A simple example

Here is a simple example of a shell script that configure and build the gdk-pixbuf shared library that depends on GTK+ and X11.

#! /bin/sh

# base directory of the cross development environment
devkit_base="/opt/STM/ST40Linux-1.0/devkit/sh4"

devkit_dir="${devkit_base}/sh4-linux"
x_dir="${devkit_base}/target/usr/X11R6"

# local directory with target files
target_dir="${devkit_base}/target"

# architecture prefix
arch="sh4-linux"

# environment variables
export CC="${arch}-gcc"
export LD="${arch}-ld"
export NM="${arch}-nm -B"
export AR="${arch}-ar"
export RANLIB="${arch}-ranlib"
export LN_S="ln -s"
 
export CFLAGS="-O2"
export CROSS_COMPILE=1

# configuration commands for GTK+
export GLIB_CONFIG="${devkit_dir}/bin/glib-config"
export GTK_CONFIG="${devkit_dir}/bin/gtk-config"

# configuration
./configure --build="`./config.guess`" --host="${arch}" --prefix="/usr" \
            --disable-glibtest --disable-gtktest --disable-mmx --disable-modules \
            --x-includes="${x_dir}/include" --x-libraries="${x_dir}/lib"

# rebuild libtool
CFLAGS="-g -O2" ./ltconfig --cache-file=./config.cache --with-gcc --with-gnu-ld \
                           --no-verify ./ltmain.sh ${arch}

# build library
make CC="${CC}" pixbuf_demo_LDFLAGS="\"-lpng -ltiff -ljpeg -lz\""

# Change gdk-pixbuf-config path
mv gdk-pixbuf-config gdk-pixbuf-config.orig
sed -e "s#/usr#${devkit_dir}#g" < gdk-pixbuf-config.orig > gdk-pixbuf-config

# install
make prefix="${target_dir}/usr" install
Previous   Contents   Next
Valid HTML 4.01! Last updated: 2002/03/15 23:08:09
© Copyright STMicroelectronics Limited, 2005
Printer