logo Autopackage - Easy Linux Software Installation

APBuild >> apgcc

  1. What is apgcc?
  2. Using apgcc
  3. The C++ ABI problem and how to solve it

What is apgcc?

Apgcc is a wrapper around gcc. It allows you to create more portable executables by doing three things:

How to use apgcc

Use apgcc just like how you use gcc. Examples:

IMPORTANT: Read about The C++ ABI Problem if you intend to compile C++ applications!

There are several environment variables that change apgcc's behavior:

APBUILD_PATH
Use this as the include dir for the apgcc headers. Default value: $PREFIX/include/apbuild (where $PREFIX is the prefix in which apbuild is installed)
APBUILD_CC
Use the specified C compiler. Default value: gcc
APBUILD_CXX1
Use the specified C++ compiler. Default value: g++

Read The C++ ABI Problem for more information.

APBUILD_STATIC_X
(from autopackage 1.3) If set to 1, then apbuild's old behavior of statically linking some X extension libraries.
APBUILD_NO_STATIC_X
(deprecated in autopackage 1.3, where this is now the default) If set to 1, do not force static linking to some X extension libraries.
APBUILD_BOGUS_DEPS
Specify a list of whitespace-seperated bogus library dependancies (like: X11 ICE png). These libraries will not be linked against. This option is useful if you want to specify bogus dependancies manually because the automatic bogus dependancy stripper doesn't work correctly for your project (see below).
APBUILD_DISABLE_BOGUS_DETECTOR
If set to 1, disables the automatic bogus dependancy stripper. This is useful when linking to libraries don't have correct DT_NEEDED entries, like GTK 1.2. GTK 1.2 uses libX11.so internally, but it's not linked with -lX11. Instead, gtk-config --libs returns -lgtk -lX11 or something. If your app doesn't use xlib internally, then our bogus dependancy stripper will strip the -lX11 argument. Linking will then fail.

The built-in bogus dependancy stripper is not used if you have a recent version of binutils, which supports ld --as-needed (it'll use binutil's native support for bogus dependancy stripping instead). So you should get use a recent version of binutils if your ld doesn't already support that argument.

APBUILD_NOT_BOGUS
If you want to use the automatic bogus dependancy dectector anyway (using ld --asneeded), then you can specify a list of dependancies here that are not bogus with this environment variable. Example:
export APBUILD_NOT_BOGUS="X11 ICE png"
APBUILD_STATIC
Specify a list of whitespace-seperated libraries to statically link to (like: popt z). You can also explicitly specify a filename to the static library. Examples:
export APBUILD_STATIC="popt z"
export APBUILD_STATIC="popt=/usr/lib/libpopt.a"
APBUILD_STATIC_LIBGCC
If set to 1, link all binaries with -static-libgcc. See the gcc info page for more info about this option.
APBUILD_PROJECTNAME
If non-empty, apgcc will add $ORIGIN/../lib/$APBUILD_PROJECTNAME to the library search path.
APBUILD_INCLUDE
Prepend the specified directory to the compiler's header search path. The compiler will search this directory first, before searching any other directory. This is useful in combination with the older GTK headers package (see the autopackage website). You can specify multiple directories, seperated by a ':', just like the $PATH environment variable. If the order of the -I flags is important for your application, you can replace paths by using /old/path=/new/path.
APBUILD_RESOLVE_LIBPATH
A space-seperated list of (Perl) regular expressions which specify the libraries whose path must be resolved into absolute paths.

Internally, apgcc reorders the linking arguments that are to be passed to gcc (for various reasons). This can cause problems when linking certain static libraries (for example, static WxWidgets libraries). But that can be worked around by using full path names for static libraries (e.g. turning '-lfoo' parameters into /usr/lib/full-path-to/foo.a).

The C++ ABI Problem

Introduction

GCC 2.95, 2.96, 3.0, 3.1.1, 3.2 and 3.4 generate different a ABI (Application Binary Interface) for C++ binaries. This means that a C++ program compiled with GCC 3.0 won't be able to link to a library compiled with GCC 3.2. One can only hope that the GCC team won't break C++ ABI again in the future.

Luckily, practically nobody (well... no desktop Linux users) uses pre-GCC 3.2 systems anymore, so that only leaves us with the difference between GCC 3.2 and 3.4 (for your information: GCC 3.3 is compatible with 3.2, and 4.0 is compatible with 3.4). Furthermore, GCC 3.4 is able to generate binaries with the GCC 3.2 ABI using a compiler switch. "ABI 1" is the ABI that first appeared in GCC 3.2. "ABI 2" is the ABI that first appeared in GCC 3.4.

Autopackage can work around the C++ ABI problem by compiling C++ source code twice, with different ABIs. makepackage runs the [BuildPrepare] section two times. The first time, the files are compiled with g++-3.2/3.3, the second time with g++-3.4/4.0. The, binary diffs are created from the files and the binary compiled with the ABI correct for the system is installed.

I call this technique "double compiling". This, of course, makes compilation twice as slow.

See also the Wiki for about how to integrate double compiling in your build process.
Tip: It might be useful to set CXX1/2 in your .bashrc so you don't have to type them over and over again.