=head1 NAME

makepp_rules -- How to tell makepp to build something

=head1 DESCRIPTION

A rule is what tells makepp how to build a file or a class of files.  Makepp
supports the same rule syntax as other implementations of make, plus some
additions of its own.

A rule has the general format

    target_expression : dependency_expression  [ : optional arguments]
        actions

The list of targets may not contain any automatic variables (except
C<$(foreach)>).  The dependency list may contain only automatic variables
referring to the target (i.e., C<$(output)>, C<$(outputs)>, or their
synonymns</a>).  The action may contain any automatic variables.

If makepp decides that the rule needs to be executed, each line of the rule is
executed sequentially, and if any returns a non-zero status, the remainder are
not executed (and makepp aborts with an error unless you specified the C<-k>
option on the command line.)  Each action should be only one line.  If an
action is too long to write conveniently on a single line, you can split it
into several lines and put a backslash to indicate that the several lines
should be combined into one.

In order to distinguish actions from the next rule, the action should be
indented more than the line containing the targets and dependencies.  Unlike
other implementations of make, makepp doesn't really care how much you indent
it or whether you use tab characters rather than spaces.  To keep backward
compatibility with traditional make, the rules makepp uses to decide when
actions end and the next rule begins are somewhat complicated:

=over 4

=item *

The first action line must be indented more than the line
containing the target.

=item *

If a line is indented by one tab character or 8 spaces or more,
then it is considered an action line.

=item *

A blank line or a comment line with the C<#> character at the right margin
ends the rule, unless the next non-blank line is indented more than 8 spaces
(or more than one tab).

=item *

If a line is indented as much or more than the first action
line, then it is considered an additional action line.

=back

Normally, each shell command is printed as it is executed.  However, if
the first word of the action is C<noecho>X<noecho> (or if it begins with
the character C<@>), then the command is not printed.  For example,

    %.o: %.cxx
          noecho $(LIBTOOL) --mode=compile $(CC) -c $(input)


