An beginners guide to compiling programs under Linux.

Kim Oldfield

Presented to Linux Users of Victoria

This talk is a hands on guide for someone who has never compiled a program under linux before, or someone who has never tried to compile a package from source.

  1. Compiling a simple C program
  2. Compiling a package from source
  3. Compiling your first Linux kernel

Compiling a simple C program.

What you need

Debian packages: gcc, cpp, binutils, libc-dev. C++ programs also require: g++, and libstdc++

RedHat packages: egcs, cpp, binutils, glibc-devel. C++ programs also require: egcs-c++, libstdc++.

gcc and egcs

gcc is the standard Linux compiler, 2.7.2 is the latest stable version.

egcs is a breakaway development of gcc. This has since been renamed to gcc.

From /usr/doc/gcc/README.Debian.gz in gcc-2.95.2-0pre2:

As of gcc-2.95, optimisation at level 2 (-O2) and higher includes an optimisation which breaks C code that does not adhere to the C standard. Such code occurs in the Linux kernel, and probably other places.

There are a couple of 272 packages for Debian potato (unstable) to get around this - gcc272, gcc++272.

The program

/* hello.c */
#include <stdio.h>
int main(int argc, char *argv[])
    if (argc > 1)
	printf("Greetings %s.\n", argv[1]);
	printf("Please tell me your name.\n");
    return 0;

Compile using:
> gcc -Wall -o hello hello.c
Run with:
> ./hello Linus
Greetings Linus.

gcc options

output file name, (a.out if omitted)
display warnings for many possible errors
file to be compiled, can specify multiple .c files

The info pages (info gcc) has much more information about gcc. These are in the gcc-doc package.

The Path

Typical Linux path:

$HOME/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin: /usr/sbin:/usr/bin:/usr/X11R6/bin:/usr/games

user's personal bin directory
programs installed by the local sysadmin
programs required during startup
most executables
X11 programs
programs which are normally only run by the superuser (root)
. (dot, current directory)
should be last item in path, or preferably not at all.
If you don't have "." in your path then you will need to run programs by using ./name


> cat > tryme <<EOF
echo "This is a test script."
> chmod +x tryme
> ./tryme
This is a test script.

Compiling an application from the source code

The easiest way to install new software:

  1. pre-compiled .deb, .rpm, or .tgz - use the native package for your distribution
  2. Compile from your distribution's source packages
  3. If it hasn't been packaged use the original source

If you are trying to compile a version which is newer than the package version you may be able to patch the new version using the old package .diff file.

Compiling a Debian source package

Required package: dpkg-dev
Suggested packages: fakeroot, devscripts

download source packages
Download three files for each package: .dsc, .diff.gz, and .orig.tar.gz from your local mirror.
eg mutt_1.0pre4-1.dsc mutt_1.0pre4-1.diff.gz, and mutt_1.0pre4.orig.tar.gz.
dpkg-source -x foo.dsc
Extract the package where foo is the name of the package and will include the version number, eg mutt_1.0pre4-1
cd foo
that's the common short form of chdir foo
fakeroot build
Compile the package and put it into a .deb file. Root privileges are not required to build a .deb package if the fakeroot package is installed.
dpkg -i ../foo.deb
Install your new package. You do have to be root for this - use su to change to root from an ordinary user.

All the debian specific files live in the debian directory.

debian/rules is a makefile which is run to build the package. It can be run directly with ./debian/rules build to compile the package, or ./debian/rules binary to compile and install the package to debian/tmp.

Compiling a RedHat source package

Download the source rpm (.src.rpm) from your local mirror.

rpm --recompile foo-ver.src.rpm

From rpm(8):

When invoked this way, rpm installs the named source package, and does a prep, compile and install. In addition, --rebuild builds a new binary package. When the build has completed, the build directory is removed (as in --clean) and the the sources and spec file for the package are removed.

Compiling from the original source

Extracting the archive

Read documentation

Look for files called: INSTALL, README, SETUP, or similar.

Read with less docfile, or zless docfile.gz for .gz files.


Follow the instructions that come with the package. Typically they will tell you to:

Many packages have a configure script which will query your system and configure themselves appropriately. Not supported by all software.
Compile the software. Some require a file name to build such as make foo. make reads a file normally called Makefile for what commands to run.
make install
Install the software. Typically packages will put themselves in /usr/local. Run as root.

Where to look when it doesn't work

Read the error messages. Look for errors about missing header files, libraries or commands.

Look at config.log if ./configure failed.

gcc may have be called with these options:

link in the library with a file called liblibrary.a
search for libraries here as well as /lib, /usr/lib, and paths specified in /etc/
search for #include here as well as /usr/include
compile, but don't link - produces a .o file, not an executable

Often you may be missing a file which is required to build the package. This may be a header (.h) file, library (.a) file, or command required to build certain parts (yacc, as, g++, etc).

Header files are found in Debian packages ending -dev, or RedHat packages ending in -devel.

For example, there are three Debian libncurses4 packages:

needed to run a program which uses ncurses
needed to compile an ncurses program
needed to be able to debug and step through the actual ncurses functions - not often needed

Debian has a list of all files in all packages as part or each mirror:

Use zgrep to search for missing files:

> zgrep ncurses.h Contents-i386.gz
usr/i486-linuxlibc1/include/ncurses.h	oldlibs/ncurses3.0-altdev
usr/include/ncurses.h			devel/libncurses4-dev

This search can also be performed on the web

Compiling your first kernel

Both Debian and RedHat include packages of new pre-compiled kernels, packages with the source, and Debian includes a package to help you make a package with your new kernel. The Debian packages are kernel-image-2.2.12, kernel-source-2.2.12 (the version numbers are part of the name so you can have multiple kernel sources installed at the one time), and kernel-package. The RedHat packages are called kernel, and kernel-source.

I'll assume that you don't want to use these, and show you how to compile a kernel from the original kernel source tree.

Required packages:
Debian: gcc (or gcc272), binutils, libc-dev, bin86
RedHat: egcs, binutils, libc-devel, bin86.

Download the source from your local mirror

> tar -xzvf linux-2.2.13.tar.gz
> cd linux

Documentation directory
Like most people you'll probably ignore this and jump straight into building your kernel. Just remember it's here. Goodies include instructions for building the kernel (Documentation/kbuild/), the tux logo (Documentation/logo.gif), and lots of information about supported devices.

Configure using one of
make config
text based
make menuconfig
text menu based, requires ncurses
make xconfig
X11 config, requires TCL/TK

This will create the .config file.

There is no easy way to find out the options used to configure your current kernel. You will need to know the type and model of the devices you wish to use.

Build the kernel
make dep
make bzImage
make modules

Install the kernel
cp arch/i386/boot/bzImage /boot/bzImage-2.2.13
make modules_install
cp .config /boot/config-2.2.13
cp /boot/
vi /etc/lilo.conf

Upgrading the kernel is one of those rare occasions where you really do need to reboot your Linux box.

More information