1.1 Supported Hardware
2. New Features Introduced in Release 3.1
2.2 Assertion Operators
2.3 Special Atoms
2.4 Edit Operators
2.5 Command Line Options
2.7 New cpp #pragma
2.8 New Variables in probe Information Files
3. Changes Impacting 3.0 Makefiles
3.1 Changes in Variables
3.2 Changes in Edit Operators
3.3 Changes in Command Line Options
3.4 Changes in probe
4. Bug Fixes
4.1 Fixes in Handling Variables
4.2 Fixes in Handling Assertion Operators
4.3 Fixes in Handling Special Atoms
4.4 Fixes in Handling Command Actions
4.5 Fixes in Scanning
4.6 Fixes in Viewpathing
4.8 A Fix in Handling Circular Dependency
4.9 Fixes in cpp
4.10 Fixes in probe
5. Known Bugs and Remarks
5.1 Known Bugs
This release includes support for the AT&T's C++ 4.0 translator and Sun's C++ template instantiation feature. This document discusses in detail the new features, explains the changes affecting 3.0 makefiles, highlights bug fixes as well as outstanding problems.
There are some incompatibilities between nmake 3.0 and 3.1. Section 3 provides a summary of the incompatibilities.
The 3.1 release has been ported to many UNIX-based systems. For a current list, contact the nmake Customer Support hotline at 908-582-5880, or send email to firstname.lastname@example.org.
The following new features are included in this release.
This new automatic variable is expanded to the number of actual arguments in the following constructs:
local -[n] arg ... local (formal ...) actual
F1 : .FUNCTION local (a b c) $(%) print $(#) F2 : .FUNCTION local - a b print $(#) t : $(F1 1 2 3) $(F2 1 2)
This example will return the number of actual arguments, 3 and 2. This can be used to get local function arguments (a b c) and set their values from the actual arguments into $(%).
This new automatic variable replaces of the previous semantics of $(#). It is expanded to the state variable value of the current target while the current target is a state variable. For example:
XX = bin (XX) : a.c : XX is $(;)
The rhs of :MAKE: now accepts directory names containing path name prefixes. For example:
:MAKE: ../d1 /actual/path/d2 d3/a
.ALARM is an immediate rule atom. It sets an alarm signal in seconds during nmake execution. For example:
.ALARM : 15
sets an alarm signal 15 seconds after the nmake execution. You can specify interrupt handling for the alarm signal. The value of $(.ALARM) is the absolute time to the next alarm; a value of 0 indicates no alarm.
.COMPDONE is a sequence atom. Its action is executed right after the makefile is compiled. .COMPDONE is skipped if the compiled makefile, *.mo, is not changed.
This is a sequence atom for handling a specified signal. Signals including SIGILL, SIGIOT, SIGEMT, SIGBUS, and SIGSEGV cannot be caught. Here is an example:
.INTERRUPT.INT: .MAKE error caught interrupt return 0 .INTERRUPT.ALRM: .MAKE error caught alarm .ALARM: 10 sleep: sleep 30
This example handles an alarm signal that is set for 10 seconds after the nmake execution, and handles any interrupt signals. The return value of the signal hander determines whether processing continues. A return of -1 forces process termination. Repeating alarms can be set by reinitializing .ALARM within the signal handler. For the above example, if we hit the interrupt key twice during the execution, the output will be:
+ sleep 30 caught interrupt caught interrupt caught alarm
.SYNC is a new immediate rule atom which is for synchronizing the statefile. It can be used with .ALARM to periodically set a checkpoint to synchronize the statefile for long builds. The usage is:
.INTERRUPT.ALRM: .MAKE print "Synchronizing Statefile" .SYNC : .ALARM: 60 /* repetitive alarm */ .ALARM : 60 /* initial alarm */
This example synchronizes the statefile every 60 seconds.
This atom eliminates optimization for the local scope, that is, -O is removed from CCFLAGS.
t1 :: a.c b.c .CC.NOOPTIMIZE t2 :: c.c d.c
The t1 will be built without optimization, but t2 will be optimized.
This edit operator can now select target tokens with specific prerequisite patterns. The syntax is :A>pattern.
LIST = x y z x : a.c b.c y : a.c c.x z : c.x tst : : $(LIST:A>*.c)
: x y
because the targets x and y have .c files as prerequisites.
The :F can now be used to specify format for time output. The syntax is :F=%(format)T. For example:
t : : $("806273016":F=%(%a %m-%d-%y %H:%M:%S)T)
: Thu 07-20-95 16:43:36
This edit operator returns physically bound tokens. For example:
FILES = a.c b.c t : a.c : $(FILES:P=B)
produces : a.c since a.c is bound and b.c is not.
This new edit operator, :T=QV, returns defined variables. For example:
LIST= A B C A==1 B= b.c t : : $(LIST:T=QV)
: A B
$("":T=R) now operates on the current date. The time can be printed out by using :F edit operator.
t : : $("":T=R:F=%(%a %m/%d/%y %H:%M:%S)T)
: Thu 07/20/95 15:56:14
The syntax of this new edit operator is :T=Z[CERS]. It returns the time of "cancel", "event", "relative", or "state" for the input token. These times are used during the nmake processing.
FILE = a.c t : $(FILE) : $(*:T=ZC:F=%(%a %m-%d-%y %H:%M:%S)T) : $(*:T=ZE:F=%(%a %m-%d-%y %H:%M:%S)T) : $(*:T=ZR:F=%(%a %m-%d-%y %H:%M:%S)T) : $(*:T=ZS:F=%(%a %m-%d-%y %H:%M:%S)T)
The output will be
+ : Wed 12-31-69 19:00:00 + : Fri 07-21-95 01:29:33 + : Fri 07-21-95 01:29:33 + : Thu 07-20-95 14:43:25
There is no cancel time, so the output from the :T=ZC operator indicates the Epoch time. The event time is the time that file a.c is found. The relative time is the current rule time. The state time is the last modification time of a.c, which is recorded in the state file.
This command line option can also be written as -o believe=level, which means to believe the statefile information for in the views >= level are unchanged. This is an optimization for projects that can certify that official files in the views >=level are up to date and have not been changed, while there may be only a few files on the top level and a large number of files on the lower levels. Using the option avoids the stat(2) on the lower level files and saves significant time in some cases.
The syntax of -M is now
Here, static is for generating mamfiles, dynamic is for tracing nmake execution steps, and regress is for canonicalizing regression testing on different hosts. Output appends to file. label is the label number prepended to each mam output line (usually the process ID), and root specifies that all files listed are relative to this root directory. noport inhibits porting hints. dontcare lists targets that contain the .DONTCARE special atom.
This command line option can also be written as -o never, which stands for "never execute." The difference between -n and -N is that -N overrides .ALWAYS.
This new command line option expands actions in the target directory when the target name contains a directory prefix. For instance, if a target has a directory prefix a/b/c.o, then this target will be generated in the context of the prefix directory as
cd a/b <action>
This allows assertions like
system :: a/b/c.c c/d/c.c
which would normally generate a conflict with ./c.o, but with this option the two c.o files will be generated in the a/b and c/d directories.
The print construct is for handling output messages. The syntax of print is
print -n -u[0-9] -f format [+-]o file data ...
The options are the following: -n adds a trailing null character at the end of output string. -u[0-9] sends output to the file descriptor as specified, that is, 0, 1, and 2 mean stdin, stdout, and stderr. -f format, specifies output format. The format is a C printf-like format string. [+-]o file specifies output file, file. -o file opens file for writing while +o file opens file for appending. data is the output string data.
Here are several examples:
print -u2 -f "test #1: %s" "output string"
produces the output string, test #1: output string, in stderr.
print -f "test #2: %s" -o outfile "new output string"
puts the output string, test #2: new output string, into the file called outfile. Note, since print parses options, if you want to print a string of dashes ("-"), you should explicitly mark the end of options by using "--", such as
print -- ------------------
Also note, +o file will leave the file as append mode. So the subsequent print statement will write output into file as well. You can use
print -o -
to direct output into stdout again. Here is an example:
message1 : .MAKE print Running $(<) print +o xxx print this is a test written to xxx message2 : .MAKE print this is another test written to xxx message3 : .MAKE print -o - print this message should go to the screen
The read construct reads input from a file, and then assigns the content of the file to a variable. The syntax is:
read -i file variable
The -i file is for specifying the input file, where variable is the variable that the contents of file will be assigned to. For example, if infile contains a string of file names, a.c b.c c.c, then,
read -i infile X
reads the contents of infile, the string of file names, and assigns it to X.
#pragma pp:plussplice is added for non-standard backslash. In the C++ code such as,
// comments \ static int x = 3;
the second line is a part of the comment when this pragma is specified.
In the "make" part of probe file, CC.ARFLAGS is added for certain compilers that also generate libraries (e.g. Sun's C++ compiler). CC.DIALECT now has the values of DOTI, and TOUCHO. DOTI indicates that the compiler accepts *.i files as preprocessed input. TOUCHO indicates that the compiler may touch *.o files - this supports AT&T's C++ 4.0 translator's implementation of the template instantiation feature. CC.REPOSITORY is also added for the fixed prepository directory name generated by certain compilers, such as Sun's C++ compiler. CC.SUFFIX.[ARCHIVE|COMMAND|OBJECT|SHARED|SOURCE|STATIC] are added to identify different suffixes of file names to associate with different types of files.
nmake now supports AT&T's C++ 4.0 and Sun's C++. AT&T's C++ 4.0 puts the instantiated templates back into the .o file. nmake now handles the time stamping change for the instantiated .o files. Sun's C++ compiler does the template instantiation at compile time and generates a fixed directory name for the repository, Template.DB. Sun's C++ compiler also builds archive and shared libraries with instantiated templates information. Now nmake supports all of these special situations.
This tool is located in the bin directory of nmake package. It is the replacement for ccc in nmake 3.0. This tool is automatically used when a compiler does not provide a way to use an alternate cpp. ppcc manages to use cpp to preprocess input files and then hands the output from cpp to the compiler to do the rest of the compilation.
hostinfo is located in the bin directory of nmake package. It generates host information for coshell. The usage is
hostinfo [ cpu debug name rating regress type ... ]
For example, on a Sun sparc machine called "agape" running Solaris, the command
hostinfo name type rating
agape sol.sun4 20
$(#) has new semantics in nmake 3.1. The old semantic of $(#) now is $(;). See Section 2.1.1 and Section 2.1.2.
The variable CCC is changed to PPCC in the base rules file. The usage of $(CCC) now is replaced by $(PPCC).
$("":D) no longer produces "." as the return value.
The syntax of -M is changed. The new syntax is described in Section 2.5.2. -M no longer implies -nF and -M with -o expandview no longer refers to static and port. The usage of
nmake -M -o expandview -k
The -o mamtrace (-m) option has been deleted from nmake 3.1.
The variable CC.OBJ has been changed to CC.SUFFIX.OBJECT. The variable CC.SO has been changed to CC.SUFFIX.SHARED. CC.DIALECT no longer has PTREPOSITORY as its value.
The nmake construct, local, now accepts syntax as
The rule .DO.l.cc has been deleted from the base rules. C++ lex code should be processed by a lex that can handle C++ code.
The following bugs were in nmake 3.0 and now fixed in nmake 3.1:
The value of variables assigned on the command line does not remain in the .mo files to affect subsequence of nmake execution. For example,
nmake CCFLAGS=-g nmake
for the above sequence of execution of nmake, the -g flag in CCFLAGS only affect the first issue of nmake, but won't now affect the second issue of nmake.
:INSTALLDIR: now handles rhs files with relative path name.
$(ETCDIR) :INSTALLDIR: ../../../a
The value of the variables with .REMAIN special atom is now handled correctly in viewpathing.
The common action, clobber, can correctly clobber when there is more than one -g option on the command line, such as
nmake -g rules1.mk -g rules2.mk clobber
Parsing problem that when special symbols, like $ and : appeared in include statements, as in
has been fixed.
For generated files, the scanning now occurs after the files are generated. The correct -I flags are now produced correctly for generated header files in viewpathing.
The problem of rebuilding libraries when some .o files are not removed after archiving has been fixed. Now handles the change of the prerequisites of archive targets properly. It deletes the .o files from the archive targets in the top view when those .o's are no longer dependencies of the targets.
The -ptr flags are now given correctly for C++ template instantiation at link time in viewpathing.
The problem of having one extra directory level in $(VROOT) has been fixed.
The problem of re-generating .JOINT multiple targets in viewpathing has been fixed.
The -I list in CCFLAGS now is according to all the prerequisites of current target, not just according to the first prerequisite.
The metarule %:%.c now works for C++ files.
The problem of handling aliasing when, for example, a and ../X/a are the same file has been fixed.
The circular dependency assertion such as
a.h : a.c <generate> $(<)
where a.h is a dependency of a.c is now handled correctly.
The following is a list of known bugs:
.SOURCE.mk : incl include "global.mk"The B node is built by using the "global.mk" in the B node. Then, the A node is built by using the "global.mk" in the A node. If the "global.mk" in A is removed, nmake cannot detect that "global.mk" is changed when the A node is built again.
nmake -Iinclor to avoid using .SOURCE.mk in the makefile and use: