Released: July 2006
1.1 Supported Hardware
1.2 Hardware Requirements
1.3 Software Requirements
1.4 Customer Support
2. New Features and Significant Enhancements
2.1 Introduction of new platform support: Red Hat Enterprise Linux 3, Solaris 10
2.2 Improved support for Sun C++ 7.x and 8.x compilers
2.3 :JAVA: performance enhancements
2.4 Support for Java builds from a directory other than the source package directory
2.5 Java builds filter out #empty files
2.6 globaljavadeps and localjavadeps are synchronized via the state file
2.7 MS Visual C++ compiler supported on Windows/SFU
2.8 New environment variable UMASKCHANGE to disable umask change
2.9 nmakelog now compatible with :JAR: makefiles
2.10 Enhanced manifest file support for :JAR:
2.11 Multiple :JAR: makefiles can update the same target jar file
3. Bug Fixes and Enhancements
4. Changes Impacting lu3.7 Makefiles
4.1 :JAR: Appending to an Existing Jar File
4.2 disableumaskchange Option Deprecated
5. Known Problems and Remarks
5.1 Known Problems
This document announces the new release of nmake version lu3.8. nmake is fully supported and is in wide production use throughout Lucent Technologies, AT&T, and elsewhere.
These lu3.8 Release Notes discuss in detail the new features, and highlight bug fixes, additional enhancements, and known problems.
The lu3.8 release has been ported to many UNIX-based and UNIX-like systems. For a current list see the Availability Chart on the nmake web site, http://www.bell-labs.com/project/nmake/. Or contact the Customer Support helpdesk below.
This release of nmake is available for HP-UX, Linux, Solaris, and Windows (under SFU/Interix). See the release lu3.8 download page for a listing of available distribution packages. nmake is generally upward compatible with later OS releases in a series (for example, the series Solaris 2.5 through 2.10); contact Technical Support with any compatibility questions or with any requests for porting to other systems.
The Windows-based version of nmake is based on the Windows Services for UNIX (SFU/Interix) porting/development environment from Microsoft and requires installation of the SFU package in order to run. The SFU package must be obtained from Microsoft and installed following their installation procedure. For more information see the Support for Windows page.
nmake lu3.8 provides dependency-based Java build support. This feature currently requires an external Java source scanner called JavaDeps to extract inter-modules dependencies from Java source. nmake lu3.8 requires JavaDeps release lu2.2.2; this version is downloadable from the nmake JavaDeps page. Installation instructions are also on that page. THIS PACKAGE IS ONLY REQUIRED BY PROJECTS PERFORMING JAVA BUILDS USING THE :JAVA: ASSERTION OPERATOR. JavaDeps release lu2.2.2 is itself written in Java; it requires jdk1.2.1 or higher version on its PATH in order to run. (Note that this does not restrict the project being built to jdk1.2.1 or higher.)
We provide patch support, where code changes are required, for the latest 2 point releases of nmake (currently releases lu3.8 and lu3.7). Customers using older releases can still acquire help in using the product, but genuine problems found in older releases will not be fixed. Such problems may require an upgrade to a current release or, when possible, a makefile work-around will be provided.
Fee-based services are also available. These include makefile rewrites, conversion of non-nmake makefiles to nmake, integration with vendor tools, build assessments, and porting nmake to new machines.
Contact Customer Support for any questions regarding nmake.
Release lu3.8 has been officially tested and verified on two additional platforms, Solaris 10 (sometimes referred to as 2.10) and Red Hat Enterprise Linux 3.
Support for Sun's SUNWCCh include rule has been enhanced and better supports
the 7.x and 8.x compilers. The probe variable
CC.SUFFIX.LINKHEADER has been added to list the system headers
with versions ending with SUNWCCh so nmake can bind and scan the proper
headers when scanning source code. Headers that are rewritten with
the SUNWCCh rules are also now retained in the state file so they are
known for subsequent builds.
The Java rules have been optimized for the common case resulting in a significant performance improvement when processing large Java packages. Before the optimization a particular operation in the Java rules was observed to take about 24 minutes for a Java package of about 18,000 Java source files. After optimization this operation was actually eliminated for the common build resulting in a drastic reduction in time for processing the package.
A second optimization is user controllable using the
base rule variable. The variable contains the maximum number of Java
source files in a Java package in order to determine and warn of source
files that have been removed in an incremental build. The default is
maxjavawarn=3000 meaning a Java package of 3000 or less
source files will warn the user when Java source files are removed in
an incremental build (since their old classes may still exist). The
check is skipped and no warning issued if there are more than 3000 source
files in the package. The package of 18,000 source files mentioned above
took approximately 15 minutes to check for deleted files. Projects can
maxjavawarn variable to emphasize either performance
or the warning notice. Also see the
:JAVA: manual page for information
:JAVA operator now supports building Java code where
the package root is in a different directory from the makefile and
.SOURCE.java is used to locate the package root. Here is
an example makefile:
/**** obj/Makefile ****/ JAVABUILDDIR = $(VROOT)/obj JAVAPACKAGEROOT = $(VROOT)/java .SOURCE.java : $(JAVAPACKAGEROOT) :JAVA: com
Since Java source files are not typically listed in the makefile they cannot simply be removed from the makefile to be removed from the build. Deleting a Java source file will eliminate that file from a build. However, in a viewpathing situation where versions of the deleted file remain in other viewpathed nodes, those unwanted versions will still be picked up. The #empty feature provides a way to remove a Java file from a build and also mask out viewpathed files in other nodes.
:JAVA: operator will filter Java source files
containing the string "#empty" out of the build. The contents of
a source file can be changed to "#empty", masking out old versions
of the file in the viewpath, when it should no longer be built.
Source files changed to "#empty" in an incremental build will have the
contents of their class files changed to "#empty" effectively removing
the class and masking out old versions in the viewpath.
:JAR: operator will also exclude Java source files
containing the string "#empty" when creating a jar archive of source
files. By default class files are not scanned nor filtered to eliminate
any performance impact for projects not using the feature. Class files
can be filtered from jar archives by including the following in the
.ATTRIBUTE.%.class : .SCAN.java
See the :JAVA: and :JAR: manual pages for details.
are now stored in the state file. If either file changes or is removed
outside of nmake the file will be automatically regenerated to return it
to a trusted state.
globaljavadepsis touched or removed then it is regenerated from a full rescan of the Java source code.
localjavadepsis touched or removed then it is regenerated from the existing
The Microsoft Visual C++ compiler is now supported on the Windows/SFU
(Services for Unix/Interix) platform using the Interix
compiler wrapper. The wrapper and environment must be configured
according to Interix requirements.
disableumaskchange option name and
line option have been removed and replaced with the environment variable
UMASKCHANGE. The change is due to the need to set the umask
early in nmake startup before the options are read.
must be set in the environment not in the makefiles.
UMASKCHANGE may be 0/NO/no to suppress changing the umask to
match the current directory permissions, or 1/YES/yes/null to change the
umask. For compatibility the umask change is enabled by default. Any
UMASKCHANGE value generates a warning and keeps the
umask change enabled.
nmakelog output serializer is now compatible with
The manifest file in a
:JAR: assertion now triggers updates
when the manifest file is touched or when a different manifest file is
specified. If multiple manifest prerequisites are specified the first
one is used and others are ignored with a warning message.
:JAR: makefiles can update the same target jar
file by setting the new nmake variable
By default the jar target is recreated by each makefile thereby
losing the archive members from the previous makefile. Set
jarappend=1 in the makefile to add members to an
existing jar without losing its contents.
ppccto drop the
-Iflags when calling the compiler when linking. This caused errors when the
-Iflags were needed for template instantiation. This has been fixed by passing the
ppcc -lflag when the probe variable
::) operator; the variable
sharedlibvers=0is set. This is fixed so the executable is now re-linked as expected when
cleancommon action now removes
.ofiles on AIX platforms.
.SUNWCChsuffix header files. The new probe variable
CC.SUFFIX.LINKHEADERhas been added to support this, which contains the system headers with versions ending with SUNWCCh.
/bin/cccompiler wrapper. The compiler wrapper calls GNU ld automatically to do the linking since VC++ does not support it. GNU ld must be in the PATH.
:LIBRARY:was used to make the library; the executable was made from the same makefile as the library; and
-g. This has been fixed so the executable now links with the updated library in the local node.
<new.h>would build fine the first time but give an error about not finding
new.h.SUNWCChin the second build. This was caused by
.SUFFIX.INCLUDEattribute after the initial run. This has been fixed by retaining the
.SUFFIX.INCLUDEin the state file so it can be used when binding the include files in subsequent builds.
.REQUIRE.+l%function now returns
+lname only for the parent required library. Previously all the required libraries were transformed from
+lwhich may not be appropriate and is error prone since additional archive libraries may be picked up that were not intended, including system libraries.
LINE_MAXwhich is usually 2048 but may vary by platform.
:P=L=xedit operator was resolving some files to the wrong viewpath node which resulted in an error from
:JAR:complaining that files didn't begin with
JARROOT. The problem occurred when a file down the viewpath, but not in the last node, was added to .SOURCE.pattern and then .SOURCE.pattern was cleared. Then
:P=L=xreturned the file when
xwas one level deeper in the viewpath than where the file really exists. This problem has been fixed.
-Ilist, which could lead to an unexpected compile error during incremental builds. This has been fixed.
vpath" would be executed any time a shell job was run. This was a result of the
disableumaskchangeoption added in release lu3.7 (the option did not need to be set to see the problem). The
disableumaskchangeoption has been deprecated and replaced with the
:JAVA:operator is now regenerated if it is deleted outside of nmake. Additionally, both the localjavadeps and globaljavadeps files are now maintained by the state file and regenerated when necessary.
:JAR:operator an existing jar target file would be updated if it had no state information. For example, if an old jar was lying around, building it would append to it rather than regenerate it and could result in old, unwanted archive members in the jar. Now by default such jar files will be regenerated from scratch so the old contents are lost and only the members from the current build are archived. The old behavior can be restored by setting
jarappend=1which also allows multiple makefiles to maintain a single jar file.
:JAR:rules were initializing
JARFLAGSto null thus erasing any user settings.
JARFLAGSis no longer initialized and if set by the user
:JAR:will add the flags to the jar operations.
:JAR:, removing the jar target file without doing a
clobberor removing the state file no longer causes an error on the next build.
:JAR:operator indexed the jar file after generating it by running
jar i /full-path/file.jar. This index operation would fail for some jar files that contain a manifest which defines Class-Path. This has been fixed by not generating the index with the full path to the jar but instead changing directory to the jar file and specifying the file name with no path information on the command line.
:JAVA:makefiles that have no associated Java source files.
--vpathflag passed to JavaDeps by the
:JAVA:operator has been changed to accommodate Javadeps release lu2.2.2. The path specified now is each viewpath root node (like the
VPATHenvironment variable) instead of the current directory expanded through the viewpath.
:LIBRARY:operator is now correct when using the MS VC++ compiler on Interix.
:JAR:operators now filter Java source files containing "#empty" out of the build. This can be used to mask old, unwanted Java files that still exist in the viewpath but should no longer be built.
:JAVAoperator to build Java code located under a different directory from the makefile and using
.SOURCE.javato locate the package root, each Java source file would be passed to JavaDeps multiple times, expanded once for each node in the viewpath. This has been fixed.
:JAR:operator is now compatible with the nmakelog output serializer.
:JAVA:operator, Java packages with certain inner classes could result in an error from the
touchcommand while the package was being prepared to be compiled. This was caused by some of the class directories not being created before
touchwas called and has been fixed.
:JAVA:operator which result in significant speed up for very large Java packages. The new
maxjavawarnvariable can be used to control part of the optimization.
:JAR:operator no longer recurses the directory tree for explicit files specified on the right hand side with no shell pattern. Since the file is explicitly identified the recursion is not necessary to locate the file. Previously this would cause large delays when specifying files at the top of a tree since all the sub-directories were needlessly searched. Now a recursion is triggered only when a shell pattern is specified somewhere in the path.
:JAR:operator would attempt to re-index the jar file when everything was already up to date. An error would occur if the jar was down the viewpath and not in the current node. This has been fixed.
:JAVA:operator no longer generates an unexpected error when
JAVACis defined with some command line flags (e.g.,
JAVAC = javac -g).
JARROOTdirectory exists down the viewpath and not in the local build node.
:JAVA:operator would re-run JavaDeps without specifying any Java files when everything was up to date. This has been fixed so JavaDeps is not re-run.
:JAVA:to build a large Java package with multiple batch compiles the last batch was not triggered resulting in an incomplete set of class files. This has been fixed.
:JAR:fixes found in beta test. When two jar files are built in one makefile, the second jar includes the first jar and the jar targets are not in the current directory a JARROOT error occurred when updating the jars in a new viewpath node. Under the same conditions using the clobber common action would result in an unexpected error. Both issues have been fixed.
LD_LIBRARY_PATHto include in the
CC.STDLIBprobe variable. This has been fixed.
cutfrom the PATH instead of
/bin/cutwhich may not exist on all platforms.
_LONG_LONGnow is properly defined in the pp probe script for the AIX C compiler.
logfiltercommands on Solaris no longer depend on the
CC.SUFFIX.LINKHEADER- see 040085.
jarappend- see 040007.
maxjavawarn- see 050054.
UMASKCHANGE- see 050063.
disableumaskchange- see 050063.
The changes in release lu3.8 are largely backward compatible with lu3.7. Every effort has been made to insure code changes do not unexpectedly change the documented behavior of nmake features.
The following may impact builds and require changes.
jarappend=1in your makefile.
disableumaskchangeoption has been removed. The option introduced in release lu3.7 was used to prevent changing the umask to match the current directory permissions. The setup of the umask has to be done very early, before the options are parsed, so the option was replaced with an environment variable.
NOare also accepted). The variable must be set in the shell environment not in the makefile.
.REQUIRE.+l%function may change the way required-libs used from
CC.REQUIRED.name works. Previously when the parent required-lib was referenced as
+lname all the required-libs were transformed to
+linstead of using
+lis used to prefer archive libraries over shared libraries). This is error prone since additional archive libraries may be picked up that were not intended, including version specific system platform libraries which can break portability to later versions of the platform.
libabcwhich depends on the
$ cat lib.mk CCFLAGS += $$(CC.PIC) LIBDIR = lib :ALL: abc :LIBRARY: abc.c -lsocketIf
+labcwas specified as the prerequisite to an executable then its required-libs were also changed to
libsocket.awould be pulled in instead of
$ cat app.mk .SOURCE.a : lib hello :: hello.c +labc $ nmake -f app.mk + cc -O -I- -c hello.c + cc -O -o hello hello.o lib/libabc.a /usr/lib/libsocket.a
libsocketshared library is pulled in:
$ cat app.mk .SOURCE.a : lib hello :: hello.c +labc $ nmake -f app.mk + cc -O -I- -c hello.c + cc -O -o hello hello.o lib/libabc.a -lsocket
+lname with required-libs to intentionally pick up archive libraries for all the required-libs.
+lyou can define
CC.REQUIRE.name when linking with libname to override the default required-libs. Or if you are already using
CC.REQUIRE.name define it with
+llibraries. For example, if you want
libxyzto pull in
+lzthen defining the following when linking with
CC.REQUIRE.xyz = -lxyz +lx +ly +lzSpecifying
-lxyzas a prerequisite will automatically pull in
.REQUIRE.+l%rule in the project's local rules to restore the old behavior. This is discouraged since the project will need to maintain the rule.
.REQUIRE.+l% : .FUNCTION local L L := $(.REQUIRE.-l% $(%:/+l/-l/)) return $(L:/-l/+l/:T=F)
+lwhen the required-libs are originally specified as such on the
:LIBRARY:assertion. This feature is not currently supported but is a candidate for inclusion in a future release.
The following is a list of known problems:
CC.REPOSITORYis defined, and
::is used to trigger the metarule. Note that
CC.REPOSITORYis defined automatically for some C++ compilers in the probe file. The work-around is to add
::assertion, or to not use the
::assertion (such as add the target to
%.c, the first metarule defined will be triggered instead of the metarule matching the file prerequisite suffix.
.xyzfile which is included on the command line when compiling the
$ cat Makefile %.c : %.xyz cp $(>) $(<) abc.o :: abc.xyz $ nmake + cp abc.xyz abc.c + cc -O -I- -c abc.c abc.xyzFix this by defining the %.c->%.o meta rule locally to filter out the unwanted files.
cat Makefile %.c : %.xyz cp $(>) $(<) %.o : %.c (CC) (CCFLAGS) $(CC) $(CCFLAGS) -c $(>:N=*.c) abc.o :: abc.xyz $ nmake + cp abc.xyz abc.c + cc -O -I- -c abc.c
-Iflags pointing to the system include files cause compiler errors. One work-around is to strip these
-Iflags from the command line. For example:
%.o : %.c (CC) (CCFLAGS) $(CC) $(CCFLAGS:N!=-I/opt/sc8.0a/SUNWspro*) -c $(>)
:JAR:operator uses shell patterns to pick up files to include in the jar archive. However the rules currently assume the file names include a
.suffix at the end and specifying
dir/*to pick up all files does not work correctly. Instead use
dir/*.*. To pick up files that do not include a dot specify the full filename.
.ofiles referenced with a path starting with
:JAR:operator are not rebuilt if they fail during a build using the