May 12
Building Older GCC Versions on x86-64 Debian/Ubuntu: Redux

After 2+ years running Lucid Lynx I decided to upgrade to a recent version of Ubuntu, Oneiric Ocelot. I tend to stay behind the curve a bit to give early adopters the opportunity to work out most of the kinks. In the past I have been burned in my haste to stay on the bleeding edge. Being 1-2 versions behind seems to work well to avoid any potential issues. Upgrading to Oneiric was mostly uneventful and I didn’t notice any compatibility issues until I tried building some code against an older version of GCC I previously built in Lucid. I encountered the following error anytime I tried to compile using the -m64 flag:

/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
collect2: ld returned 1 exit status

It turns out that recent Debian releases and their derivatives have transitioned to multiarch support. The idea is to allow seamless support of binaries built for different architectures, related or not, to live concurrently on the same system. In theory it should be more portable than the lib32/lib64 conventions of the past. Unfortunately, the side effect is that some applications depending on the old paths are now woefully broken. The good news is a simple workaround will allow older GCC versions to build without issue. Building an older version of GCC is still straightforward when following the instructions in my previous post, applying the necessary patches and running the following command to fix-up the compiler paths:

sed -i 's|\.\./lib64|x86_64-linux-gnu|' gcc-<version>/gcc/config/i386/t-linux64

For example, the following will build and install GCC 4.7.0 from source to a custom prefix:

tar xzf gcc-4.7.0.tar.gz
sed -i 's|\.\./lib64|x86_64-linux-gnu|' gcc-4.7.0/gcc/config/i386/t-linux64
mkdir ../gcc-4.7.0-objdir
cd ../gcc-4.7.0-objdir
../gcc-4.7.0/configure --prefix=/opt/x86_64/gcc/gcc-4.7.0 --enable-languages=c,c++
make install

Voila! Older GCC versions should now build and compile applications without issue.


  1. RafaelMartins

    Trevor, I’m reproducing your trip down compiler-memory-lane and the above sed line works perfectly down to 3.1.1; on that version it fails because the variable you’re changing (MULTILIB_OSDIRNAMES) is not present. Adding the variable didn’t work for me. The only solution I found was to symlink /usr/lib64 to /usr/lib/x86_64-linux-gnu.

    Thanks for these two posts, they’re life savers!

  2. @Rafael: Glad you enjoyed both posts. You are correct that the variable doesn’t exist in versions prior to 3.2.x. It is likely due to the 3.1.x series first introducing x86_64 support. You could try the following sed command for 3.1.1, although, I haven’t tested it so your mileage may vary.

    sed -i 's|/usr/lib64/||' gcc-3.1.1/gcc/config/i386/linux64.h

    If you take a look at the header file in question you will notice that for !m32 support it hard codes the path prefix for the crt*.o objects to /usr/lib64. The linker should be smart enough to find the correct location, so removing the path prefix should suffice. Hope that helps!

  3. RafaelMartins

    Thanks, it worked. I’ve got a new problem, though; it’s actually the same problem from the last comment on your previous post. GCC 2.95.3 built fine, but when using it to compile anything, it gives the following error:

    /usr/bin/ld: crt1.o: No such file: No such file or directory
    collect2: ld returned 1 exit status

    The file “crt1.o” is in /usr/lib, and GCC 3/4 versions work fine in the same system.

    Any ideas?

  4. RafaelMartins

    Ok, I solved it. My mistake was to use your instructions without change on a 32-bit chroot. So with “gcc-2.95.3 -print-search-dirs” I realized that it was searching on “/usr/lib32″, which works fine on Debian 64, but not on 32. So I temporarily symlinked “/usr/lib32″ to “/usr/lib” and it’s working now. Later I’ll review your 2.95.3 patch and fix it to work in a 32-bit environment.

  5. @Rafael: Thanks for taking some time to work through the potential issues. FWIW, I haven’t totally vetted the steps from both posts to see if they still apply on multiarch releases. If you have any revised steps, feel free to pass them along and I will revise the posts with the pertinent information.

  6. Hello,
    I’m failing to install gcc-4.7.0 in a 32 bit:
    2.6.9-55.0.9.ELsmp #1 SMP Tue Sep 25 02:17:24 EDT 2007 i686 i686 i386 GNU/Linux
    Config goes ok, apparently.
    I put mpfr mpc and bmp inside the /opt/gcc-4.7.0 dir, to build them together

    I get an error like this:

    /opt/gcc-build/./mpc/src/.libs/libmpc.a(tan.o)(.text+0x7f0):../../../gcc-4.7.0/mpc/src/tan.c:218: undefined reference to `mpfr_set_erangeflag’
    collect2: ld returned 1 exit status
    make[2]: *** [cc1] Error 1
    make[2]: Leaving directory `/opt/gcc-build/gcc’
    make[1]: *** [all-gcc] Error 2
    make[1]: Leaving directory `/opt/gcc-build’
    make: *** [all] Error 2

    Could I have some help?

Leave a comment