Even though C source code is usually fairly portable, there are still differences on each platform that make it impossible to compile most packages with a single Makefile. An early solution to this problem was to provide individual Makefiles for every operating system, or to provide a Makefile that was easy to modify. This approach somehow evolved into scripts that generate Makefiles based on an analysis of the system used to build the package.
GNU autoconf is now the most popular system for automatic file generation. Packages using this system come with files named configure, Makefile.in, and config.h.in. To generate a Makefile, run configure to check your system for prerequisites:
You should get a lot of diagnostic output like this:
checking build system type... i586-pc-linux-gnu checking host system type... i586-pc-linux-gnu checking for a BSD-compatible install... /bin/install -c checking whether build environment is sane... yes ... ...
configure creates a cache file (config.cache) so that it does not need to run certain tests more than once. In addition, configure consults config.cache on subsequent runs (this may come up if your system requires special options).
If all goes well, configure creates one or more Makefiles and config.h:
configure: creating ./config.status config.status: creating Makefile ... ... config.status: creating config.h
If you're looking for a package to test, get the coreutils package from the GNU FTP site (ftp://ftp.gnu.org/pub/gnu/coreutils/). Coreutils includes common system programs like ls and cat.
Now you can type make to compile the package. A successful configure step doesn't necessarily mean that the make step will work, but the chances are pretty good (see Section 9.6 for troubleshooting failed configures and compiles).
After the build completes, you might want to try running a program from the package, just to see if it works. To install the program, run this command:
The configure script that comes with autoconf-enabled packages has several useful options. The most important of these is the installation directory. By default, the install target uses a prefix of /usr/local — that is, binary programs go in /usr/local/bin, libraries go in /usr/local/lib, and so on.
If you want to use a prefix other than /usr/local, run configure with this option:
For example, if you specify --prefix=/tmp/test, a make install puts binaries in /tmp/test/bin, libraries in /tmp/test/lib, and so on.
Most versions of configure have a --help option that lists other configuration options. Unfortunately, the list is usually so long that it's sometimes hard to figure out what might be important. Here are some other options:
--bindir=directory Installs executables in directory.
--sbindir=directory Installs system executables in directory.
--libdir=directory Installs libraries in directory.
--disable-shared Prevents the package from building shared libraries. Depending on the library, this can save hassles later on (see Section 9.4.1).
--with-package=directory Tells configure that package is in directory. This is handy when a necessary library is in a nonstandard location. Unfortunately not all configure scripts recognize this type of option, and furthermore, it can be difficult to determine the exact syntax.
You can create separate build directories if you want to experiment with some of these options. To do this, create a new directory anywhere on the system, and from that directory, run the configure script in the original package source code directory. You will find that configure then makes a symbolic link farm in your new build directory, where all of the links point back to the source tree in the original package directory. Some developers actually prefer that you build packages this way.
You can influence configure with environment variables that the configure script puts into make variables. The most important variables are CPPFLAGS, CFLAGS, and LDFLAGS. Be aware that configure can be very picky about environment variables. For example, you should always use CPPFLAGS instead of CFLAGS for header file directories, because configure often runs the preprocessor independently of the compiler.
In bash, the easiest way to send an environment variable to configure is by placing the variable assignment in front of ./configure on the command line. For example, to define a DEBUG macro for the preprocessor, use this command:
Environment variables are especially handy when configure doesn't know where to look for third-party include files and libraries. For example, to make the preprocessor search in include_dir, run this command:
As shown in Section 8.1.5, to make the linker look in lib_dir, use this command:
If lib_dir has shared libraries (see Section 8.1.4), the previous command probably won't set the runtime dynamic linker path. In that case, use the -rpath linker option in addition to -L :
LDFLAGS="-Llib_dir -Wl,-rpath=lib_dir" ./configure
Be careful when setting variables. A small slip can trip up the compiler and cause configure to fail. Let's say that you forget the - in -I, as in this example:
This yields an error like this:
checking for C compiler default output... configure: error: C compiler cannot create executables See `config.log' for more details.
Digging through config.log yields this:
configure:2161: checking for C compiler default output configure:2164: gcc Iinclude_dir conftest.c >&5 gcc: Iinclude_dir: No such file or directory
In addition to the standard all and install, an autoconf-generated Makefile has these targets:
make clean As described in Section 8.1.5, make clean removes all object files, executables, and libraries.
make distclean This is similar to make clean, but it removes all automatically generated files, including Makefiles, config.h, config.log, and so on. The idea is that the source tree should look like a newly unpacked distribution after running make distclean.
make check Some packages come with a battery of tests to verify that the compiled programs work properly; the command make check runs the tests.
make install-strip This is like make install, but it strips the symbol table and other debugging information from executables and libraries when installing. Stripped binaries require much less space.
If something goes wrong during the configure process and the cause isn't obvious, you can examine config.log to find the problem. Unfortunately, config.log is often a gigantic file, making it difficult to locate the exact source of the problem.
The best approach is to go to the very end of config.log (for example, by pressing G in less), and then page back up until you see the problem. However, there is still a lot of stuff at the end, because configure dumps its entire environment there, including output variables, cache variables, and other definitions.
You can also try running a search for the error message, starting from the end of the file. For example, let's say that configure fails, terminating with this message:
See 'config.log' for more details.
Search backward for the string "for more details" (or "config.log," or anything that looks reasonably unique); it's a pretty good bet that the error is nearby.