New LFS Hint: gcc_multiple_versions

Cort Tompkins rtompkin at cs.odu.edu
Tue Jul 31 18:38:34 PDT 2001


Hello all,

I've put together a hint for very easily changing between GCC versions.  I 
think you'll find it representative of a fundamental misunderstanding of the 
how GCC and its associated files work.  Seriously though, 'gcc -V' does not 
work well (or at all) for this kind of thing.  The GCC FAQ recommends two 
solutions for using concurrent GCC versions so I've taken one of the 
suggestions and clarified, simplified, and automated it.  Please let me know 
what you think.

Thanks,
Cort Tompkins

--

TITLE:		GCC Multiple Versions
LFS VERSION:	All
AUTHOR:		R. Cortland Tompkins <rtompkin at cs.odu.edu>

SYNOPSIS:
	How to install multiple versions of GCC with a simple method of 
	switching between them.

HINT:
version 1.0 (7/31/01)

	Disclaimer:  This hint has yet to be extensively tested.

TABLE OF CONTENTS:
------------------
1) Introduction
2) Methodology
3) Installation
   3.1) Install GCC versions
   3.2) Remove old binaries and libraries
   3.3) Manually create gcc-swap infrastructure
4) swap-gcc script
5) Conclusion


1) Introduction:
----------------
As of this writing, LFS is beginning to move towards the relatively new GCC 
version 3.0.  Unfortunately, there are still many software packages that will 
not compile with GCC 3.0; KDE maintainers advise against compiling current
versions of KDE with GCC 3.0.  The GCC FAQ suggests two methods for achieving
concurrent GCC versions, one of which simply doesn't work and the other of 
which is the basis for this hint.  The method suggested here will allow you
to install an unlimited number of GCC versions and change between them with
a single command.

2) Methodology:
---------------
An easy way to install multiple versions of the compiler on the same system is
to configure the two compilers with different paths.  We will use a shell
script to create and remove symlinks from the various compilers' individual
directories to a common directory, such as /usr/bin.  By maintaining the
traditional binaries' names and paths ('/usr/bin/gcc' instead of 
'/usr/bin/gcc-VERSION' or '/usr/gcc-VERSION/bin/gcc'), we can eliminate much 
of the fuss of dealing with multiple compilers.

3) Installation:
----------------

3.1) Install GCC versions:
--------------------------
You'll need to be super-user to complete this hint.  First, create the
directory which will be home to the various GCC versions.  I recommend 
/usr/local/gcc:

	mkdir /usr/local/gcc

Next, compile GCC just as you did when creating your LFS system, but modify
the prefix path:

	mkdir ../gcc-build &&
	cd ../gcc-build &&
	../gcc-VERSION/configure --prefix=/usr/local/gcc/VERSION \
	--with-slibdir=/lib --enable-shared &&
	make bootstrap &&
	make install

Repeat the above procedure for all versions of GCC you wish to install,
substituting the VERSION number where indicated (such that GCC 3.0 will be 
installed in /usr/local/gcc/3.0).  You must repeat the above procedure even 
for the GCC version that is already installed (but specifying the new 
prefix, of course).  For instance, if I currently had gcc-2.95.2.1 installed
and wanted gcc-3.0 as well, I would compile gcc-2.95.2.1 (again) 
with-prefix=/usr/local/gcc/2.95.2.1 as well as compile gcc-3.0 
with-prefix=/usr/local/gcc/3.0

3.2) Remove old binaries and libraries:
---------------------------------------
The GCC-related binaries and libraries will reside exclusively in 
/usr/local/gcc/VERSION/, therefore we can delete the libraries and
binaries originally installed in /usr.  First however, you should edit
/etc/ld.so.conf to include the ./lib directories of each gcc version,
replacing VERSION as appropriate:

	echo /usr/local/gcc/VERSION/lib >> /etc/ld.so.conf

Repeat the above command for each VERSION of GCC installed.  Enact these
changes by running ldconfig:

	/sbin/ldconfig -v

Verify that the shared libraries in the various /usr/local/gcc/VERSION/lib
directories appear in ldconfig's output.  Next, from the bash prompt,
execute the following command to delete your original GCC installations'
binaries from /usr/bin, substituting the version of GCC you installed with the
original LFS instructions with VERSION (i.e. 2.95.2.1 for LFS-3.0pre4):

	for GCC_BINARY in $(/bin/ls --color=no /usr/local/gcc/VERSION/bin)
	> do
	> /bin/rm -f /usr/bin/$GCC_BINARY
	> done

