This document compares and contrast the features of GNU make version 3.75
and nmake version 3.x.
The intention here is to facilitate Lucent software development product teams
in deciding on the tool that best fits their environment.
The strength and weakness of both tools are outlined and compared.
A GNU make to nmake makefile conversion example is provided to
give users an idea of the mapping of the features of both tools and the ease
of the conversion effort.
This table provides a summary of the similarities of GNU make and
nmake.
This table provides a summary of the differences between GNU make and
nmake. It is not exhaustive. The intent was to highlight those
areas where one would be likely to assume similarities and point out features
present in one and absent in another that seem to be of significance.
| GNU make |
nmake |
| MAKEFILE PROCESSING |
-
Interprets the makefile at each
execution.
|
-
Compiles the makefile and recompiles
only if the original is altered.
|
RE-MAKING TARGETS |
-
Has no knowledge of any previous run and must infer out-of-date
targets by checking time stamps of targets and prerequisites.
|
-
Creates a statefile and uses the data in it to decide whether a target
is out of date.
|
PREPROCESSING |
|
|
-
Uses a new C preprocessor for makefile
and C files, if requested.
|
COMMAND EXECUTION |
-
Each command line is executed by a
new subshell. To get multiple lines
executed by 1 subshell terminate
each command line (except the last)
with a ';' and a '\'. Default shell
is /bin/sh.
|
-
Each shell action is sent as a unit
(cf shell script) to the subshell.
Default shell also /bin/sh.
|
AUTOMATIC DETECTION OF DEPENDENCIES |
-
NO MECHANISM to scan a file and detect
implicit dependencies. For
example, included header files of
C files MUST BE EXPLICITLY specified
as dependencies in the makefile.
|
-
Has a powerful dynamic dependency generation
mechanism that scans a source
file for its implicit prerequisites--
file and preprocessor variable references.
A great benefit of this
mechanism is the fact that it is
automatic and programmable - the scan
can be extended to detect dependencies
in new programming languages.
For example C/C++ files: header files
referenced with #include would become
implicit file prerequisites while
variables defined with a #define,
implicit state variable prerequisites
of the files scanned by nmake.
Hence, they would NOT need to be
explicitly specified as prerequisites
of the source file, in the makefile.
|
SEARCHING DIRECTORIES FOR DEPENDENCIES |
-
VPATH Variable -- a colon or blank
separated list of directories to
be searched - cf. nmake's patternless
.SOURCE special atom.
No notion of a "node" as in nmake.
|
-
VPATH Variable -- a colon-sep list of
"nodes" to be searched. A node may be
seen as a product's directory structu-
re that accounts for proper directory
partitioning of its source and
destination (built) files. The whole
structure usually can be referenced
through a root node -- may be seen as
an inverted tree.
|
-
"vpath" Directive -- colon or blank
separated list of directories which
allows one to search for files that
match a particular pattern.
|
-
.SOURCE Atoms -- a blank-sep list of
directories searched for files. It has
pattern and no pattern forms and is
used in conjunction with VPATH (when
set).
|
INCLUDING OTHER MAKEFILES |
-
include Directive -- used to include
other makefiles. It is of the form,
[-]include filenames ....
where '-' tells make not to give an
error if specified filename was not
found.
|
-
include Directive -- used to include
other makefiles. It is of the form,
include [-] filenames ...
where '-' tells nmake not to generate
a warning if the specified filename
was not found.
|
-
The search -- if the specified file
did not start with a '/' and is not
found in PWD, then it searches a
specified list of -Idir options and
the following directories;
/usr/local/include, /usr/gnu/include,
/usr/local/include and /usr/include.
|
-
The search -- uses .SOURCE atoms to
search for file (Note: PWD is always
searched first).
|
-
filenames Syntax -- may be shell file name patterns.
|
-
filenames Syntax -- no patterns or wildcards.
|
A SPECIAL METARULE |
|
|
-
Not available - however, may be
implemented in nmake with .USE rule.
|
OPERATIONS ON VARIABLES |
-
Variable values may be tested and
modified by a set of builtin func-
tions (over 20 in v3.76) - of the
form, $(function arguments)
There are functions for string
substitution & analysis, filenames,
repetitive substitution and testing
the origin of a variable. For
example, the following assigns all
but the directory part (basename
and suffix) of the filename in VAR1
to VAR2 (VAR2 becomes "myfile.c"):
VAR1 = ../mydir/myfile.c
VAR2 = $(notdir $(VAR1))
|
-
Comes with a powerful set of what it
terms 'edit operators' (over 60), that
allows one to test and modify variable
values during expansion - of the form,
$(variable[:[@]edop[sep arg]]...)
Using the same example to set VAR2
from VAR1 would be,
VAR1 = ../mydir/myfile.c
VAR2 = $(VAR1:B:S)
|
VARIABLES (Used by Engine) |
-
From the environment -- by default
vars from the env have a lower
precedence than those in the makefile,
but may be overridden by the
-e flag.
|
-
From the environment -- always have a
lower precedence than those defined in
user makefile, but higher than those
defined in a project-defined global
rules and the standard base rules (Makerules.mk).
|
-
Common Variables
- MAKEFILES
- env. variable whose
definition is used as a list of
names of additional makefiles to
be read before the default or
specified one.
- MAKECMDGOALS
- set by make to the
list of goals/targets specified
on the command line.
- CFLAGS
- used to pass extra flags
to the C compiler of the built-in
implicit rule for compiling a C
program. This is built into the
make engine.
|
-
Common Variables
- MAKEFILES
- an engine var. whose default
value is 'Makefile:makefile', a
colon-sep list of candidate implicit
makefile names.
- $(*.ARGS)
- the prerequisites of the
special atom .ARGS are the list of
targets specified on the command line
- CCFLAGS
- variable used to pass extra
flags to the C/C++ compilers for the
metarules defined in the base rules
(NOT the engine!) that compiles C/C++
source files.
|
AUTOMATIC VARIABLES |
-
Form -- can evaluate single character
automatic variables without
parentheses.
|
-
ALL variables require parentheses!
|
-
$@ File name of current target.
If target is archive member,
$@ is archive file.
|
-
$(<) Current target in all cases.
$(@) Action for the current target.
|
-
$? All the prerequisites newer
than the target.
|
-
$(>) Current out-of-date file
prerequisites in all cases.
$(?) All prerequisites of current
target.
|
-
$* The stem in a pattern rule definition.
|
-
$(*) All file prerequisites of current target.
|
-
$^ All the current prerequisites.
$~ Not available.
$< The name of the first prerequisite.
|
-
$(~) All explicit prerequisites of current target.
|
-
$% The target member name when
target is an archive member
|
-
$(%) The file name portion matched by
'%' in a metarule definition.
|
|
|
-
$(!) All explicit and implicit prereqs
of current target.
|
-
$+ Like $^, but prerequisites
listed more than once are
duplicated in the order
listed in the makefile.
|
-
$(+) The current option settings
suitable for use by the 'set' option.
|
USING THE VALUE OF A VARIABLE AS A PREREQUISITE |
|
|
-
nmake not only allow targets to have
file prerequisites but also variable
prerequisites. It calls such variables
STATE VARIABLES and saves its value
and modification time (in the state-
file) for subsequent update requests.
These variables are useful in defining
a command and its associated flags,
such as $(CC) and $(CCFLAGS) for a
C compiler. They also play a vital
role in nmake's scan for implicit
prerequisites.
|
RECURSIVE MAKES |
|
|
-
Implementation -- with the :MAKE:
operator, as follows,
subsystem :MAKE: subdir
|
-
Sub-make Communication --
MAKEFLAGS - used by make to pass
flags/options to the sub-make.
Environment - explicit export
of variables to the environment
using 'export' directive.
|
-
Recursive make communication --
$(-) and $(=) -- used to pass flags and
variables to recursive make.
Environment - also read by sub-make.
|
DISTRIBUTED BUILDS |
|
|
-
Uses a network shell coprocess server
(coshell) that establishes shell co-
processes to other homogenous
machines within a LAN, sending user
jobs (commands) to them to be
executed. A working UNIX® system and
TCP/IP are required.
|
DOUBLE COLON RULE |
-
The rules of targets with multiple
:: rules are independent of each
other. Each rule is executed only
if the target is older than any
dependencies of that rule. This
may result in none, any or all of
the :: rules being executed.
|
-
Most commonly used assertion operator,
the source dependency operator. It is
a set of predefined base rules that
simplifies making an executable or
archive target from a list of source
files.
|
-
When used in a pattern rule it
makes the dependencies terminal
(not intermediate) files.
|
|
COMPUTED VARIABLE NAMES |
|
|
|
ATTRIBUTE DIFFERENCES |
-
- .IGNORE
- when making the dependencies
of the .IGNORE special
target, make will ignore all exit
codes from commands executed for
making those files.
|
-
- .DONTCARE
- an assertion attribute
that causes nmake to continue if it
cannot make the target that has this
attribute.
- .IGNORE
- an attribute that forces target generation.
|
-
- .PHONY
- a special target whose
dependencies are considered
to be phony targets.
|
-
- .VIRTUAL
- targets with this attribute
are considered virtual/phony targets.
|
VARIABLE DEFINITION USING OUTPUT OF SHELL COMMANDS |
|
|
|
-
Using the 'shell' function --
The shell function does what back-
quotes do in most shells - command
expansion. That is, it takes an
argument which is a shell command and
returns the output of the command.
So the above example could be written
mydotcees := $(shell cd $(MYDIR); ls *.c)
|
|
HIGH-LEVEL ACCESS TO CANNED BASIC ASSERTIONS |
-
None available -- GNU make does
NOT possess any feature to define
canned assertions as it does
canned command sequences.
|
-
nmake provides "macro-like" assertion
operators that define various funcio-
ionalitites, using a sequence of ':'
dependency operators. Not only does
nmake define various useful ones in
its base rules (See Chapter 11 of the
Reference Manual) it also allow users
to define their own.
|
COMMON ACTIONS |
-
All targets must be explicitly
defined in the user's makefile,
including the common targets/actions
such as 'install', 'clean', 'all'.
|
-
nmake realizes that targets such as
'install', 'clean', 'all' represents
actions that are frequently done by
users. Hence, the user doesn't have
to define these targets in the
makefile - nmake provides them.
Common actions are specified on the
command line. So to remove all
generated intermediate files, issue
$ nmake clean
For a list of nmake's common actions
see Chapter 3 -- 'Common Actions'
(pgs. 3-21 to 3-30) of the Reference
Manual.
|