Makepp Incompatibilities

Incompatibilities between makepp and GNU make

Makepp was designed to be as close as possible to GNU make. However, because of the difference in philosophy (see the makepp_build_algorithm manpage), some of GNU make's features cannot be supported. Others have not been implemented because we haven't had time. Also, in order to emulate GNU make's behavior precisely, you may in some cases have to add additional command line options to the makepp command line, as noted below. Most of the differences from GNU make are quite technical and only rarely cause problems.

Makepp will give warning messages for many things which the traditional unix make accepts without flinching. This is because there are better ways to do them with makepp. If these warnings annoy you, you can turn them off with the --nowarn command line option.

Incompatibilities without the variable makepp_percent_subdirs=1

By default, % in a pattern rule does not match directories. Thus %.c matches only .c files in the current directory. If you want it to match files in subdirectories too, then set the variable makepp_percent_subdirs=1 on the command line or near the beginning of a makefile.

Incompatibilities without the -m option

By default, makepp will attempt to rebuild all targets if any of the dependencies have changed since the last build, or if the command has changed (see the makepp_signatures manpage for details). This is normally what you want. Sometimes, however, you don't want the target to be rebuilt if it has been modified apart from the control of makepp (e.g., by editing it, or by running a program manually to make the file). You can force makepp to use the traditional make algorithm, which only rebuilds if any of the targets are newer than the dependencies, by adding the option -m target_newer to the command line.

As a special exception, any targets which are built while rebuilding the makefile are automatically checked using the target_newer method in order to avoid problems with configure procedures.

Incompatibilities without the --traditional-recursion option

Recursive invocations of make are often considered to be an unsafe practice (see Better system for hierarchical builds in the makepp manpage for details), but they are extremely common in existing makefiles. Makepp supports recursive make for backward compatibility; for new makefiles, it is much better to use the load_makefile statement, or makepp's implicit makefile loading mechanism.

In order to be able to use repositories for variant builds, and to help make recursive invocations of make safer, makepp normally does not actually invoke itself recursively even if you tell it to. Instead, a subprocess communicates with the parent process, and the actual build is done by the parent process.

This works in most cases, but there are a few incompatibilities. (All of these incompatibilities are removed by adding the --traditional-recursive-make option to the command line.)

This may seem like a long list of restrictions, but many makefiles obey them. For example, as far as I know, all makefiles produced by automake follow these restrictions.

All of these restrictions go away if you add the --traditional-recursive-make option to the command line, but that has the following undesirable side effects:

Even with the --traditional-recursive-make option, the environment variables MAKEOVERRIDES and MFLAGS not set up, and are ignored, so makefiles that depend on those will not work.

Incompatibilities without the makepp_simple_concatenation variable

Rc-style substitution is the default way makepp performs variable substitution into text strings because it very rarely breaks legacy makefiles and is often useful in new makefiles. However, it does introduce occasional incompatibilities in the substitution of variables not surrounded by spaces. For example,

INCLUDE_PREFIX := -I/some/include/dir -I
INCLUDES := $(INCLUDE_PREFIX)/other/include/dir

will set INCLUDES to -I/some/include/dir/other/include/dir -I/other/include/dir if rc-style substitution is enabled, whereas GNU make would set it to -I/some/include/dir -I/other/include/dir.

There is also an incompatibility in the handling of whitespace in a variable:

null :=
T := -o $(null)             # T contains -o followed by one space.
OUTFILE = $(T)outfile

will set OUTFILE to -ooutfile if rc-style substitution is enabled, whereas GNU make would set it to -o outfile.

Both of these incompatibilities are removed by setting the makepp_simple_concatenation variable. Note, however, that even with makepp_simple_concatenation, makepp still treats whitespace incompatibly in some situations:

T := -o # Don't delete this comment.

GNU make sets T to contain -o followed by a space, whereas makepp strips out the trailing space anyway. If you want the trailing space, you must set makepp_simple_concatenation and also set T using the technique involving a dummy variable such as null, as shown above.

Command line incompatibilities

Makepp supports a few of make's more useful command line options. The following, however, are not supported, and are ignored after a warning message is printed:

-d or --debug
-i
-l or --load-average or --max-load
-m

Makepp's -m option has to do with signature method selection, whereas GNU make ignores -m.

-p or --print-data-base
-q or --question

Makepp's -q option suppresses makepp's chatty informational messages, which is different from -q in GNU make.

-R or --no-builtin-variables

Makepp's -R option actually does something completely different.

-S --no-keep-going or --stop

The --stop option stops (puts to sleep) makepp after learning all the rules, so you can continue editing.

-t or --touch
-w or --print-directory

This happens automatically.

--no-print-directory
--warn-undefined-variables

Some of these can be easily supported if anyone cares.

Incompatibilities in order of expression expansion

Though I have not seen this used, GNU make allows the following:

colon = :
a$(colon) b
    echo $^

Makepp expands $(colon) too late for this to work. However it offers the alternative $[colon] syntax, which can do much more than GNU make, because it is expanded very early.


Last modified: 2008-06-02