Getting Started
Cross compiling GTK+ v2
|
|
One Script to rule them all, One Script to
find them, One Script to bring them all and in the Darkness bind
them.
This paper documents the efforts needed to cross compile the GTK+ v2
set of libraries on a Linux/Intel host for a SuperH based Linux
target.
I have been developing and packaging applications for the
STMicroelectronics Embedded Linux distribution for the SuperH
family of microprocessors (STLinux) since 2000 and working on Linux and
embedded systems in general since 1997.
STMicroelectronics is actively developing a port of Linux on the
SuperH family of processor. Its contribution is available as a
complete Embedded Linux distribution on
www.linuxsh.st.com
GTK+ v2 (GTK2) is only one of the X11 widget libraries available in our
distribution, the others being Qt/Embedded by Trolltech and the previous
version of GTK+: version 1.2
GTK2 is more than a simple collection of widgets for X11. The whole
system is comprised of four libraries: Glib, Atk, Pango and Gtk. Gtk
itself is made of sub-libraries that cover the specific areas needed to
draw a complex GUI on screen: gdk contains the low-level drawing
routines, gdk-pixbuf handles all the standard image formats (Jpeg,
PNG, GIF, etc.), and gtk implements the high-level visible
widgets.
The decision to package a complex set of libraries like those that make
GTK2 has been taken because of customer request. We knew in advance that
packaging such a complex system was going to be difficult because of the
intricate dependencies that such packages always show, dependencies that
become even more difficult to get right when cross compiling in an
environment different from the one where the library will actually be
used.
Our embedded Linux distribution, STLinux, is a collection of
tools and applications created to support the development of Embedded
Linux systems targeted at the SuperH family of processor on an host
platform, currently an x86 PC running RedHat Linux.
It must be stressed that STLinux is not a complete distribution; it can
only be installed on top of an already existing RedHat Linux system. All
its packages have names starting with the stm- prefix to clearly
separate them from the standard packages installed on the host.
STLinux is completely self contained in a single directory rooted at
/opt/STM/ST40Linux-1.0; from now on we'll call this directory
$STROOT. The most important tools available are a cross
compiler (gcc), a debugger with remote debugging capabilities (gdb),
loaders for different evaluation boards, and a set of kernels with
different configurations.
A set of packages (the stm-target-* ones) can be used to build a
compact but fully functional target environment rooted at
$STROOT/devkit/sh4/target. This environment provides a
complete root filesystem that can be used on the evaluation boards to
create a working Linux system. It could be directly mounted using NFS or
its content can be copied to a bootable flash memory.
The most important subtrees available in our distribution are, for our
purpose, and relative to the base path shown above:
- .../host
- .../devkit/sh4
- .../devkit/sh4/target
Each of these contains a fairly standard Linux tree of directories:
/bin, /lib, /share and so on.
Let's look in more detail at the type of files contained in those
directories
- /host
- This tree contains files that may be needed when developing an
application for STLinux on the host machine. Binaries in the
bin subdirectory have a target- prefix, e.g.
target-shellconfig. Typically the equivalent SH version is
installed somewhere in $STROOT/devkit/sh4/target. These
files are located here because they are considered architecture
independent, i.e. they are the same regardless whether you are using an
SH3 or SH4 target.
- /devkit/sh4
- This directory contains x86 hosted development tools that are in
some way dependent on the target architecture. Binaries in the
bin subdirectory have a sh4-linux- prefix,
e.g. sh4-linux-gcc. The directory also contains header and config
files for SH libraries installed in the target subtree to be used when
cross compiling on the host. These include the libtool .la
files and the pkgconfig .pc files.
- /devkit/sh4/target
- This tree is a complete root filesystem for an SH4 target. It is
populated by the stm-sh4-* rpm packages and can be mounted by a
development board using NFS.
The reason why we focus on cross compilation is that many embedded
Linux systems are not powerful enough to support a self-hosted complete
development environment. This environment must nonetheless be available to
leave to the developer the option of compiling complex packages on a
target system. The computing power gained by developing on the host
machine is balanced by the more complex environment needed by cross
compilation.
The key issue in this setup is that libraries assume a
"split-personality". The library itself, the header files, the
libtool and pkg-config files, and any other files that may be related to a
library, need to be usable in two very different environments: cross
compiling on the host and also compiling or running an application on the
target.
Every STLinux library package contains only the basic libraries needed
to run applications on the target, while the -dev packages contain
all the remaining files needed for development. This are the packages that
provide the dual environment previously described.
Another key point that we tried to enforce in creating packages for the
STLinux distribution is the independence from the host platform. Our
distribution currently support RedHat 6.2 and 7.x.
Differences in the host environment should not affect a closed system
like ours but they can become important when rebuilding the packages. This
is due to the autoconf tools that tend to look for the
information they need in many places and are difficult to constrain to a
subset of the directory tree. They often end up looking for commands or
libraries on the host system making the host environment an important
factor in the whole process of cross-compiling packages.
The main STLinux developer tools all have their name prefixed with the
sh4-linux string. Thus the SH4 compiler is named
sh4-linux-gcc and so on. These tools are built and set up so
that they look for and use libraries and header files only in the
$STROOT directory.
If we cross compile a simple Hello World program hello.c
using the -v option, we get the following output
(slightly edited for readability):
...
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/gcc-lib/sh4-linux/3.0.3/cc1 -lang-c -v
-D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNUC_PATCHLEVEL__=3 -D__ELF__ -Dunix -D__sh__
-Dlinux -D__ELF__ -D__unix__ -D__sh__ -D__linux__ -D__unix -D__linux -Asystem=posix
-D__NO_INLINE__ -D__STDC_HOSTED__=1 -D__LITTLE_ENDIAN__ -D__SH4__ hello.c
-musermode -ml -m4 -quiet -dumpbase hello.c -version -o /tmp/ccJ2qMEH.s
GNU CPP version 3.0.3 (STMicroelectronics/Linux Basic) (cpplib) (SH4 GNU/Linux with ELF)
GNU C version 3.0.3 (STMicroelectronics/Linux Basic) (sh4-linux)
compiled by GNU C version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release).
#include "..." search starts here:
#include <...> search starts here:
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/gcc-lib/sh4-linux/3.0.3/include
/opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/include
End of search list.
...
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/gcc-lib/sh4-linux/3.0.3/collect2
-dynamic-linker /lib/ld-linux.so.2
/opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/lib/crt1.o
/opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/lib/crti.o
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/gcc-lib/sh4-linux/3.0.3/crtbegin.o
-L/opt/STM/ST40Linux-1.0/devkit/sh4/target/lib
-L/opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/lib
-L/opt/STM/ST40Linux-1.0/devkit/sh4/lib/gcc-lib/sh4-linux/3.0.3
-L/opt/STM/ST40Linux-1.0/devkit/sh4/sh4-linux/lib
/tmp/ccsYYbUi.o -lgcc -lc -lgcc
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/gcc-lib/sh4-linux/3.0.3/crtend.o
/opt/STM/ST40Linux-1.0/devkit/sh4/target/usr/lib/crtn.o
|
|
|
It is clear the all the tools work inside a self-contained environment
rooted at $STROOT.
The Real Thing
The GTK+ v2 framework
The GTK2 system is more than a simple widget set. Is is a set of
tightly connected libraries, each one optimized for a particular task,
designed to build complex user interfaces for multi-lingual
applications.
These libraries are distributed as separate packages and must be built
following an exact sequence. Some of these libraries depends, in turn, on
other software that should be already available in the system. Here is a
brief description of the libraries from the
www.gtk.org website.
- GLib
- This is the low-level core library that forms the basis of GTK+ and
GNOME. It provides data structure handling for C, portability wrappers,
and interfaces for such runtime functionality as an event loop, threads,
dynamic loading, and an object system.
- Pango
- is a library for layout and rendering of text, with an emphasis on
internationalization. It forms the core of text and font handling for
GTK+-2.0.
- ATK
- The ATK library provides a set of interfaces for accessibility. By
supporting the ATK interfaces, an application or toolkit can be used with
such tools as screen readers, magnifiers, and alternative input
devices.
- GTK+
- is a multi-platform toolkit for creating graphical user interfaces.
Offering a complete set of widgets, GTK+ is suitable for projects ranging
from small one-off projects to complete application suites.
The external dependencies of these four libraries are:
- Freetype
- This is the de-facto standard for the rendering of TrueType fonts and
is used Pango and ?????
- Graphics libraries (jpeg, png, tiff)
- These are used to support image formats and are used by components
inside GTK+
These libraries are considered available in their native (x86) versions
on the build machine. While libjpeg, libpng and libtiff are quite stable
and suitable versions are available on RedHat 6.x, Freetype can be more
problematic. To build GTK2, Freetype 2 is in fact needed on the host.
The first library built was Freetype. I knew it was a prerequisite
for Pango and it is needed by other applications too.
Its build system uses autoconf but does it in a special way. Instead
of being directly invoked before make, the configure script is
called by a pre-existing Makefile using the setup target. Options
for the script can be passed in using the CFG make
variable. E.g.
make setup CFG="--prefix=/usr --build=i686-pc-linux-gnu --host=sh4-linux" CC="sh4-linux-gcc"
|
|
|
The content of the variable is used as the only command line
arguments to configure.
The only important patch needed introduced the DESTDIR variable in
builds/unix/install.mk as a prefix to all the destination
directories to simplify the installation step.
As usual, at the end of the compilation, the host libtool files (.la)
and the freetype-config utility had to be modified for a cross
development environment.
Installation was straightforward with a simple
make install DESTDIR="%{buildroot}%{_stm_cross_target_dir}"
|
|
|
command. The host environment for cross compilation had to be created
manually but this has became a standard procedure in our spec files.
This package provides a stripped down x86 version of GLib 2 and some
of the binaries that come with it. Host versions of these tools are
needed during the cross compilation phase and when building other
packages. It must be noted that the need for this package emerged only
after trying to compile GLib 2 for the target system. This added to the
final time needed.
We decided to provide this package because we can't assume that a
suitable version of glib2 is available on the host system (e.g. RedHat
6.x) and to be able to track changes in the library independently from
the host distribution.
Building the library for the host system is easy. The only thing I
had to do is passing configure the proper options to make the
library aware of the unusual installation path
($STROOT/host.)
Installation was straightforward due to the DESTDIR and
transform make variables. The first quirk in the system is
found here: the transform variable is used to specify a
sed command that is applied to the executables name.
E.g.
This will prepend the string "target-" to the name of all
executables. This modification is performed at install time but the
pkg-config files are generated at the end of the configuration phase and
therefore they still contain the original name. A sed command is used to
fix this in the %install section of the spec file.
The commands installed by this package are:
- $STROOT/host/bin/target-glib-genmarshal
- $STROOT/host/bin/target-glib-gettextize
- $STROOT/host/bin/target-glib-mkenums
- $STROOT/host/bin/target-gobject-query
A brief note on the target-gobject-query command. It is
supposed to DO WHAT WITH MODULES??? but will it work when
handling modules for a different architecture?
This package marked the beginning of the complex stuff
The first thing you want to try after reading a bit about autoconf is
the following simple command:
./configure --build="i686-pc-linux-gnu" --host="sh4-linux"
|
|
|
You get the following error message:
checking for extra flags to get ANSI library prototypes...
configure: error: cannot run test program while cross compiling
|
|
|
A bit of investigation shows that this is due to the following section
of the configure.in:
dnl DU4 native cc currently needs -std1 for ANSI mode (instead of K&R)
AC_MSG_CHECKING([for extra flags to get ANSI library prototypes])
glib_save_LIBS=$LIBS
LIBS="$LIBS -lm"
AC_TRY_RUN([#include <math.h>
...
|
|
|
This is just the first example of the use of the
AC_TRY_RUN() macro in autoconf scripts. Using this macro
prevents the package to be configured (and built) in a cross development
environment. A quick check shows 18 (eighteen) invocations of that macro
in configure.in.
Many of those invocations can be avoided preloading the cache
file config.cache with correct values. When configure runs it
checks for this file and if found it sources it. config.cache
is just a sequence of Bourne shell variable assignments. Many of the
autoconf macros do not perform their checks if a certain variable is
pre-defined. By preloading the cache with values we force
configure to skip those tests and we avoid the problem. Yes,
I know, it's ugly :-)
Here's how we do it (first few lines from the spec file):
# preload config.cache with proper values
cat > config.cache << EOF
glib_cv_long_long_format=\${glib_cv_long_long_format=ll}
glib_cv_stack_grows=\${glib_cv_stack_grows=no}
glib_cv_has__inline=\${glib_cv_has__inline=yes}
glib_cv_has__inline__=\${glib_cv_has__inline__=yes}
...
|
|
|
And we then invoke configure with the
--cache-file="config.cache" option. 19 variables are needed
to reach a successful completion of the configure script.
Some other problematic tests that use AC_TRY_RUN() without
the possibility of being overridden with a cache variable are the threads
and the poll() support sections. In order to fix these problems I
had to patch configure.in and generate a new
configure script. MORE DETAIL FROM THE PATCH
Even rebuilding configure can be problematic because the
configure.in file requires autoconf 2.52 or higher while RedHat 7.3 still
uses autoconf 2.13 as default. Version 2.52 is available but its name is
autoconf-2.52. Using this filename in the spec file will make
them non portable and will break when autoconf is upgraded.
After these modifications autoconf works and generate a working
Makefile:
./configure --build="i686-pc-linux-gnu" --host="sh4-linux" --prefix="/usr" ...
|
|
|
Installation is again problematic because the standard
libtool script tries to relink (what does it mean and
why is it needed?) the libraries and fails with the following error:
$ make install DESTDIR="/tmp/testdir"
... lot of output ...
/bin/sh ../libtool --mode=install /usr/bin/install -c libgobject-2.0.la \
/tmp/testdir/usr/lib/libgobject-2.0.la
libtool: install: warning: relinking `libgobject-2.0.la'
( cd /home/chinstrap/users/acister/work/packages/BUILD/glib-2.0.4/gobject;
/bin/sh ../libtool --mode=relink sh4-linux-gcc -O2 -Wall -D_REENTRANT -o libgobject-2.0.la \
-rpath /usr/lib -version-info 0:4:0 -export-dynamic \
gboxed.lo ... object files ... gvaluetypes.lo \
../glib/libglib-2.0.la -inst-prefix-dir /tmp/testdir
)
sh4-linux-gcc -shared gboxed.lo ... object files ... gvaluetypes.lo \
-L/usr/lib -L/tmp/testdir/usr/lib -lglib-2.0 -Wl,-soname -Wl,libgobject-2.0.so.0 \
-o .libs/libgobject-2.0.so.0.0.4
/usr/lib/libglib-2.0.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
libtool: install: error: relink `libgobject-2.0.la' with the above command before installing it
make[2]: *** [install-libLTLIBRARIES] Error 1
...
|
|
|
It is clear that libtool tries to link the SH4 object
files with an x86 library located in /usr/lib. This is the
result of some hard-coded paths in the libtool script itself.
Given the complexity of libtool this problem has been
solved by using an extremely simple replacement called
libtool-local that handles the installation phase with less
"cleverness" and just installs things where they should go. The script is
added to the top-level directory by the %prep section of the
spec file.
The final command line for installation is then:
make install DESTDIR="/tmp/testdir" LIBTOOL="$(pwd)/libtool-local"
|
|
|
As usual the host libtool files (.la) and the pkg-config files (.pc)
had to be rebuilt and the target specific directory tree had to be
populated for a cross development environment. The files installed are
needed when cross compiling SH4 applications that use GLib 2.
This was easier. The only case where the autoconf system actually
worked once provided the right environment and the right options.
As usual the host libtool files (.la) and the pkg-config files (.pc)
had to be rebuilt and the target specific directory tree had to be
populated for a cross development environment.
The reason we need an host package for Pango is the
pango-querymodules command. Is is used by the Makfiles of
other libraries and is part of the standard development environment for
Pango applications.
For the first attempt I configured the package as follows:
CFLAGS="-O2" ./configure --with-qt=no --disable-shared --with-included-modules=basic-ft2,basic-x
|
|
|
This works OK but leaves me with an executable with lots of
dependancies on libraries that may not be available on the host:
$ ldd ./pango/pango-querymodules
libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0x40020000)
libgmodule-2.0.so.0 => /usr/lib/libgmodule-2.0.so.0 (0x4005a000)
libdl.so.2 => /lib/libdl.so.2 (0x4005e000)
libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0x40061000)
libXft.so.1 => /usr/X11R6/lib/libXft.so.1 (0x400c6000)
libXrender.so.1 => /usr/X11R6/lib/libXrender.so.1 (0x400f0000)
libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x400f5000)
libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x40103000)
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x401d8000)
libc.so.6 => /lib/i686/libc.so.6 (0x42000000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$
|
|
|
Wich is a big number of libraries for a simple, command-line program
that doesn't need half of them.
In the end I decided to go with a custom build sequence because I
wanted a very simple pango library; the bare minimum needed to build
pango-querymodules that, by itself, doesn't need X11 or
Freetype, but only some pango functions and GLib 2.
The config file config.h and the list of files needed
for this minimal libpango have been taken from a standard build run. The
executable is basically built and installed by hand and only depends on
the host GLib 2 library and glibc.
At this point things are starting to get really difficult. First of
all Pango needed a number of patches to work:
- The
glib-mkenums program name is hard-coded in
Makefiles.am. Why? The macro @GLIB_MKENUMS@ is available
for substitution in configure and could be used to override
the custom setting by setting the environment variable with the same
name.
- The
configure script tries to build the OpenType tests
but it fails on RedHat 6.x. I had to delete the corresponding macro from
configure.in and rebuild it.
- Examples and tests are built by default but they fail when
cross-compiling. The system tries to run the freshly built
pango-querymodules command but it is an SH4
executable.
- The
pango-querymodules command name, needed during
compilation, is hard-coded in the Makefiles to the one that has just
been built (i.e. an SH4 executable). To make this work when cross
compiling I patched the Makefiles and added a
$TARGET_PREFIX variable to the command name. I still have
to manually copy the x86 executable in the pango directory for this to
work.
Having changed configure.in we have to rerun
autoconf. This operation on Pango resulted in a number of
problems.
-
On systems where GLib 2 is not available as part of the standard
installation (e.g. RedHat 6.2) we get this error:
error: no macro AM_PATH_GLIB_2_0
|
|
|
This happens even if we have already installed the stm-host-glib2
package that provides a GLib 2 host development environment.
- It seems that old versions of autoconf/automake/aclocal are required
on the host computer. At least if we have to use automake. This is in
contrast with other libraries that require autoconf >= 2.52 for
example.
- After running
autoconf it seems that we need to run
configure at least once on the host system in order to have
a working environment. This makes Freetype 2 a needed package on the host
machine. Another unneeded dependency.
Let's look at these in more detail.
The AM_PATH_GLIB_2_0 macro is used in
configure.in and can be found in the glib-2.0.m4
file that is installed with glib2. On those systems where glib2 is not
available as part of the standard installation (e.g. RedHat 6.2) the file
is installed with the glib2-host-dev package outside of the
canonical /usr/share/aclocal directory. (I.e. in
$STROOT/host/share/aclocal)
When rebuilding the aclocal.m4 file in the pango top-level directory
using the aclocal command, we could use the
--acdir command line option to tell aclocal to search in
$STROOT/host/share/aclocal but this doesn't work because many
standard macros are missing now. The fact is that aclocal
only looks in one directory for its m4 macro files: the default one
(/usr/share/aclocal) or the one passed with the last
--acdir option. If you have macros in more than one place
you're stuck.
I solved this problem by copying at build time all the available m4
macros into one temporary directory and using this directory as argument
to the --acdir option of aclocal. An interesting problem I
run into while doing this is trying to locate the directories holding the
m4 files. The --print-ac-dir option is not enough because it
only prints /usr/share/aclocal (at least on 1.4-p5 and 1.5)
and not the complete versioned directory
/usr/share/aclocal-x.x.
This directory could be accessed knowing the aclocal version number but
the strings printed using --version can have strange formats
like 1.4-p5 or 1.5 or 1.6.1. After some cut and
sed acrobatics I managed to extract the real version number in its
X.X format and access the right versioned directory. A more
uniform and easily machine readble version number would definitely help in
this case.
The autoconf/automake/aclocal version mismatch was discovered because
using automake 1.5 on a RedHat 7.3 box the reconfiguration step failed
with cryptic messages. I had to revert back to the old versions (autoconf
2.13 and automake 1.4) for the process to work again. This is in contrast
with the GLib 2 package where autoconf >= 2.52 was needed. These tools
are already overly complex, a standardisation of the version used would
help a lot.
If we had run configure and make in cross compile mode now, we would
end up with two invocations of configure, the second one being triggered
by a rule in the Makefiles when running make. To avoid configure being
executed without the right options, I had to perform the following
steps:
- Rebuild configure using
automake -a -c and
autoconf.
- Run
configure with extremely simple options (this needs
Freetype 2 on the host to succeed.)
- Run
make distclean to trigger another automatic
configure invocation and to clean the environment.
- Finally run
configure in cross compile mode
- Run
make defining the appopriate
TARGET_PREFIX and ACLOCAL variables.
Installation is again tricky. I had to use the
libtool-local script again because of re-linking problems.
The target .la and .pc files are broken: they
contain the host directory instead of /usr/lib; they had to
be corrected with sed.
As usual the host libtool files (.la) and the pkg-config
files (.pc) had to be rebuilt and the target specific
directory tree had to be populated for a cross development
environment.
The end of the installation phase should generate a
pango.modules configuration file in /etc and
this is problematic because the modules are SH4 binaries and the Intel
version of pango-querymodules may have problems with them or
generate wrong data. Some more info on this file would be appreciated.
When is it needed? If only at runtime then it's OK to install it only in
/devkit/sh4/target/etc while if it is needed at compile time as well, then
it must be installed somewhere else too (probably with paths changed).
We need this package because of two utilities that are needed while
building the SH version: gtk-query-immodules-2.0 and
gdk-pixbuf-csource.
Building a standard version of GTK2 for the host (i386) would also need
all its dependencies (Glib, Freetype, Pango and maybe Atk) for the same
host. Therefore I decided to compile the minimum amount of code needed to
link those applications. In the end the files needed are just a few and a
standard installation would have been a waste of resources.
The best example of this is the gtk-query-immodules-2.0
command that because of a single generic function
(pango_split_file_list()) located in the pango library, would
then need the whole library leading to the usual chain of dependencies for
just a single function.
I solved this problem by importing from Pango the source file
containing the function (pango_utils.c) using a patch file
and modifying some GTK files to satisfy the needs of that function. The
gtk-query-immodules-2.0 command is then build using a single
gcc invocation and without any dependency apart from Glib.
To build gdk-pixbuf-csource we first need the
gdk-pixbuf library and the image loaders needed by it. Again
we do this manually because the standard makefile pulls in many
unneeded libraries as dependencies of gdk-pixbuf.
This is the main library. We have worked hard to get to this one.
This was so messy that in the end the only option available was to
rewrite from scratch the build system.
I started trying to run configure in cross compilation mode. After
setting the following environment variables
export PKG_CONFIG_PATH="/opt/STM/ST40Linux-1.0/devkit/sh4/lib/pkgconfig"
export FREETYPE_CONFIG="/opt/STM/ST40Linux-1.0/devkit/sh4/bin/sh4-linux-freetype-config"
export GDK_PIXBUF_CSOURCE="/opt/STM/ST40Linux-1.0/host/bin/target-gdk-pixbuf-csource"
export GLIB_MKENUMS="/opt/STM/ST40Linux-1.0/host/bin/target-glib-mkenums"
export GLIB_GENMARSHAL="/opt/STM/ST40Linux-1.0/host/bin/target-glib-genmarshal"
export GOBJECT_QUERY="/opt/STM/ST40Linux-1.0/host/bin/target-gobject-query"
|
|
|
I could run configure:
./configure --host="%{_stm_target_config}" --build="%{_stm_host_config}" \
--prefix="%{_stm_target_prefix}" --exec-prefix="%{_stm_target_exec_prefix}" \
--sysconfdir="%{_stm_target_sysconf_dir}" --localstatedir="%{_stm_target_localstate_dir}" \
--sharedstatedir="%{_stm_target_sharedstate_dir}" --mandir="%{_stm_target_man_dir}" \
--infodir="%{_stm_target_info_dir}" --cache-file="config.cache" \
--disable-gtk-doc --disable-glibtest --enable-debug="minimum" \
--with-gdktarget="x11" --x-libraries="%{_stm_cross_x_dir}/lib" \
--x-includes="%{_stm_cross_x_dir}/include"
|
|
|
Typing make now doesn't work. Again because of libtool and the absolute
paths embedded in its code. While building the jpeg loader I got this
error:
... lots of output ...
/bin/sh ../libtool --mode=link sh4-linux-gcc -O2 -Wall -o libpixbufloader-jpeg.la \
-rpath /usr/lib/gtk-2.0/2.0.0/loaders \
-avoid-version -module io-jpeg.lo -ljpeg libgdk_pixbuf-2.0.la -Wl,--export-dynamic \
-L/opt/STM/ST40Linux-1.0/devkit/sh4/lib -lgmodule-2.0 -ldl -lgobject-2.0 -lglib-2.0 -lm
rm -fr .libs/libpixbufloader-jpeg.la .libs/libpixbufloader-jpeg.* .libs/libpixbufloader-jpeg.*
(cd . && ln -s io-jpeg.lo io-jpeg.o)
sh4-linux-gcc -shared io-jpeg.lo \
-Wl,--rpath -Wl,/home/chinstrap/users/acister/work/packages/BUILD/gtk+-2.0.5/gdk-pixbuf/.libs \
-Wl,--rpath -Wl,/opt/STM/ST40Linux-1.0/devkit/sh4/lib \
-Wl,--rpath -Wl,/opt/STM/ST40Linux-1.0/devkit/sh4/lib \
-L/opt/STM/ST40Linux-1.0/devkit/sh4/lib /usr/lib/libjpeg.so ./.libs/libgdk_pixbuf-2.0.so \
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/libgmodule-2.0.so -ldl \
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/libgobject-2.0.so \
/opt/STM/ST40Linux-1.0/devkit/sh4/lib/libglib-2.0.so -lm \
-Wl,--export-dynamic -Wl,-soname -Wl,libpixbufloader-jpeg.so \
-o .libs/libpixbufloader-jpeg.so
/usr/lib/libjpeg.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
make[3]: *** [libpixbufloader-jpeg.la] Error 1
make[3]: Leaving directory `/home/chinstrap/users/acister/work/packages/BUILD/gtk+-2.0.5/gdk-pixbuf'
...
|
|
|
I tried several solutions to this problem but each one ended up in
creating some more problems. Given that we don't need some of the
components that are built by a standard compilation, I decided to rewrite
the complete build system from scratch using shell scripts instead of
Makefiles.
Using the captured output of a local build as reference, I wrote a
number of shell scripts, one for each directory where something needed to
be built, that take care of building each original target. As all the
build instructions are contained in a set of sh4-build.sh
scripts that are added to the source tree, the spec file is deceptively
simple.
Installation is managed by a similar set of scripts named
sh4-install.sh. These scripts are run in the directories
containing the needed files and take care of moving everything in the right
place.
Using shell scripts instead of Makefile may seem less flexible but we
must consider that package building is quite different from normal
development. The whole system is meant to compile a fixed set of sources in
one go with no interation or modification from the developer.
Maybe put here issues with the autotools????
IS THIS THE RIGHT PLACE?
Almost all the problems encountered during this quest came from the four
tools that are supposed to make the developers' life easier: autoconf,
automake, libtool and pkg-config.
Here is a more detailed description af the issues I had with these tools
when trying to cross compile GTK2.
Autoconf (and and the configure script)
-
The use of
AC_TRY_RUN macros in configure.in simply
forbids cross-compilation because the executable produced by the
compiler for the test is for a different architecture (the target's
one). AC_TRY_RUN should be avoided or, at least, a chance
should be given of overriding the values it is needed for.
The solution I've found to solve this problem is described in the
GLib 2 for the target section.
-
The
configure script generates the pkg-config files at the
end of the configuration phase ignoring a possible definition of the
make variable translate at install time. This variable can be
used to change the name of the executables at install time, e.g. adding
a common prefix.
Ignoring the definition of this variable lead to wrong program names
being written in these files. E.g. gcc insted of
sh4-linux-gcc
Libtool
This is the program that gave me more problems than all the others
together. I still can't believe that a simpler solution, or at least one
that can be overridden, to the shared libraries problem can't be found. I'm
particularly worried by the incredible complexity of this tool added by the
number of supported architectures when most of the times only a handful of
them are really useful.
Here are the main griefs I had with libtool:
Automake
- The glib-mkenums program name is hard-coded in Makefiles.am, why? The
macro
@GLIB_MKENUMS@ is available for substitution in
configure and could be used by setting the environment variable with the
same name.
Aclocal
- The --print-ac-dir option should print all directories including the
versioned one.
- The -I option can't really be used to add directories to the search
path because if a macro is defined in two places we get a "duplicate
macro" error message. (E.g. GLIB2 both on the host and in our
distro.)
- The version number should be accessible alone and in a more standard
format.
|