This means that when the libtool command is executed, it is not
printed.  (Libtool itself usually prints the modified command that
it executes, so it's redundant to print it twice.)

Normally, if the shell command returns a non-zero status, then makepp
aborts because the command failed.  However, some programs incorrectly
set the status on exit, or there may be an error which really isn't
fatal and shouldn't abort the whole compilation.  You can cause makepp
to ignore the return status by specifying C<ignore_error>X<ignore_error>
as the first word of the command line (or C<-> as the first character).
For example,

    $(phony distribution):
    	ignore_error rm -r my_program-$(VERSION) # Get rid of previous junk.
    	mkdir my_program-$(VERSION)
    	cp $(FILES) my_program-$(VERSION)
    	tar cf my_program-$(VERSION).tar my_program-$(VERSION)

This command makes a directory, copies a bunch of files into it, and
then puts everything into a tar file for distribution.  It's a good idea
to clean out the previous contents of the directory, if there was
anything there previously, and that's what the first line does.  The
C<rm> might fail, but its return status is ignored.

There are several different kinds of rules, each with different purposes.

=head2 Explicit Rules

    target1 target2: dependency1 dependency2 ...
    	actions to be performed


This syntax specifies that in order to make either F<target1> or
F<target2>, all the files F<dependency1>, F<dependency2>, etc., must
already have been made.  Then the given actions are executed by the
shell to make the targets.  Unlike traditional makes, makepp usually
assumes that one invocation of the action makes all of the targets
(unless there are no dependencies).  For example, one invocation of yacc
creates both output files for this rule:

    y.tab.c y.tab.h : parser.y
    	$(YACC) -d parser.y

Note that other implementations of make do not have a concept of a single
command producing multiple output files, and so when you specify multiple
targets they will execute the rule once per target.  Makepp will revert to
this behavior if it looks like this is an old-style makefile.  Specifically,
it will execute the rule once per target, instead of just once overall, if all
of the following are true:

=over 4

=item *

The rule action mentions the automatic variable C<$@>.  (The synonymns
C<$(output)> or C<$(target)> do not trigger this behavior.)

=item *

The rule action does not mention the automatic variable C<$(outputs)> (or its
synonymn C<$(targets)>).

=item *

This is not a pattern rule, and there is no foreach clause.

=back

For example,

    all test install:
    	for subdir in $(SUBDIRS); do cd $$subdir && $(MAKE) $@; cd ..; done

is a common idiom in makefiles, and makepp supports it.  (Note that you should
never use recursive make in any new makefiles you write--use the
C<load_makefile> statement, or implicit makefile loading instead.)

If you want to have the same rule executed once for each target, it's
preferable to use either a pattern rule (see below) or a C<foreach> clause.

As with other implementations of make, the first explicit rule in a file is
the default target, and is made if you do not specify any targets on the
command line.

=head3 Phony targets

A I<phony target> is a target that will never actually exist in the
file system; it's just a way of getting makepp to build some targets
and possibly execute some additional commands.

A typical phony target is C<all>, which usually is used to cause
everything that can be built to be built, like this:

    all: prog1 prog2 subdir/prog3 subdir2/libmine.a
          @echo "All done!"

If you type S<C<makepp all>>, or if you put all as the first explicit
target in your makefile (which is typical) and just type C<makepp>,
then it will cause all the dependencies to be built, then it will
print "All done!".  At this point, makepp will look for the file
F<./all> and will discover that it doesn't exist.  It will complain
loudly.

To keep makepp from expecting the file F<./all> to exit, you need to
tell it that it's a phony target.  Just put a line like the following
in your makefile (it makes no difference where):X<.PHONY>

    .PHONY: all

An equivalent alternative which is sometimes more convenient is to use
the S<C<$(phony )>> function, like this:

    $(phony all(: prog1 prog2 subdir/prog3 subdir2/libmine.a

Phony targets in one makefile can refer to phony targets in another
makefile.  This is often done with the C<clean> target, like this:

    # Top level makefile:
    # lots of rules and stuff here
    # ....
    $(phony clean): subdir1/clean subdir2/clean
        $(RM) -rf my_program .makepp*

Then in the subdirectories, the makefiles might read like this:

    # Makefile in a subdirectory
    # ...
    $(phony clean):
        $(RM) -rf *.o *.a .makepp*


=head3 Wildcards

It is safe to specify wildcards in the dependency list.  Wildcards match not
only files that exist, but files which can be created given the rules in the
makefile.  For example, to build a library from all .o files in a directory,
you could write this:

    libmine.a: *.o
        $(RM) -f $(output)
    	ar cr $(output) $(inputs)

This will work even if none of the C<.o> files have been created yet, because
makepp's wildcards match files which do not yet exist but can be built.

Makepp supports all the usual shell wildcards (C<*>, C<?>, and C<[]>).  It
also has a wildcard C<**> which matches any number of intervening directories.
(This idea was stolen from zsh.)  For example, C<**/*.c> matches all the F<.c>
files in the entire source tree.  C<objects/**/*.o> matches all the F<.o>
files contained anywhere in the subdirectory F<objects> or any of its
subdirectories or any of their subdirectories.  The C<**> wildcard will not
follow soft links to directories.  It also will never return phony targets.

Makepp's wildcards will ignore files or directories which exist but cannot be
read.  After all, such files cannot be used in the build process anyway.
Putting unreadable files in a directory is primarily useful to inhibit the
automatic import of the given file from a repository.


=head2 Pattern rules

A pattern rule is a rule that is applied based on some textual pattern.  This
is used to apply the same rule to a whole class of files.  The syntax is the
same as GNU make's pattern rules:

    %.o: %.c
    	$(CC) -c $(input) -o $(output)


This says that any file in the current directory which matches C<*.c> can be
converted into the corresponding .o file using the given command.

Note that several pattern dependencies may be supplied.  For example, if
your F<xyz.o> file depends on the corresponding F<xyz.cpp> file, and
also on a file called F<moc_xyz.cflags> which contains the compiler
options, this could be expressed with:

    %.o: %.cpp %.cflags
    	$(CXX) `cat $(stem).cflags` -c $(inputs) -o $(output)

You may also have several pattern targets.  For example,

    %.tab.h %.tab.c : %.y
    	yacc -d $(input)
    	mv y.tab.h $(stem).tab.h
    	mv y.tab.c $(stem).tab.c

X<percent_subdirs>Ordinarily, pattern rules only look for files in the
current directories.  You can force them to search in the current
directory and all directories beneath it by using the command line
option C<--percent-subdirs>, or by specifying

    percent_subdirs := 1

before the first pattern rule in your makefile.

=head2 Static pattern rules

A static pattern rule is a pattern rule that is applied only to a
limited set of files:

    $(SPECIAL_MODULES).o : %.o : %.cpp
        $(CX) -c $(input) -o 

This says that the pattern rule applies only to the files in
S<C<$(SPECIAL_MODULES).o>>.

This is mostly for compatibility with GNU make; foreach rules (see
below) are a more powerful way of doing the same thing. 

=head2 Foreach rules

The above pattern rule syntax is powerful enough to support almost all builds,
but occasionally it is necessary to do something more complicated.  Makepp
provides a more powerful syntax: the C<:foreach> clause for the rule.

    target_expression : dependency_expression : foreach file-list
    	actions

The simplest kind of foreach rule is just a pattern rule whose
application is restricted to a specific list of files.  For example,
suppose you have a pattern rule that tells makepp how to compile all
F<.c> files.  However, you have a list of F<.c> files for which you want
to do something different.  You could do something like this:

    # Here's the rule that applies to everything:
    %.o : %.c
        $(CC) $(CFLAGS) -c $(input) -o $(output)

    %.o : %.c : foreach $(SPECIAL_MODULES)
        $(CC) $(SPECIAL_CFLAGS) -c $(input) -o $(output)

An even more powerful use of foreach rules takes advantage of the fact
that the variable C<$(foreach)> is set in turn to each file matching the
file list and the target and dependency expressions are evaluated.  The
file-list may contain wildcards, and these match even files which don't
exist yet but which can be built (see L<makepp_rules/Wildcards>).

This is an unwieldy syntax but it is extremely flexible, because the
C<$(foreach)> variable may appear in any way in the expression.  First,
note that pattern rules are in fact a special case of foreach rules; the
pattern rule

     %.o : %.c
        $(CC) $(CFLAGS) -c $(input) -o $(output)

is exactly equivalent to:

    $(patsubst %.c, %.o, $(foreach)) : $(foreach) : foreach *.c
        $(CC) $(CFLAGS) -c $(input) -o $(output)

(In fact, it's converted to approximately that internally.)  

As an example of how you would use a C<:foreach> clause where a pattern
rule isn't sufficient, suppose you have some F<.c> files which are built
using some kind of preprocessor which takes as input files with a F<.k>
extension.  You want to compile those F<.c> files with a different set
of compilation options than the usual F<.c> files which are ordinary
source files.  You could do something like this:

    # Rule for ordinary .c files:
    %.o : %.c
        $(CC) $(CFLAGS) -c $(input) -o $(output)

    # Rule to make .c files from .k files:
    %.c : %.k
        $(preprocessor) $(input) > $(output)

    # Special build rules for .c files which are made from .k files:
    $(foreach:%.k=%.o) : $(foreach:%.c=%.k) : foreach *.k
    	$(CC) $(SPECIAL_CFLAGS) -c $(input) -o $(output)

(This uses the slightly more concise substitution reference syntax
rather than calling C<patsubst> explicitly.)

Note that if all you want to do is to change the value of a variable
(C<CFLAGS> in this case) it's sometimes more convenient to use
L<target-specific variables|makepp_variables/Target-specific assignments>.

=head2 Legacy suffix rules

For backward compatibility, makepp supports the old-style
suffix rules.

    .suffix1.suffix2:
    	actions

is equivalent to

    %.suffix2: %.suffix1
    	actions

but much harder to remember.  (Which suffix comes first?)  This is
usually done like this:

    .c.o:
        $(CC) $(CFLAGS) -c $*.c -o $*.o

which is exactly equivalent to

    %.o : %.c
        $(CC) $(CFLAGS) -c $(input) -o $(output)

=head2 Conflicting rules

When there is more than one way to make a file, makepp
uses a simple procedure to determine which rule to use.

=over 4

=item *

It is an error to have conflicting explicit rules for building a file.

=item *

Pattern rules and foreach rules with wildcards never override explicit
rules.  Thus explicit rules can be used to specify exceptions for
pattern rules.  (Note that simply using a C<:foreach> clause doesn't
make something a pattern rule.  It must have a wildcard (like "*" or
"?") as part of the filename in the C<:foreach> clause.  If it is just
an explicit list of files, it is treated as an explicit rule for those
files.)

=item *

When conflicting pattern rules come from different makefiles, rules from
"nearer" makefiles override rules from "farther" makefiles.  "Nearer"
means that the makefile is located closer to the target in the directory
hierarchy (i.e., the file name of the target relative to the directory
the makefile is run from is shorter).  If this doesn't distinguish the
makefiles, then the rule from the makefile which is loaded latest is
used.

This means that you can specify a pattern rule that applies to all files
in your entire directory tree in just the top-level makefile, but then
you can override it in a lower-level makefile.  For example, your
top-level makefile could contain:

    %.o : %.c : foreach **/*.c
        $(CC) $(CFLAGS) -c $(input) -o $(output)

and you could have a makefile in one of the subdirectories that says:

    %.o : %.c
        $(CC) $(SPECIAL_CFLAGS) -c $(input) -o $(output)

=item *

Pattern rules that have a shorter chain of inference are preferred over
other pattern rules.  For example, if you had the following rules (based
on an example from the linux kernel):

    %.s: %.c
    	$(CC) -s $(input) -o $(output)
    
    %.o: %.s
    	$(AS) $(input) -o $(output)
    
    %.o: %.c
    	$(CC) -c $(input) -o $(output)


If we need to build C<xyz.o>, we could either build the intermediate
C<.s> file and then run that through the assembler using the first two
rules, or we could go directly to a C<.o> file using the last rule.  The
last rule is preferred because there are fewer steps in the chain of
inference (one instead of two).

=item *

Rules later in a makefile override rules that are earlier.  (This is
backwards from GNU make.)  This means that you should put your more
general rules earlier, and your more specific rules later.  For example,

    %.o: %.c                            # General compilation rule.
    	action
    
    special_%.o: special_%.c            # Special rule for files with a
    	different action            # "special_" prefix.

=back

=head2 Rule options

Sometimes it is necessary to supply additional options to modify how
makepp executes the rule.  These options are specified as C<:optionname
value>, either on the line containing the dependencies, or separated on
subsequent lines.

Supplying the options on separate lines may make it possible for
you to use the same makefile with makepp and a traditional
make.  For example,
    target : dependencies
           : signature target_newer
    	actions

will work fine with a traditional unix make, because it interprets the
S<C<: signature>> line as a shell command, and a command beginning with
a colon does nothing.

=head3 signature signature_method X<signature>

     target : dependencies
            : signature target_newer
          actions

This tells makepp what algorithm to use to determine if the file is out
of date.  See L<makepp_signatures> for more details.  Signature methods
which are included with the makepp distribution are are C<exact_match>,
C<target_newer>, C<md5>, and C<c_compilation_md5>.  This overrides any
signature method specified with the C<-m> or C<--signature-method>
command line options, or with the C<signature> statement.

=head3 scanner name X<scanner>

This tells makepp how to scan for include files.  Usually, makepp guess
how to do this based on the words in the command itself (see
L<makepp_scanning> for details).  However, if makepp guesses wrongly,
you may want to explicitly indicate the scanner, like this:

    %.o: %.abc
    	: scanner c_compilation
    	action here

This causes makepp to perform the same scanning that it does for C/C++
build commands, even if it doesn't recognize the action as a C
compilation.

Legal values for C<:scanner> are (currently):

=over 4

=item none

Don't bother scanning the command or any files at all.  Makepp will not
know about any dependencies or targets other than those explicitly
listed in the rule.  This is the default for all commands that makepp
does not recognize.

=item c_compilation

Uses thes scanner for C/C++ compilation, which looks for
include files.

=back

The default scanner depends on the command.  If you do not specify a
C<:scanner> option, then the first word of the command is examined.  If
it looks like a compile or link command, then makepp will use the
C<c_compilation> scanner; otherwise it usese the C<none> scanner.  For
more details on this, or if you want to write your own scanner or change
makepp's default scanners, see L<makepp_scanning>.

=head2 Special characters

Makepp can support filenames that have special characters
in them like a colon or a space.  Suppose, for example, you want to
create a file called C<a:thing> from the file
C<b:thing>.  You can't write the rule this way:

    a:thing : b:thing       # This is a syntax error
    	cat $(input) > $(output)

because makepp won't know which colons separate targets from
dependencies and which are part of the filenames.  Instead, simply
enclose the name in quotes, like this:

    "a:thing" : "b:thing"
    	cat $(input) > $(output)

Now the rule is unambiguous.

Makepp's quoting rules are quite similar to the shell's.  You can, for
example, use single quotes instead of double quotes, or you can escape special
characters with a backslash:

    a\:thing : 'b:thing'
    	cat $(input) > $(output)

Suppose, for example, that your filename is C<'"!;\$>.  Now why you'd want
such a filename I don't know, but here are several ways you could specify it
to makepp (and the shell):

    \''"!;\$$'
    "'\"!;\\$$"

Note that (unlike the shell) variables beginning with C<$> are expanded even
inside single quotes.  Dollar signs cannot be protected by quotes or
backslashes.  To get a literal dollar sign, use a double dollar sign.

Generally, you should be able to deal with just about any special character by
quoting it in some way.  This includes spaces, control characters, etc.
However, be aware that at present, makepp's comment stripping is somewhat
simplistic, and any C<#> characters preceded by whitespace will be interpreted
as comments no matter how they are quoted.

When a target or dependency name is put into an automatic variable like
L<C<$(output)>|makepp_variables/output>, then the quotes and any backslashes
are stripped.  This means that if you want to reference the filename in the
actions, you will probably have to quote it again, like this:

    "a file name with spaces":
    	echo "Special contents" > "$@"

If you don't put the quotes around C<$@>, then the
shell will see the command

    echo "Special contents" > a file name with spaces

which writes the string "Special contents file name with spaces" to the file
called F<a>.  This is probably not what you want.

=head1 AUTHOR

Gary Holt (holt-makepp@gholt.net)

