f78 General Conventions for Makefiles Contents|Index|Previous|Next

General Conventions for Makefiles

Every Makefile should contain the following line to avoid trouble on systems where the SHELL variable might be inherited from the environment. (This is never a problem with GNU make.)

SHELL = /bin/sh

Different make programs have incompatible suffix lists and implicit rules, and this sometimes creates confusion or misbehavior.

So it is a good idea to set the suffix list explicitly using only the suffixes you need in the particular Makefile, using something like the following.

.SUFFIXES:
.SUFFIXES: .c .o

The first line clears out the suffix list, the second introduces all suffixes which may be subject to implicit rules in this Makefile.

Don’t assume that ‘.’ is in the path for command execution. When you need to run programs that are a part of your package during the make, please make sure that it uses ‘./’ if the program is built as part of the make or ‘$(srcdir)/’ if the file is an unchanging part of the source code. Without one of these prefixes, the current search path is used.

The distinction between ‘./’ and ‘$(srcdir)/’ is important when using the ‘--srcdir’ option to ‘configure’. A rule of the following form will fail when the current directory is not the source directory, because ‘foo.man’ and ‘sedscript’ are not in the current directory.

foo.1 : foo.man sedscript
sed -e sedscript foo.man > foo.1

When using GNU make, relying on ‘VPATH’ to find the source file will work in the case where there is a single dependency file, since the ‘make’ automatic variable ‘$<’ will represent the source file wherever it is. (Many versions of make set ‘$<’ only 530 in implicit rules.) A makefile target like the following should instead be re-written in order to allow ‘VPATH’ to work correctly.

foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o

The makefile should be written like the following.

foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@

When the target has multiple dependencies, using an explicit ‘\$(srcdir)’ is the easiest way to make the rule work well. For instance, the previous target for ‘foo.1’ (see (srcdir) )is best written as the following.

foo.1 : foo.man sedscript
        sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@

0