Next, we'll remove your original GCC installation's libraries from /usr/lib in
the same way.  Substitute the version of your original GCC installation in
place of VERSION.

	for GCC_LIBRARY in $(/bin/ls --color=no /usr/local/gcc/VERSION/lib)
	> do
	> /bin/rm -f /usr/lib/$GCC_LIBRARY
	> done

You may also remove your old installation's gcc-lib directory:

	rm -rf /usr/lib/gcc-lib

You have nothing to fear when deleting these formerly important files. All of
the required binaries and libraries now reside in each respective 
/usr/local/gcc/VERSION directory.  As long as you remebered to add the
required entries to /etc/ld.co.conf, you're good to go.

3.3) Manually create gcc-swap infrastructure:
---------------------------------------------
We will be using a script called swap-gcc to change between GCC versions, but
this script relies on a few files and locations that must be set up manually
before it is run.  First we'll create the symbolic links from your original
GCC version (i.e. 2.95.2.1 for LFS-3.0pre4) to /usr/bin:

	for GCC_BINARY in $(/bin/ls --color=no /usr/local/gcc/VERSION/bin)
	> do
	> /bin/ln -sf /usr/local/gcc/VERSION/bin/$GCC_BINARY \
	> /usr/bin/$GCC_BINARY
	> done

swap-gcc relies on a file /usr/local/gcc/.active to figure out which GCC
version is currently active.  Create it using the following command,
substituting the same GCC version number you used above (your original GCC 
version) with VERSION:

	echo "ACTIVE=VERSION" > /usr/local/gcc/.active

4) swap-gcc:
------------
The swap-gcc script allows you to change the current GCC version with a single
command.  Its contents is as follows:
---- Begin copy here ----
#!/bin/bash
# Begin /usr/bin/swap-gcc

# Source the file containing the version of active GCC
. /usr/local/gcc/.active

# Verify that the given parameter is a valid (i.e. installed) GCC version
if [ -d /usr/local/gcc/"$1" ] && [ "$1" != "" ]; then
	# For every file in the current GCC version's bin directory...
	for GCC_OLD_BINARY in $(/bin/ls --color=no /usr/local/gcc/$ACTIVE/bin)
	do
		# Delete its symlinks in /usr/bin
		/bin/rm -f /usr/bin/$GCC_OLD_BINARY
	done
	# For every file in the new GCC version's bin directory...	
	for GCC_NEW_BINARY in $(/bin/ls --color=no /usr/local/gcc/$1/bin)
	do
		# Make a symlink to the new version in /usr/bin
		/bin/ln -sf /usr/local/gcc/$1/bin/$GCC_NEW_BINARY \
		/usr/bin/$GCC_NEW_BINARY
	done

	# Update with the current GCC version
	echo "ACTIVE=$1" > /usr/local/gcc/.active
	echo "Changed from GCC version $ACTIVE to GCC version $1"
else
	echo Usage: swap-gcc gcc-version
	echo " Current GCC version: $ACTIVE"
	echo -n " Available GCC versions: "
	# This should return all available GCC versions if set up properly
	for DIRNAME in $(ls /usr/local/gcc)
	do
		echo -n "$DIRNAME "
	done
fi
# End /usr/bin/swap-gcc
---- End copy here ----

Put the above script in /usr/bin.  Make it executable:

	chmod 0755 /usr/bin/swap-gcc

Now run swap-gcc with no arguments:

	/usr/bin/swap-gcc

You will see the currently active GCC version as well as the other available
gcc versions.  You can verify the active GCC version by running 'gcc -v'.  To
change the active GCC version simply use the following command, substituting
VERSION with the GCC version you want to become active:

	/usr/bin/swap-gcc VERSION

Obviously only root will be able to change the GCC version successfully,
although I suppose you could do some fancy things with groups and permissions
to allow other users to, as well.

When it comes time to install another compiler (GCC 3.1, for example),
simply configure it with-prefix=/usr/local/gcc/3.1 and swap-gcc will require
no changes to work with the new compiler.

5. Conclusion:
--------------
While I have used the above method to great success by compiling my LFS base
system with GCC 3.0 and reverting to GCC 2.95.3 to compile KDE 2.1.1, your
mileage will almost certainly vary.  If you have any insights or suggestions
for this hint, please contact me at rtompkin at cs.odu.edu.

Enjoy!




More information about the hints mailing list