If there is a source file (such as ./source.c
) and there are two
SCCS files corresponding to it (./s.source.c
and
./SCCS/s.source.c
), on XSI-conformant systems make uses the SCCS
file in the current directory. However, users are advised to use
the underlying SCCS utilities (admin, delta, get, and so on) or
the sccs utility for all source files in a given directory. If
both forms are used for a given source file, future developers
are very likely to be confused.
It is incumbent upon portable makefiles to specify the .POSIX
special target in order to guarantee that they are not affected
by local extensions.
The -k
and -S
options are both present so that the relationship
between the command line, the MAKEFLAGS variable, and the
makefile can be controlled precisely. If the k
flag is passed in
MAKEFLAGS and a command is of the form:
$(MAKE) -S foo
then the default behavior is restored for the child make.
When the -n
option is specified, it is always added to MAKEFLAGS.
This allows a recursive make -n
target to be used to see all of
the action that would be taken to update target.
Because of widespread historical practice, interpreting a
<number-sign> ('#'
) inside a variable as the start of a comment
has the unfortunate side-effect of making it impossible to place
a <number-sign> in a variable, thus forbidding something like:
CFLAGS = "-D COMMENT_CHAR='#'"
Many historical make utilities stop chaining together inference
rules when an intermediate target is nonexistent. For example, it
might be possible for a make to determine that both .y.c
and .c.o
could be used to convert a .y
to a .o
. Instead, in this case,
make requires the use of a .y.o
rule.
The best way to provide portable makefiles is to include all of
the rules needed in the makefile itself. The rules provided use
only features provided by other parts of this volume of
POSIX.1‐2017. The default rules include rules for optional
commands in this volume of POSIX.1‐2017. Only rules pertaining to
commands that are provided are needed in an implementation's
default set.
Macros used within other macros are evaluated when the new macro
is used rather than when the new macro is defined. Therefore:
MACRO = value1
NEW = $(MACRO)
MACRO = value2
target:
echo $(NEW)
would produce value2 and not value1 since NEW
was not expanded
until it was needed in the echo command line.
Some historical applications have been known to intermix
target_name and macro=name operands on the command line,
expecting that all of the macros are processed before any of the
targets are dealt with. Conforming applications do not do this,
although some backwards-compatibility support may be included in
some implementations.
The following characters in filenames may give trouble: '='
, ':'
,
'`'
, single-quote, and '@'
. In include filenames, pattern
matching characters and '"'
should also be avoided, as they may
be treated as special by some implementations.
For inference rules, the description of $< and $? seem similar.
However, an example shows the minor difference. In a makefile
containing:
foo.o: foo.h
if foo.h
is newer than foo.o
, yet foo.c
is older than foo.o
, the
built-in rule to make foo.o
from foo.c
is used, with $< equal to
foo.c
and $? equal to foo.h
. If foo.c
is also newer than foo.o
,
$< is equal to foo.c
and $? is equal to foo.h foo.c
.
As a consequence of the general rules for target updating, a
useful special case is that if a target has no prerequisites and
no commands, and the target of the rule is a nonexistent file,
then make acts as if this target has been updated whenever its
rule is run.
Note:
This implies that all targets depending on this one will
always have their commands run.
Shell command sequences like make; cp original copy; make may
have problems on filesystems where the timestamp resolution is
the minimum (1 second) required by the standard and where make
considers identical timestamps to be up-to-date. Conversely,
rules like copy: original; cp -p original copy will result in
redundant work on make implementations that consider identical
timestamps to be out-of-date.
This standard does not specify precedence between macro
definition and include directives. Thus, the behavior of:
include =foo.mk
is unspecified. To define a variable named include, either the
white space before the <equal-sign> should be removed, or another
macro should be used, as in:
INCLUDE_NAME = include
$(INCLUDE_NAME) =foo.mk
On the other hand, if the intent is to include a file which
starts with an <equal-sign>, either the filename should be
changed to ./=foo.mk, or the makefile should be written as:
INCLUDE_FILE = =foo.mk
include $(INCLUDE_FILE)