| Alcatel-Lucent nmake Product Builder | ![]() |
Released: July 2006
1. Introduction
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
3.1 Baserules
3.2 cpp
3.3 Engine
3.4 Operators
3.5 Probe
3.6 Miscellaneous
3.7 Variables
3.8 Options
4. Changes Impacting lu3.7 Makefiles
4.1 :JAR: Appending to an Existing Jar File
4.2 disableumaskchange Option Deprecated
4.3 Required-libraries
5. Known Problems and Remarks
5.1 Known Problems
5.2 Remarks
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 maxjavawarn
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
set the maxjavawarn variable to emphasize either performance
or the warning notice. Also see the
:JAVA: manual page for information
on maxjavawarn.
The :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.
The :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.
The :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
makefile:
.ATTRIBUTE.%.class : .SCAN.java
See the :JAVA: and :JAR: manual pages for details.
Information for localjavadeps and globaljavadeps
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.
globaljavadeps is touched or removed then it is
regenerated from a full rescan of the Java source code.localjavadeps is touched or removed then it is
regenerated from the existing globaljavadeps.
The Microsoft Visual C++ compiler is now supported on the Windows/SFU
(Services for Unix/Interix) platform using the Interix /bin/cc
compiler wrapper. The wrapper and environment must be configured
according to Interix requirements.
The disableumaskchange option name and -u command
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. UMASKCHANGE
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
other UMASKCHANGE value generates a warning and keeps the
umask change enabled.
The nmakelog output serializer is now compatible with
:JAR: makefiles.
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.
Multiple :JAR: makefiles can update the same target jar
file by setting the new nmake variable jarappend=1.
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.
-l flag for
ppcc which causes ppcc to drop the
-I flags when calling the compiler when linking.
This caused errors when the -I flags were needed
for template instantiation. This has been fixed by passing
the ppcc -l flag when the probe variable
CC.DIALECT contains PTRIMPLICIT.
::) operator; the variable
sharedlibvers=0 is set. This is fixed so the executable
is now re-linked as expected when force_shared=1.
clean common action now removes .o
files on AIX platforms.
.PREFIXED attribute.
.SUNWCCh suffix header files. The new probe variable
CC.SUFFIX.LINKHEADER has been added to support this,
which contains the system headers with versions ending with SUNWCCh.
/bin/cc
compiler 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 CCFLAGS contained -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.SUNWCCh in the
second build. This was caused by new.h.SUNWCCh losing the
.SUFFIX.INCLUDE attribute after the initial run. This has
been fixed by retaining the .SUFFIX.INCLUDE in 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
-l to +l which may not be appropriate and
is error prone since additional archive libraries may be picked up
that were not intended, including system libraries.
LINE_MAX which is usually 2048 but may
vary by platform.
:P=L=x edit 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=x returned the file when x was one
level deeper in the viewpath than where the file really exists.
This problem has been fixed.
-I list, 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
-u/disableumaskchange option added in release
lu3.7 (the option did not need to be set to see the problem).
The disableumaskchange option has been deprecated and
replaced with the UMASKCHANGE environment variable.
: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=1 which also allows multiple makefiles
to maintain a single jar file.
:JAR: rules were initializing JARFLAGS
to null thus erasing any user settings. JARFLAGS is 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 clobber or 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.
--vpath flag 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
VPATH environment variable) instead of the current
directory expanded through the viewpath.
:LIBRARY:
operator is now correct when using the MS VC++ compiler on Interix.
:JAVA: and :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.
:JAVA operator
to build Java code located under a different directory from the makefile
and using .SOURCE.java to 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 touch command while the package was being prepared
to be compiled. This was caused by some of the class directories not
being created before touch was called and has been fixed.
:JAVA: operator
which result in significant speed up for very large Java packages.
The new maxjavawarn variable 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 JAVAC is defined with some command line
flags (e.g., JAVAC = javac -g).
JARROOT directory
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_PATH to include in the CC.STDLIB
probe variable. This has been fixed.
cut from the PATH instead of
/bin/cut which may not exist on all platforms.
_LONG_LONG now is properly defined in the pp probe script
for the AIX C compiler.
/bin/cc wrapper.
taglines and logfilter commands on
Solaris no longer depend on the libstdc++.so and
libgcc_s.so shared libraries.
CC.SUFFIX.LINKHEADER -
see 040085.
jarappend -
see 040007.
maxjavawarn -
see 050054.
UMASKCHANGE -
see 050063.
-u /
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=1 in your makefile.
-u / disableumaskchange
option 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.
-u or disableumaskchange
option.
UMASKCHANGE=no (values
0 (zero) and NO are 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 :LIBRARY: or
CC.REQUIRED.name works. Previously when the
parent required-lib was referenced as +lname all
the required-libs were transformed to +l instead
of using -l (+l is 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.
libabc which depends on the libsocket
system library:
$ cat lib.mk CCFLAGS += $$(CC.PIC) LIBDIR = lib :ALL: abc :LIBRARY: abc.c -lsocketIf
+labc was specified as the prerequisite to an
executable then its required-libs were also changed to +l,
thus libsocket.a would be pulled in instead
of -lsocket:
$ 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
+l so the libsocket shared 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.
+l you 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 +l libraries. For
example, if you want libxyz to pull in
+lx +ly +lz then
defining the following when linking with libxyz:
CC.REQUIRE.xyz = -lxyz +lx +ly +lzSpecifying
+lxyz or -lxyz as a prerequisite
will automatically pull in +lx +ly
+lz.
.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)
+l when 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.REPOSITORY is defined, and ::
is used to trigger the metarule. Note that CC.REPOSITORY
is defined automatically for some C++ compilers in the probe file.
The work-around is to add .IMPLICIT to the ::
assertion, or to not use the :: assertion (such as add
the target to :ALL: instead.)
force_shared=1.
%.c, the first metarule defined will be triggered
instead of the metarule matching the file prerequisite suffix.
.xyz file which is included on the command line when
compiling the .c.
$ cat Makefile
%.c : %.xyz
cp $(>) $(<)
abc.o :: abc.xyz
$ nmake
+ cp abc.xyz abc.c
+ cc -O -I- -c abc.c abc.xyz
Fix 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
-I flags pointing to the system include
files cause compiler errors. One work-around is to strip these
-I flags 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.
.o files
referenced with a path starting with ../.
:JAR: operator are not rebuilt if they
fail during a build using the -k keepgoing option.