=head1 NAME
makepp_statements -- Various statements in a makefile
=
for
vc
$Id
: makepp_statements.pod,v 1.36 2010/07/16 21:15:23 pfeiffer Exp $
=head1 DESCRIPTION
=
for
genindex
'-?\w+'
makepp_statements.pod
B<A:>E<nbsp>L<autoload|/autoload_filename>,E<nbsp>
B<B:>E<nbsp>L<build_cache|/build_cache_path_to_build_cache>,
L<build_check|/build_check_build_check_method>,E<nbsp>
B<D:>E<nbsp>L</define>,E<nbsp>
B<E:>E<nbsp>L<export|/export_var>,E<nbsp>
B<G:>E<nbsp>L<global|/global_var>,E<nbsp>
B<I:>E<nbsp>L<ifdef|/ifdef_variable>,
L<ifeq|/ifeq_string1_string2>,
L<ifmakeperl|/ifperl_perlcode>,
L<ifndef|/ifdef_variable>,
L<ifneq|/ifeq_string1_string2>,
L<ifnsys|/ifsys_wildcard>,
L<ifntrue|/iftrue_expression>,
L<ifperl|/ifperl_perlcode>,
L<ifsys|/ifsys_wildcard>,
L<iftrue|/iftrue_expression>,
L<include|/include_makefile>,E<nbsp>
B<L:>E<nbsp>L<load_makefile|/load_makefile_some_directory_somewhere_makefile>,E<nbsp>
B<M:>E<nbsp>L<make|/prebuild_target>,
L<makeperl|/perl_perlcode>,
L<makesub|/
sub
>,E<nbsp>
B<N:>E<nbsp>L</no_implicit_load>,E<nbsp>
B<P:>E<nbsp>L<perl|/perl_perlcode>,
L</perl_begin>,
L<prebuild|/prebuild_target>,E<nbsp>
B<R:>E<nbsp>L<register_command_parser|/register_command_parser_command_word_class_name>,
L<register_input_suffix|/register_input_suffix_command_word_suffix>,
L<register_scanner|/register_scanner_command_word_scanner_name>,
L<repository|/repository_directory>,
L<runtime|/runtime_program_library>,E<nbsp>
B<S:>E<nbsp>L</signature>,
L</
sub
>
A statement is any line beginning
with
a word which does not have a C<:> in
it. (A colon implies that the line is a rule.) For example, these are
statements:
include extra_rules.mk
load_makefile subdir
Makepp
has
a number of builtin statements which you may occasionally need to
use
.
Note that wherever you see an underscore, you may also
use
a dash,
because makepp converts dashes to underscores in statement names.
=head2 Conditionals
Conditionals are special statements, which control what lines of the
Makeppfile are actually seen. The simplest form (where C<ifxxx> stands
for
any of the conditional statements documented below) is:
ifxxx ...
lines seen
if
the statement evaluates as true
endif
or:
ifxxx ...
lines seen
if
the statement evaluates as true
else
lines seen
if
the statement evaluates as false
endif
There is also the possibility to
do
complex combinations like this:
ifxxx ...
and ifxxx ...
and ifxxx ...
or ifxxx ...
and ifxxx ...
lines seen
if
the combined statements evaluate as true
else
ifxxx ...
or ifxxx ...
and ifxxx ...
lines seen
if
the first combination evaluates as false
and these combined statements evaluate as true
else
lines seen
if
the statements above evaluate as false
endif
As is suggested by the indentation, B<C<and>>
has
higher precedence than
B<C<or>>. In other words an B<C<or>> elects between two groups of
B<C<and>>`s. There may be any number of C<and ifxxx>`s, C<or ifxxx>`s and
C<
else
ifxxx>`s.
The C<ifxxx> conditional statements are unique in that they may occur in the
middle of rule actions, as in the above example, without disrupting the rule.
=over 4
=item ifeq I<string1, string2>
=item ifneq I<string1, string2>
ifeq ($(STR1),$(STR2))
makefile lines
if
true
else
makefile lines
if
false
endif
If the two strings match exactly (except
for
leading or trailing
whitespace), then the first set of lines is used; otherwise the second
is used. The
else
clause is optional.
There are two other acceptable syntaxes
for
the C<ifeq> and C<ifneq>
statements:
ifeq string1, string2
ifeq string1 string2
which are equivalent. Of course you can quote the strings as needed.
C<ifeq> and its friends C<ifneq>, C<ifdef>, C<ifndef>, C<ifperl>,
C<ifmakeperl>, C<ifsys> and C<iftrue> are primarily useful
when
you have
to build a program under several different conditions. For example,
BUILD_TYPE := debug
ifeq ($(BUILD_TYPE), debug)
CFLAGS := -g
else
CFLAGS := -O2
endif
program : *.o
$(CC) $(CFLAGS) $(inputs) -o $(output) $(LIBS)
ifeq ($(BUILD_TYPE), production)
strip $(output)
endif
%.o : %.c
$(CC) $(CFLAGS) -c $(input) -o $(output)
If this is a production build, all files are compiled
with
the C<-O2>
option instead of the C<-g> option. Furthermore, the program C<strip>
is run on the resulting binary (in case you happened to
link
with
some
libraries that were compiled in debug mode).
Sometimes it is easier to
use
the L<C<$(
if
)>
function|makepp_functions/if_string_result_if_string_not_blank_result_if_string_blank>
or L<C<$(perl)> function|makepp_functions/perl_perlcode> function instead of a
C<ifeq> statement.
If you just want to see whether a symbol is blank or not, you only need
to supply a single argument, like this:
ifneq $(EXE_SUFFIX)
endif
=item ifdef I<VARIABLE ...>
=item ifndef I<VARIABLE ...>
These statements work analogously to the C<ifeq> and C<ifneq> statements,
except that they test whether any of the variables is
defined
or not any is
(i.e. none is
defined
). A variable is
defined
if
:
=over 4
=item *
It was
given
a value
with
an assignment earlier in the makefile. See
L<makepp_variables>
for
details.
=item *
It was
given
a value as a perl variable in a C<perl_begin> block.
=item *
The variable is present in the environment.
=item *
The variable is present on the command line, e.g., to invoke your
makefile, you typed
makepp CFLAGS=-O2
=back
For example,
ifndef CFLAGS
CFLAGS := -g
endif
In this case, C<CFLAGS> is set to C<-g> only
if
it wasn't already
defined
. Note that this statement could just as easily have been
written using the C<?=> assignment, like this:
CFLAGS ?= -g
=item ifperl I<perlcode>
=item ifmakeperl I<perlcode>
These statements work analogously to the C<ifeq> and C<ifneq> statements,
except that the tests are in Perl. The first variant is plain Perl code,
while
the second variant first passes the statement through Make-style
variable expansion.
VERSION := 3.0
ifperl
$VERSION
<= 2
CPPFLAGS := -DNEW
endif
ifmakeperl
my
$$x
=
'$(CFLAGS)'
;
$$x
=~ /-g/
CFLAGS := -g -O2
endif
=item ifsys I<wildcard ...>
=item ifnsys I<wildcard ...>
Tests
if
the current
system
makepp is running on matches any of the wildcards
or not any (i.e. none).
ifsys i[3-6]86
and ifsys Linux SunOS
...
else
ifnsys sparc power*
...
endif
There are up to six different strings you can match against. The actual
strings are not standardized. Three of them reflect what the Perl instance
was built
for
(not necessarily the same as where it is running), and the
others come from the
system
and all vary wildly in form. You can find all of
what the current platform matches by typing the following command at the
Shell:
perl -MConfig -e
'print "$^O @Config{qw(archname myarchname)} "'
; uname -mps
=item iftrue I<expression>
=item ifntrue I<expression>
Tests
if
the expression evaluates to some value other than zero or the empty
string.
=back
=head2 Other Multiline Statements
Conditionals may control a whole multiline statement, but they cannot be
inside such a statement.
=over 4
=item define X<endef> X<define> X<enddef>
define VARIABLE
variable value line 1
variable value line 2
endef
Defines $(VARIABLE)'s value to be all the lines between the C<define>
statement and the C<endef> statement. See L<setting
variables|makepp_variables/Setting variables inside a makefile>.
=item perl_begin X<perl_begin> X<perl_end>
This is the same as C<perl>, but using GNU make style statement syntax.
This statement introduces a block of code which is interpreted verbatim
by perl. It can be useful
for
defining functions, but you can
do
this
more concisely
with
the C<
sub
> statement. A block of perl code in your
makefile can be useful to perform actions that are easier in perl than
with
makepp functions and rules.
The remainder of the line following the C<perl_begin> statement is
ignored. All text up
until
a line that begins at the left margin
with
C<perl_end> is sent verbatim to the perl interpreter. There can be
no
spaces
before
C<perl_end>.
One example that I
use
this
for
is to make directories that might not
necessarily exist. It's common in makefiles to put all the .o files in
a subdirectory (e.g., a directory
with
a name F<i386>, or F<sparc>, or
something that depends on the machine type). But what
if
the directory
does not exist yet? You can make
each
.o file depend on the
subdirectory, and put a rule in to build the subdirectory. But it's a
lot easier just to
do
this:
OBJDIR := $(ARCH)
perl_begin
-d
$OBJDIR
or
mkdir
$OBJDIR
;
perl_end
This way, every
time
the makefile is run, the subdirectory will be
created
if
it does not exist.
Some operations are better expressed in terms of regular expressions
than makepp's text functions. For example,
perl_begin
if
(
$ARCH
=~ /^i[56]86/) {
$CFLAGS
=
'-O6 -malign-double'
;
}
else
{
$CFLAGS
=
'-O6'
;
}
perl_end
%.o: %.c
$(CC) $(CFLAGS) -c $(input) -o $(output)
Any make variable can be accessed directly as a perl
scalar
.
In this case, we've set the value of C<CFLAGS>
differently based on a regular expression match on the
architecture flags.
As a final example, some pieces of information are easier to access
directly from perl than from makepp. For example, you can access all of
the configuration information that perl knows about your
system
,
including how to build shared libraries, etc. (Type
S<C<perldoc Config>>
if
you want to see what configuration information
perl
has
available.)
perl_begin
$ARCH
=
$Config
{
'archname'
};
$CC
=
$Config
{
'cc'
};
$SHARED_OBJ_CFLAGS
=
$Config
{
'cccdlflags'
};
$SHARED_OBJ_LDFLAGS
=
$Config
{
'ccdlflags'
} .
" "
.
$Config
{
'lddlflags'
};
$SHARED_CC_LINK
=
$Config
{
'ld'
};
$SHARED_EXTENSION
=
$Config
{
'dlext'
};
perl_end
%.o: %.c
$(CC) $(CFLAGS) $(SHARED_OBJ_CFLAGS) -c $(input) -o $(output)
libmylib.$(DLEXT): *.o
$(SHARED_CC_LINK) $(inputs) -o $(output) $(SHARED_OBJ_LDFLAGS)
Note how we define a bunch of variables in the perl block, and then we
use
them afterwards in the rest of the makefile. You can
use
the full
power of the perl interpreter to set your variables in arbitrarily
complicated ways. You can run shell commands from your perl code,
access a database, or whatever you want.
=item perl I<perlcode>
=item makeperl I<perlcode>
This is the same as C<perl_begin>, but using Perl-style braces. The first
variant is plain Perl code,
while
the second variant first passes the
statement through Make-style variable expansion. Note that the difficulty of
parsing Perl's braces
has
lead to the following simple heuristic:
=over
=item *
If a double opening brace is found on the same or
next
line, a double closing
brace will terminate the block. It must be at the beginning of a line, but
may be preceded by whitespace.
=item *
Else,
if
the closing brace is at the very end of the C<perl> line this is a
one liner.
=item *
Otherwise the closing brace must be at the very beginning of a following line,
i.e.
no
leading whitespace.
=back
For an efficient way to call Perl scripts, see
L<C<run>|makepp_extending/run_script_argumentsmakepp_extending/run>. Unlike
the L<C<$(perl)>|makepp_functions/perl_perlcode> function, the
return
value of
this block is ignored.
perl {
print
"passed this point in the makefile\n"
}
perl
{
print
"and this one too\n"
;
}
ifdef NOISY
perl {{
print
"as well as this one\n"
}}
endif
You can
use
the Perl debugger
for
your embedded code, by running makepp itself
in the debugger, where ... are the arguments,
if
any, you normally pass:
perl -d -S mpp ...
It is hard to set breakpoints in Perl code that
has
not been loaded. You can
work
around
this by putting this line into your embedded Perl, just
before
where you want to break:
$DB::single
= 1;
Then you can type C<c> at the debugger's prompt, to
continue
till that point.
=item
sub
=item makesub
This statement provides a way to define a perl subroutine inside your
makefile. The first variant is plain Perl code,
while
the second variant
first passes the statement through Make-style variable expansion. The syntax
is identical to that of the perl
sub
statement, except that prototypes are
meaningless.
For the three possibilities of putting the braces of the body, see the
explanation at the C<perl> statement.
A perl subroutine is invoked whenever a statement is seen, or
when
an
expression like S<C<$(name words)>> is seen. For example, suppose that
for
some reason you need to load the contents of a file into a make
variable. (You could
do
this by saying S<C<$(shell cat filename)>> but
it's possible to
do
it without ever invoking the shell.) This can be
done by placing the following into your makefile:
sub
f_file_contents {
my
(
$file
) =
@_
;
open
my
$fh
,
$file
or
die
"$file: $!\n"
;
local
$/ =
undef
;
<
$fh
>;
}
ifdef NEWSUB
makesub f_VAR2
{{
$(VAR) * 2;
}}
endif
makesub f_VAR1 { $(VAR) + 1 }
Now,
with
this function
defined
, you can
write
X = $(file_contents filename)
and the variable C<$(X)> will fetch the contents of the
given
file every
time
it gets expanded. Use C<:=> to
do
this exactly once, or C<;=> to
do
this at
most once.
See L<makepp_extending>
for
more details and examples.
=back
=head2 Simple Statements
=over 4
=item autoload I<filename ...>
Specifies one or more makefiles to load should an attempt to find a rule
for
a file in this directory otherwise fail.
This is useful
when
the makefile
has
rules whose definitions depend (possibly
indirectly) on a file in another directory that depends (possibly indirectly)
on other files in this directory (built by rules that
do
I<not> depend
on the file in the other directory).
For example, your F<Makeppfile> might look like this:
rules-to-build-files-that-otherdir/x-depends-on
more_rules.makeppfile: otherdir/x
action-to-build-more_rules.makeppfile
autoload more_rules.makeppfile
Note that we cannot reliably replace C<autoload>
with
C<include> here,
because
if
something other than the rule
for
F<more_rules.makeppfile>
tries to build F<otherdir/x> first, then F<more_rules.makeppfile> will
probably fail because F<otherdir/x> won't exist yet, because there is
already an attempt to build it underway
when
F<Makeppfile> is implicitly
loaded on its behalf.
WARNING: Be very careful about doing things in an autoloaded makefile that
change the behavior of rules in the directory's other makefileZ<>(s), as this
will cause that behavior to depend on whether or not some previously built
target caused makefiles to be autoloaded.
=item build_cache I</path/to/build/cache>
Specifies a path to a build cache. See L<makepp_build_cache>
for
details.
The build cache must already exist; see
L<makepp_build_cache/How to manage a build cache>
for
how to make it in the
first place. A C<build_cache> statement in a makefile overrides the
C<--build-cache> command line option
for
rules in the makefile, but it may be
overridden by the C<:build_cache> rule modifier on a per-rule basis.
Specify C<none> instead of a path to a directory
if
you want to disable
the build cache
for
all rules in this makefile.
=item build_check I<build_check_method>
Specifies the
default
build check method
for
all rules in this
makefile. See L<makepp_build_check>
for
details. The C<build_check>
statement overrides the C<--build-check-method> command line option
for
all rules in the makefile, but may be overridden by the C<:build_check>
modifier on a per-rule basis.
=item export I<VAR ...>
=item export I<assignment>
export PATH := $(PWD):$(PATH)
Marks the
given
variables
for
export to subprocesses. See L<setting
variables|makepp_variables/Setting variables inside a makefile>.
=item global I<VAR ...>
=item global I<assignment>
global MYPROJECT.INFO = info to be seen in all makefiles
Marks the
given
variables as global to all makefiles. See L<setting
variables|makepp_variables/Setting variables inside a makefile>.
=item include I<makefile>
This inserts the contents of another makefile into the current makefile. It
can be useful
if
you have boilerplate files
with
a number of rules or
variables, and
each
directory only needs to make a few modifications. The
C<include> statement also used to be commonly used in traditional makes in
conjunction
with
automatic include file scanners, but this is
no
longer
necessary
with
makepp.
C<include> first considers the current directory, then the parent of the
current directory, then its parent, etc. It stops considering
directories
when
it reaches the root of the file
system
or
when
the file
system
device ID changes. (This means that it will not find files
located in other NFS mounts. This is to prevent problems
with
network
file systems or automounters and dead servers.) If it does not find a
file of the
given
name by the
time
its search is stopped, then it looks
in the makepp data directory (F</usr/
local
/share/makepp>
if
you
installed makepp in F</usr/
local
>)
for
one of the include files that
comes
with
makepp.
If you want to include a template file in every makefile in a whole
directory hierarchy, you can place your makefile template at the top
directory. The makefiles
do
not have to know exactly where they are in
the hierarchy;
each
makefile can contain a line like this:
include standard_definitions.mk
instead of something more complicated, like this:
include ../../../standard_definitions.mk
You can specify as many files as you want, and variables are allowed:
include file1 file2 file3 $(other_include_files)
If you're working on a build that needs to work
with
both GNU make and
makepp, sometimes it's convenient to have exactly identical makefiles
but a different include file. For example, all of your makefiles may
contain a line like this:
include $(TOPDIR)/standard_rules.mk
and you want F<standard_rules.mk> to be different
for
GNU make and
makepp. To facilitate this, the C<include> statement B<first> looks
for
a file
with
the suffix of F<.makepp>
before
looking
for
the file you
asked
for
. In this case, it would first look
for
a file called
F<standard_rules.mk.makepp>, and
if
that
exists
, it would load it
instead of F<standard_rules.mk>. This way,
when
you run the makefile
with
GNU make, it loads F<standard_rules.mk>, but
with
makepp, it loads
F<standard_rules.mk.makepp>.
=item _include I<makefile>
A minor variant on C<include>, the C<_include> statement includes the file
if
it
exists
but doesn't generate a fatal error
if
it does not. The C<_include>
statement used to be important
for
include file scanning
with
GNU make, but is
seldom useful
for
makepp.
=item load_makefile I</some/directory/somewhere/Makefile>
=item load_makefile I<subdir>
=item load_makefile I<VAR1=value1 VAR2=value2 subdir>
This statement causes makepp to cd to the directory containing the makefile
and load its rules into makepp's internal database. If you specify just a
directory instead of a makefile, C<load_makefile> looks
for
C<Makeppfile>,
C<makefile>, or C<Makefile> in that directory.
Any variables you specify
with
the syntax C<VAR=value> (or S<C<VAR="value1
value2">>) are passed to the loaded makefiles. They
override
any settings in
those makefiles, just as
if
you had typed them on the command line.
Using C<load_makefile> is different from the command
include dir/makefile
in two ways. First, C<load_makefile> does not transfer any variables from the
top-level makefile into the subordinate makefile;
each
makefile
exists
in its
own namespace. The subordinate makefile cannot influence the variables in the
top-level makefile in any way.
Second,
each
build command is tagged
with
the directory of the makefile that
it came from. When makepp executes a rule from a different makefile, it first
cd's to the directory containing that makefile
before
executing the command.
Makefiles which are seen
with
the C<include> statement are actually treated as
part of the makefile that included them, and therefore their rules are not
tagged
with
a different directory.
You usually
do
not have to load a makefile explicitly,
unless
it
has
an
unusual name, or it
has
targets which are not contained in the same
directory as the makefile itself, or you have disabled implicit makefile
loading. By
default
,
if
makepp is trying to build a file and doesn't
have a rule to build it, or
if
it is evaluating a wildcarded filename in
a directory, it will automatically attempt to load a makefile from that
directory. See L<makepp_cookbook/Tips
for
multiple directories>
for
info on building
with
multiple directories.
You cannot
use
C<load_makefile> to load several makefiles that apply to the
same directory. Use C<include>
for
several pieces of the makefile that apply
to the same directory, and C<load_makefile>
for
makefiles that apply to
different directories.
=item no_implicit_load
This statement turns off L<implicit loading|makepp_build_algorithm/Implicit
loading> of makefiles from a set of directories. This can be useful
if
you
want to load makefiles automatically from most directories, but there are some
directories which
for
various reasons you
do
not want makepp to attempt to
update. (E.g., maybe the directory
has
a makefile
for
some other version of
make which makepp does not understand.) For example,
no_implicit_load dir1 dir2/*
The above statement will turn off implicit loading
for
makefiles
in C<dir1> B<and all of its subdirectories>. It
will also turn of implicit makefile loading
for
all subdirectories
of C<dir2> (and all of their subdirectories), but not
for
C<dir2> itself.
You may
use
wildcards in the statement. Non-directory files that
match the wildcard are ignored. You can also
use
functions to further
specify the directories that you are interested in, e.g.,
no_implicit_load $(filter-out dir1 dir2, *)
will turn off implicit loading
for
all subdirectories except F<dir1> and
F<dir2> and their subdirectories.
=item prebuild I<target>
=item make I<target>
The arguments (which undergo Make-style variable expansion) are built
immediately. This is useful
when
the list of targets that the Makefile can
build depends on a generated file in another directory.
Currently, it will quietly fail to build targets
if
there is a dependency
loop among the prebuilt targets and the Makefiles that must be loaded to
build them, but that ought to be treated as an error.
=item register_scanner I<command_word scanner_name>
Registers the C<scanner_name> (which usually begins
with
prefix
"scanner_"
that can be omitted here) as the command parser
for
commands whose base name
is C<command_word>. In the name you can
use
C<-> interchangeably
with
C<_>.
The predefined scanners are documented in L<makepp_scanning>.
=item register_command_parser I<command_word class_name>
Register an anonymous subroutine that constructs and returns an object of
exact type Mpp::CommandParser::C<class_name> as the command parser
for
commands whose base name is C<command_word>.
=item register_input_suffix I<command_word suffix ...>
Add C<suffix> ... to the list of input file suffixes recognized
when
an
action beginning
with
C<command_word> is scanned. The scanner would
normally pick this up via Mpp::CommandParser::input_filename_regexp, but it
might instead ignore this entirely.
Mpp::Scanners don
't normally pick up all the arguments that aren'
t recognized as
options, because they might be arguments of unrecognized options.
(For example, F<i386v> is I<not> an input file of the command C<gcc -b i386v foo.c>.)
Instead, they pick up only positional arguments that look like input filenames.
It is not unusual to
use
standard tools
with
site-specific nonstandard suffixes
in order to signify that those files
require
special handling, such as
different command options and/or postprocessing steps. For example:
register_input_suffix cpp .vpp
%.v: %.vpp
cpp $< > $@
=item repository I<directory>
=item repository I<destdir=srcdir>
Specifies one or more L<repository directories|makepp_repositories>.
The first repository specified
has
precedence over the others
if
the
same file
exists
in multiple repositories and there is
no
build command
for
it. See L<makepp_repositories>
for
more details about repositories.
If you specify just a directory
after
C<repository>, its contents are
linked into the current directory. You can
link
its contents into any
arbitrary place in the file
system
by specifying the location
before
an
equals sign, e.g,
repository subdir1/subdir2=/users/joe/joes_nifty_library
You should put the repository statement near the top of your makefile,
before
any rules that may need to
use
it.
=item runtime I<program,library>
Store C<library> as a runtime dependency of C<program>.
Both C<program> and C<library> may contain multiple words, in which case
each
word in C<library> is stored as a runtime dependency of
each
word in
C<program>.
When C<program> is added automatically as the executable dependency
of a command by the C<Mpp::CommandParser> base class, its runtime dependencies
(
if
any) are added as well.
In order
for
this to happen, C<program> must be specified in the rule
with
a directory component, and without any shell meta characters.
The purpose of this statement is to capture dependencies on libraries and
other executables that are often loaded by the program, without having to
specify them explicitly as dependencies of
each
rule that invokes C<program>,
or to scan C<program> to determine those dependencies (which could be
prohibitively difficult.)
Runtime dependencies are traversed recursively, so
if
C<a>
has
a runtime
dependency on C<b> and C<b>
has
a runtime dependency on C<c>, then any rule
that uses C<./a> will have implicit dependencies on both C<b> and C<c> (
unless
it uses a special C<Mpp::CommandParser> class that overrides this behavior).
Note that missing dependencies won't necessarily be added
after
you add this
statement to a makefile,
unless
the rule is re-scanned.
Use the C<--force-rescan> command line option to ensure that this happens.
=item signature
signature md5
signature c_compilation_md5
signature
default
Overrides the
default
signature method
for
all rules following the
C<signature> statement. This overrides the signature method specified
on the command line
with
C<-m> or C<--signature-method>, but does not
override
signature methods specified
with
the C<:signature> rule
modifier.
Specify S<C<signature
default
>> to
return
to makepp's
default
, either
the builtin
default
or the
default
specified on the command line.
For more information about signature methods, see L<makepp_signatures>.
=back
=head2 Commands
All builtin and self
defined
commands (see L<builtin commands|makepp_builtins>
and L<extending makepp|makepp_extending>), as well as external cleanly
programmed perl scripts can be used like statements. In this case they differ
from rule actions in that they run in the same process as makepp and any input
or output files are not noted as dependencies or as having been built by
makepp.
As
with
all statements, they are considered as such,
if
they are indented less
than the actions of the previous rule,
if
any.
This can be used
for
messages to be output
while
reading the makefile:
&echo
The value of $$(VAR) is $(VAR)
Or instead of making many rules
each
depend on a directory creation rule, you
can simply create it on the fly. Note that commands which create files are
processed again every
time
the makefile is
read
., That's why we protect this
one
with
a test -- though in this special case that would not be necessary, as
this command would
do
no
harm
when
repeated:
ifperl !-d
'include'
&mkdir
-p include
endif
=head1 AUTHOR
Gary Holt (holt-makepp
@gholt
.net)