views:

470

answers:

4

I'd like to set up a cross-compilation environment on a Ubuntu 9.10 box. From the documents I've read so far (these ones, for example) this involves compiling the toolchain of the target platforms.

My question is: how do you determine the required version of each of the packages in the toolchain for a specific target platform? Is there any rule of thumb I can follow?

This is a list found in one of the websites linked above:

binutils-2.16.1.tar.bz2
linux-2.6.20.1.tar.bz2
glibc-2.5.tar.bz2
glibc-linuxthreads-2.5.tar.bz2
gcc-core-4.2.0.tar.bz2
gcc-g++-4.2.0.tar.bz2

But suppose I want to generate executables for standard Ubuntu 8.04 and CentOS 5.3 boxes. What are the necessary packages?

My primary need is to avoid errors like "/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found" in the customers' machines but in the future I want to deal with different architectures as well.

+1  A: 

Compiling for other Linux distributions is easiest by installing them in virtual machines (apt-get install kvm) and then doing the compilation from within. You can also script them to do it automatically. Building a cross-compiler and providing the exact same versions of all libraries and such, as the other Linux distro does, is nearly impossible.

Tronic
Building a chroot for the target distributions is an alternative plan, lighter weight but may not be as straightforward depending on the distributions involved. The debootstrap utility will assist greatly in the Debian/Ubuntu world.
crazyscot
A: 

Depending on your target platforms, have you considered using Optware?

I'm currently working on getting Mono and Moonlight built for my Palm Pre using the cross-compilation toolchain (and the Optware makefiles handle the majority of dependencies already).

Justin Niessner
A: 

It is generally a good idea to build a cross-toolchain that uses the same version of libc (and other libraries) found on the target system. This is especially important in the case of libraries that use versioned symbols or you could wind up with errors like "/usr/lib/libstdc++.so.6: version 'GLIBCXX_3.4.11' not found".

Same Architecture

For generating executables for standard Ubuntu 8.04 and CentOS 5.3 systems, you could install the distributions in virtual machines and do the necessary compilation from within the virtual machine to guarantee the resulting binaries are compatible with the library versions from each distribution.

Another option would be to setup chroot build environments instead of virtual machines for the target distributions.

You could also build toolchains targeted at different environments (different library versions) and build under your Ubuntu 9.10 environment without using virtual machines or chroot environments. I have used Dan Kegel's crosstool for creating such cross-toolchains.

Different Architecture

As I noted in my answer to a another cross-compiler question, I used Dan Kegel's crosstool for creating my arm cross-toolchain.

It appears it may be slightly out of date, but there is a matrix of build results for various architectures to help determine a suitable combination of gcc, glibc, binutils, and linux kernel headers.

Required Package Versions

In my experience, there really isn't a rule of thumb. Not all combinations of gcc, binutils, glibc, and linux headers will build successfully. Even if the build completes, some level of testing is necessary to validate the build's success. This is sometimes done by compiling the Linux kernel with your new cross-toolchain. Depending on the target system and architecture, some patching of the source may be necessary to produce a successful build.


Since you are setting up this cross-compilation environment on Ubuntu 9.10, you might want to look into the dpkg-cross package.

jschmier
A: 

My question is: how do you determine the required version of each of the packages in the toolchain for a specific target platform? ... binutils-2.16.1.tar.bz2 gcc-core-4.2.0.tar.bz2 gcc-g++-4.2.0.tar.bz2

Generally pick the latest stable: these only affect your local toolchain, not runtime.

linux-2.6.20.1.tar.bz2

You don't need this. (For targeting embedded platforms you might use it.)

glibc-2.5.tar.bz2 glibc-linuxthreads-2.5.tar.bz2

You don't need these. I.e. you should not download them or build them; you should link against the versions from the oldest distro you want to support.

Is there any rule of thumb I can follow? But suppose I want to generate executables for standard Ubuntu 8.04 and CentOS 5.3 boxes. What are the necessary packages?

You survey the distros you want to target, find the lowest common denominator versions of of libc, libstdc++, pthreads, and any other shared library you will link with, then copy these libs and corresponding headers from the box that has these LCD versions to your toolchain.

Nathan Kidd
While a good idea in theory, linking against the lowest common denominator library versions *may not* always work. Sometimes symbols that were public in older library versions become private in later versions (i.e. `__libc_stack_end`).
jschmier
My years of experience suggest it's a good idea in practice too. An isolated PPC-only issue like __libc_stack_end is a reason to sanity check your results, not something to base your process on.
Nathan Kidd
While this is an isolated issue, it is not PPC only. The symbol simply wasn't exported anymore anyone using it had to adapt their code. I agree that a process should not necessarily be dictated by the exception case, but you should be aware of the possibility of the exception.
jschmier