9.3 Other Systems

9.3 Other Systems

If a package does not use GNU autoconf for platform-specific configuration, you should expect that the package uses one of these three systems:

  • A customizable Makefile and/or config.h. At one time, administrators had to configure nearly all third-party Unix software by editing Makefiles. GNU autoconf has made this practice nearly extinct, but you still may come across custom configuration in older packages or very Linux-specific packages.

  • Imakefiles. Many X Window System applications use imake to create Makefiles from Imakefiles.

  • "Anybody's guess." Some developers just have to be different.

In addition, many packages, including those using the three types listed above, now rely on the pkg-config program for compiler and linker options. You will see how these work in Section 9.3.3.

9.3.1 Custom Makefiles

When you need to customize a Makefile, make a copy of the original Makefile (to Makefile.dist, for example) before changing anything. This ensures that you can always refer to a pristine original when you delete or alter a line that you shouldn't have touched.

A typical custom Makefile might look like this:

# CC=gcc
# use -O to enable optimizer


# To enable X11 support, use -DHAS_X11
# XINC=-I/usr/X11R6/include
# XLIB=-L/usr/X11R6/lib -lX11 -lXt
# Don't edit below this line

As you learned in Chapter 8, # is a comment in a Makefile. Custom Makefiles often include macros that are commented out; and uncommenting those macros allows you to override defaults and add extra features.

The XINC and XLIB macros in the preceding example illustrate use of a third-party library. Macros like DESTDIR are analogous to the --prefix parameter in the GNU autoconf system. Don't expect all Makefiles to have such a mechanism, though.

Finally, some particularly old configuration files ask you to specify whether your system is a BSD-like or SVR4 (System V Release 4) system. At one time, most Unix flavors were derived from one or the other. Linux leans more toward SVR4, but depending on the nature of the package, there are many BSD-isms on Linux that you might need to take into account.

9.3.2 Imake

Many X Window System applications use imake to create Makefiles from Imakefiles. The Imake system attempts to produce valid Makefiles from Imakefile template files with the help of predefined default values for the C compiler, options, and so on. The imake program uses the C preprocessor for its dirty work.

Imake is standard on any platform that has an X Window System installation (usually located in /usr/X11R6). Imake's ubiquity is its only advantage. The system's disadvantages are that it's not very flexible (it usually requires installing packages with a /usr/X11R6 prefix) and it's not very smart (it doesn't dig around in your system and verify that things actually work as advertised).

To build and install a package that comes with an Imakefile, do the following:

  1. Run xmkmf or xmkmf -a (use -a if there are subdirectories) to create the valid Makefile.

  2. Run make to compile the package.

  3. Run make install to install the executables and libraries.

  4. Run make install.man to install the manual pages.

X Resource Files

Many packages that have Imakefiles also use application default ("app-defaults") files to store default configuration data. A program window missing an app-defaults file may look "plain" or extremely bad.

App-defaults files are usually in /usr/X11R6/lib/X11/app-defaults. Some packages give you an option for installing their app-defaults file in a place other than the default. Unfortunately, most do not, and you might have to resort to this ugly trick in order to install the package in a nonstandard location:

  1. Identify the programs to be installed with make -n install.

  2. Identify the app-defaults file (it usually ends with .ad). Your make -n install from the previous step should tell you the name of the installed file, though in the make -n install output the app-defaults filename normally does not have the .ad extension.

  3. Install the program by hand.

  4. Install the app-defaults file without a .ad extension.

  5. Rename the program with a .bin extension.

  6. Write a wrapper script like the following and name it program without the .bin extension (app_defaults_path is where you installed the app-defaults file, and prog_path/program.bin is the binary program):

    exec prog_path/program.bin

9.3.3 pkg-config

The number of third-party libraries has risen dramatically in recent years. Because keeping all add-on libraries in a common location can be messy, you may wish to install each with a separate prefix. However, doing so can lead to problems when building packages that require these third-party libraries. For example, if you want to compile OpenSSH, you need the OpenSSL library. How do you tell the OpenSSH configuration process the nonstandard location of the OpenSSL header files and libraries?

Many libraries now use the pkg-config program not only to advertise the locations of their include files and libraries, but also to specify the exact flags that you need to compile and link a program. The syntax is as follows:

pkg-config options package1 package2 ...

For example, to find the include files for OpenSSL, you can run this command:

pkg-config --cflags openssl

The output should be something like this:


If you want the linker flags, use --ldflags instead. This should yield a library location and the names of the individual libraries, as in this example for OpenSSL:

-L/opt/openssl/lib -lssl -lcrypto -ldl

To see all libraries that pkg-config knows about, run this command:

pkg-config --list-all

If you look behind the scenes, you will find that pkg-config finds package information by reading configuration files that end with .pc. For example, here is openssl.pc, from the OpenSSL socket library:


Name: OpenSSL
Description: Secure Sockets Layer and cryptography libraries and tools
Version: 0.9.7b
Libs: -L${libdir} -lssl -lcrypto -ldl
Cflags: -I${includedir}

You can change this file if you like — for example, you may wish to add -Wl,-rpath=${libdir} to the library flags to set a runtime dynamic linker path. However, the bigger question is how pkg-config finds the .pc files in the first place. What happens is that pkg-config looks in the lib/pkgconfig directory of its installation prefix. A pkg-config installed with a /usr/local prefix looks in /usr/local/lib/pkgconfig.

Unfortunately, pkg-config does not read any .pc files outside of its installation prefix by default. The previous OpenSSL example .pc file would reside at /opt/openssl/lib/pkgconfig/openssl.pc, almost certainly out of the reach of any stock pkg-config installation.

There are two basic ways to show pkg-config the .pc files that are located outside of the pkg-config installation prefix:

  • Make symbolic links (or copies) from the actual .pc files to the central pkgconfig directory.

  • Set your PKG_CONFIG_PATH environment variable to include any extra pkgconfig directories. This strategy does not work well on a system-wide basis.