Issue No. 13 - December 2002
|
Patch level 01 for lu3.5 is now available for download. The patch overlays lu3.5. Installation is automated and includes an option to back-out the patch and restore your nmake installation to its previous state. For details see the lu3.5-p01 patch page.
The following files are affected:
Here is a summary of the lu3.5-p01 fixes:
A JavaDeps update release, JavaDeps-lu2.0.3,
coincides with the lu3.5-p01 patch release. JavaDeps is an optional package
and only required for projects building Java code using the nmake supplied
:JAVA: operator. Although the JavaDeps update
does not require the lu3.5 patch, there are several java related fixes in
the lu3.5 patch so we recommend upgrading both for projects currently
using nmake with JavaDeps. For details see the
JavaDeps page and the
lu3.5-p01 patch page.
JavaDeps lu2.0.3 includes the following fixes:
We have recently verified nmake lu3.4 and lu3.5 on Solaris 2.9 and found
no major problems. It is safe to run nmake on Solaris 2.9. However,
you should be aware that the system sorting routines in 2.9 are sensitive
to the locale for category LC_COLLATE. Since nmake uses the system
sorting routines the :H and :L edit operators
may produce unexpected sort results. Exporting LC_COLLATE=C
in the shell environment will give you the traditional UNIX sort behavior.
Notice the sort order on Solaris 2.6:
$ uname -sr SunOS 5.6 $ sort list a.h aa.h b.h bb.h
Now notice Solaris 2.9 gives different result until LC_COLLATE is set:
$ uname -sr SunOS 5.9 $ sort list aa.h a.h bb.h b.h $ export LC_COLLATE=C $ sort list a.h aa.h b.h bb.h
If you are using Solaris 2.9 and you have nmake rules sensitive to sort order
we recommend you set export LC_COLLATE=C in your build environment
for consistency across platforms. We plan to address this in the next release
so sort results from nmake are consistent by default.
Update 12/04/2002:
Gary Sitzmann wrote in to tell us the defaults can be changed system wide,
for all users, by setting the LC_ variables to C
in file /etc/default/init on Solaris 2.8 and 2.9. Thanks Gary!.
The nmake team recently transitioned our JavaDeps build to use the standard
:JAVA: operator. Since we started working with the JavaDeps
code before our java support was implemented we initially used some
interim nmake rules for building the java code. Here we will take a look
at our before and after results of the transition.
The original makefile was about 48 lines without comments and white-space. By design it rebuilt all the java code when anything changed since dependencies were not being tracked. It also generated the jdeps.jar file and the source and binary distribution tar files. The generation of the jar and tar files required all the class and distribution files to be in the same node, so building incrementally in the viewpath did not work too well. The original makefile can be seen below.
/*
* Original Makefile for JavaDeps package
*/
PACKAGE := JavaDeps
VERSION := lu2.0.3
distDir := $(PACKAGE)-$(VERSION)
clobber = 1
/*
* Directory variables
*/
INSTALLROOT = $(VROOT)/prod
SRCDIR := $(INSTALLROOT)/src
CLASSDIR := $(INSTALLROOT)/bin
DOCDIR := $(INSTALLROOT)/doc
/*
* Tools variables
*/
JAVAC = javac
JAVACFLAGS = -d $(CLASSDIR)
JAR = jar
/*
* Source files variables
*/
grammarFile := Java1.2.jj
grammarSrcs := Java.java JavaConstants.java JavaTokenManager.java \
ASCII_UCodeESC_CharStream.java ParseException.java \
Token.java TokenMgrError.java
jdepsSrcs := DepTable.java ParseOptions.java InvalidOptionException.java \
JavaDeps.java ParameterEnumeration.java JarZipTable.java \
SyntaxDecoration.java
jfiles := $(grammarSrcs) $(jdepsSrcs)
distSrcs := $(grammarFile) $(jfiles)
distDocs := native.html usage.html welcome.html win95.html grammar-mods
distMisc := jdeps Makefile README.jdeps synconfig ChangeLog \
BUGS COPYING MANIFEST.MF INSTALL
distFiles := jdeps.jar README.jdeps synconfig COPYING jdeps INSTALL
TARSRC = $(INSTALLROOT)/$(distDir)-src.tar
TARBIN = $(INSTALLROOT)/$(distDir).tar
.SOURCE : $(VROOT)/src/java $(VROOT)/src/doc
:ALL: $(INSTALLROOT)/jdeps.jar - .INSTALL - $(TARSRC) $(TARBIN)
/*
* Make jdeps.jar
*/
$(INSTALLROOT)/jdeps.jar : MANIFEST.MF .javafiles
cd $(CLASSDIR)
date
$(JAR) cmf $(*:N=*.MF:P=A) $(<:D=..:B:S) smr
ls -l $(<:D=..:B:S)
.javafiles : $(jfiles) .JOINT .VIRTUAL
$(JAVAC) $(JAVACFLAGS) $(*)
$(DOCDIR) :INSTALLDIR: $(distDocs)
$(SRCDIR) :INSTALLDIR: $(distSrcs)
$(INSTALLROOT) :INSTALLDIR: $(distMisc:N!=jdeps)
$(INSTALLROOT) :INSTALLDIR: jdeps mode=555
/*
** the tar files cannot be generated through the viewpath.
** a full build needs to be in the current node.
*/
$(TARSRC) $(TARBIN) :JOINT: $(distSrcs) $(distDocs) $(distMisc)
rm -f $(<)
cd $(INSTALLROOT)
tar chf $(<:O=1:D=..:B:S) .
tar chf $(<:O=2:D=..:B:S) $(distFiles)
mv $(<:D=..:B:S) .
/*
* clobber previously built targets
*/
.CLOBBER : .CLEAR .CLEARARGS .ONOBJECT .NOSTATEFILE
$("$(.CLOBBER.:T=F:P=L=0) $(.BUILT.:A=.REGULAR:P=L=0)":Q:K=$(IGNORE) $(R
M) $(RMFLAGS))
$(IGNORE) $(RM) -rf $(CLASSDIR)/smr
To use :JAVA: we split the makefile into four pieces. That
sounds like a lot, but the result is still much smaller and easier to
maintain. Since nmake does not yet include jar support we used the
jar rules published in newsletter
issue 5 to build both the jar and the tar
files, which recommends the jar creation to be in a separate
makefile from the java build due to nmake's directory caching.
So we have one makefile to build the class files, one for the jar file and
one for the tar file. The main makefile sets some variables and calls the
other three makefiles in sequence using the :MAKE: operator.
Below are the new files.
PACKAGE := JavaDeps VERSION := lu2.1 PKGNAME := $(PACKAGE)-$(VERSION) .EXPORT : PACKAGE VERSION PKGNAME :MAKE: java.mk - jar.mk - tar.mk
/* ** This is not a typical JAVAPACKAGEROOT setting. ** It should allow building in the official environment (which uses VROOT/src) ** or from the JavaDeps source distribution package (use VPATH=$PWD). */ JAVAPACKAGEROOT = $(VROOT:L:N=java:Y?$(VROOT)?$(VROOT)/src?) JAVACLASSDEST = classes .INSTALL : .MAIN :JAVA: java
include "jarrules.mk" :ALL: jdeps.jar jdeps.jar :JAR: classes JARROOT=classes
include "jarrules.mk" JAR = tar clobber = 1 distBIN = jdeps jdeps.jar synconfig README.jdeps COPYING INSTALL distSRC = doc java ChangeLog BUGS MANIFEST.MF \ Makefile java.mk jar.mk tar.mk jarrules.mk localjavadeps JARTYPES=* $(VROOT)/prod :INSTALLDIR: $(PKGNAME).tar $(PKGNAME)-src.tar :ALL: jdeps - $(PKGNAME).tar $(PKGNAME)-src.tar $(PKGNAME).tar :JAR: $(distBIN) $(PKGNAME)-src.tar :JAR: $(distSRC) $(distBIN)
Even though we now have four makefiles we have a total of only 23 lines (not counting comments and white-space), which is just under half the size of the original. And as you can see the resulting files are much easier to read. We have realized the following benefits from the transition:
State variables are variables whose values are stored in the state files.
By storing the values nmake can detect when they change and trigger
associated actions. One use of state variables is to generate -D
define flags for the compiler. Unfortunately, many users do not take
advantage of this feature.
Instead of hard-coding -D flags in CCFLAGS,
state variables can be defined in the makefile. When nmake scans code
for include files it also detects implicit variables and will generate
corresponding -D flags for the code that use the variables.
Using state variables has a couple advantages over hard-coding the
-D flags.
CCFLAGS will recompile
everything.-D flags are generated only for compilations that
need them. The build output will show which code actually uses which
defines.Let's take a look at an example.
$ cat Makefile
CC = /opt/exp/gnu/bin/gcc
MAX == 100
test :: main.c init.c
$ cat main.c
int main() {
init();
return(0);
}
$ cat init.c
#include <stdio.h>
int init() {
printf("MAX is %d\n",MAX);
}
$ nmake
+ /opt/exp/gnu/bin/gcc -O -I- -c main.c
+ /opt/exp/gnu/bin/gcc -O -I- -DMAX=100 -c init.c
+ /opt/exp/gnu/bin/gcc -O -o test main.o init.o
$ ./test
MAX is 100
Here you can see nmake added -DMAX=100 only for
init.c since main.c does not use MAX.
What happens if we change MAX?
$ cat Makefile
CC = /opt/exp/gnu/bin/gcc
MAX == 200
test :: main.c init.c
$ nmake
+ /opt/exp/gnu/bin/gcc -O -I- -DMAX=200 -c init.c
+ /opt/exp/gnu/bin/gcc -O -o test main.o init.o
$ ./test
MAX is 200
Notice only init.c was recompiled and it now uses the new value of
MAX.
We can also use state variables for #ifdef directives.
$ cat init.c
#include <stdio.h>
int init() {
#ifdef DEBUG
printf("debug: entering init()\n");
#endif
printf("MAX is %d\n",MAX);
}
$ nmake DEBUG==1
+ /opt/exp/gnu/bin/gcc -O -I- -DMAX=200 -DDEBUG -c init.c
+ /opt/exp/gnu/bin/gcc -O -o test main.o init.o
$ ./test
debug: entering init()
MAX is 200
This time the state variable is defined on the nmake command line. This works the same as setting it in the makefile, but is handy for making temporary changes.
And of course, if we rebuild without setting DEBUG then
init.c will be recompiled without the define set.
$ nmake + /opt/exp/gnu/bin/gcc -O -I- -DMAX=200 -c init.c + /opt/exp/gnu/bin/gcc -O -o test main.o init.o $ ./test MAX is 200
If you are still hard-coding your -D define flags
then you should try out state variables.
We are always interested in feedback! Let us know what you think of the newsletter, how we may improve, or ideas you have for future issues. Send us a note at nmake@alcatel-lucent.com. All ideas, suggestions, and comments are welcome.
<<home / newsletters