Whole document tree

Whole document tree

GCC installation and setup

GCC installation and setup

GCC versions

You can find out what GCC version you're running by typing gcc -v at the shell prompt. This is also a fairly reliable way to find out whether you are set up for ELF or a.out. On my system it does

$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
gcc version 2.7.2

The key things to note here are

  • i486. This indicates that the gcc you are using was built for a 486 processor --- you might have 386 or 586 instead. All of these chips can run code compiled for each of the others; the difference is that the 486 code has added padding in some places so runs faster on a 486. This has no detrimental performance effect on a 386, but does make the binaries slightly larger.

  • box. This is not at all important, and may say something else (such as slackware or debian) or nothing at all (so that the complete directory name is i486-linux). If you build your own gcc, you can set this at build time for cosmetic effect. Just like I did :-)

  • linux. This may instead say linuxelf or linuxaout, and, confusingly, the meaning of each varies according to the version that you are using.

    • linux means ELF if the version is 2.7.0 or newer, a.out otherwise.

    • linuxaout means a.out. It was introduced as a target when the definition of linux was changed from a.out to ELF, so you won't see any linuxaout gcc older than 2.7.0.

    • linuxelf is obsolete. It is generally a version of gcc 2.6.3 set to produce ELF executables. Note that gcc 2.6.3 has known bugs when producing code for ELF --- an upgrade is advisable.

  • 2.7.2 is the version number.

So, in summary, I have gcc 2.7.2 producing ELF code. Quelle surprise.

Where did it go?

If you installed gcc without watching, or if you got it as part of a distribution, you may like to find out where it lives in the filesystem. The key bits are

  • /usr/lib/gcc-lib/target/version/ (and subdirectories) is where most of the compiler lives. This includes the executable programs that do actual compiling, and some version-specific libraries and include files.

  • /usr/bin/gcc is the compiler driver --- the bit that you can actually run from the command line. This can be used with multiple versions of gcc provided that you have multiple compiler directories (as above) installed. To find out the default version it will use, type gcc -v. To force it to another version, type gcc -V version. For example
    # gcc -v
    Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
    gcc version 2.7.2
    # gcc -V 2.6.3 -v
    Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.6.3/specs
    gcc driver version 2.7.2 executing gcc version 2.6.3

  • /usr/target/(bin|lib|include)/. If you have multiple targets installed (for example, a.out and elf, or a cross-compiler of some sort, the libraries, binutils (as, ld and so on) and header files for the non-native target(s) can be found here. Even if you only have one kind of gcc installed you might find anyway that various bits for it are kept here. If not, they're in /usr/(bin|lib|include).

  • /lib/,/usr/lib and others are library directories for the native system. You will also need /lib/cpp for many applications (X makes quite a lot of use of it) --- either copy it from /usr/lib/gcc-lib/target/version/ or make a symlink pointing there.

Where are the header files?

Apart from whatever you install yourself under /usr/local/include, there are three main sources of header files in Linux:

  • Most of /usr/include/ and its subdirectories are supplied with the libc binary package from H J Lu. I say `most' because you may also have files from other sources (curses and dbm libraries, for example) in here, especially if you are using the newest libc distribution (which doesn't come with curses or dbm, unlike the older ones).

  • /usr/include/linux and /usr/include/asm (for the files <linux/*.h> and <asm/*.h>) should be symbolic links to the directories linux/include/linux and linux/include/asm in the kernel source distribution. You need to install these if you plan to do any non-trivial development; they are not just there for compiling the kernel. You might find also that you need to do make config in the kernel directory after unpacking the sources. Many files depend on <linux/autoconf.h> which otherwise may not exist, and in some kernel versions asm is a symbolic link itself and only created at make config time. So, if you unpack your kernel sources under /usr/src/linux, that's
    $ cd /usr/src/linux
    $ su
    # make config
    [answer the questions.  Unless you're going to go on and build the kernel
    it doesn't matter _too_ much what you say]
    # cd /usr/include
    # ln -s ../src/linux/include/linux .
    # ln -s ../src/linux/include/asm .

  • Files such as <float.h>, <limits.h>, <varargs.h>, <stdarg.h> and <stddef.h> vary according to the compiler version, so are found in /usr/lib/gcc-lib/i486-box-linux/2.7.2/include/ and places of that ilk.

Building cross compilers

Linux as the target platform

Assuming you have obtained the source code to gcc, usually you can just follow the instructions given in the INSTALL file for GCC. A configure --target=i486-linux --host=XXX on platform XXX followed by a make should do the trick. Note that you will need the Linux includes, the kernel includes, and also to build the cross assembler and cross linker from the sources in .

Linux as the source platform, MSDOS as the target

Ugh. Apparently this is somewhat possible by using the "emx" package or the "go" extender. Please look at .

I have not tested this and cannot vouch for its abilities.