Introduction
NOTE: this is a very brief introduction. For more detailed information, see the apgcc documentation.
One of the problems with C++ binaries is the fluctuating Application Binary Interface (ABI). GCC 3.4 broke C++ ABI (again), so C++ software compiled with GCC 3.4 can mysteriously crash (or not run at all) on GCC 3.2/3.3 systems, and vice versa. Especially C++ programs that use large C++ dependencies (such as all Qt/KDE software!) suffer from this program.
Solution
As of autopackage 1.2, we have a solution for this: double compiling and automatic ABI selection. Here is a global overview of how it works:
- You must have both GCC 3.2/3.3 and GCC 3.4 (or later) installed.
- Your specfile's AutopackageTarget must be set to 1.2.
- APBuild (version 2.0 and later) will automatically compile your C++ source files twice, using both compilers, therebefore generating two executables (with two ABIs).
- Import both kind of executables into the package (they must be inside the same folder in the package).
- When the user installs a .package, autopackage will automatically detect the system's ABI, select the C++ binaries with the correct ABI, and install those.
Binary deltas are used to keep package sizes as small as possible. Most packages won't suffer a large size increase due to this double compiling as the ABI differences between 3.2 and 3.4 are minimal.
Setting up APBuild for double compiling
First you must set a few environment variables so APBuild knows what compiler is GCC 3.2 and what compiler is GCC 3.4 (or later). You can do this by setting APBUILD_CC to the command for gcc 3.2, CXX1 to the command for g++ 3.2/3.3, and CXX2 to the command for g++ 3.4+. For example (for Fedora Core 4):
export APBUILD_CC=gcc32 export CXX1=g++32 export CXX2=g++34
Tip: It might be useful to set CXX1 and CXX2 in your ~/.bashrc file so you don't have to type them over and over again.
It could also be useful to put the following code in the [BuildPrepare] section of your specfile, so that you won't forget to set those variables when you create your package:
if [[ "$CXX2" == "" ]]; then
red
echo "\$CXX2 is not set. apgcc double compiling must be enabled."
normal
exit 1
fi
Now, when makeinstaller is run, it will execute the [BuildPrepare] twice--once using CXX1 and then again using CXX2. At the end, all the binaries are compared, and a binary diff file is included containing the differences between the files. At install time, the correct binary for the system is patched and installed.
Instructions for projects that use prepareBuild
If your project uses prepareBuild in your [BuildPrepare] section of the specfile, then here are the things you have to do:
- Set the APBuild environment variables, as instructed above.
- Bump AutopackageTarget to 1.2.
- Re-create the package.
And that's all. prepareBuild and makeinstaller take care of most of the magic.
Instructions for non-prepareBuild projects
Non-prepareBuild() (autotools) projects will have to clean their build directory manually and use the $APBUILD_CXX1 to compile C++ files.
- Set the APBuild environment variables, as instructed above.
- Bump AutopackageTarget to 1.2.
- You must copy/install the compiled files into $build_root so Autopackage can find them.
- Run the equivalent of make clean at the beginning of [BuildPrepare] to clean up any object files that were compiled using the other C++ compiler.
- Use the apg++ command to compile C++ files (or, if you can't use apg++, compile using the value of the $APBUILD_CXX1 variable.
Example
An example project from autopackage.org that demonstrates the C++ feature is the Visual Dependency Walker application.
