Nokia nmake Product Builder
Customer Support Newsletter

http://www.bell-labs.com/project/nmake/newsletters/

Issue No. 14 - April 2003
Highlights
  1. Current Work
  2. Support for Windows NT/2000
Technical Notes
  1. Jar Rules Update
  2. Stray Lock Files
  3. lu3.5 -I flags
Tidbits
  1. Exporting Variables to the Shell
  2. Tracing Rule Dependencies
  3. Newsletter Feedback
Contacts
email: nmake@alcatel-lucent.com (tech support)
email: software@alcatel-lucent.com (licenses/orders)
web: http://www.bell-labs.com/project/nmake/


Highlights

Current Work

We are currently working on release lu3.6. Besides several enhancements and fixes release lu3.6 will have enhanced java support, including concurrent batched java compilations and built-in support for creating jar files. The jar rules from the newsletters will no longer be needed as the new rules include a number of enhancements over the old, newsletter rules. We are also working on a port to Windows® NT/2000. See the Windows NT/2000 article below for more information.

index

Support for Windows NT/2000

nmake release lu3.6 is being ported to Windows NT/2000. This will be the first time nmake is available for a Windows based platform. The Windows port is being done using AT&T's UWIN (UNIX for Windows) product. UWIN will be required, and must be obtained separately, to run this port. We are using UWIN from Wipro Technologies.

A Call for Beta Testers

We hope to start beta testing the win32 port in April. If you are interested in beta testing please contact us at nmake@alcatel-lucent.com. Since this is a very new platform for us we would like to get as much feedback as possible.

Other Platforms

We would like to know what other win32 based platforms you are interested in. If you have a need to run nmake on Cygwin, MKS Toolkit, or other UNIX environments for Windows please let us know at nmake@alcatel-lucent.com so can evaluate demand for these platforms.

index


Technical Notes

Jar Rules Update

The jar rules originally posted in issue 5 have had a minor update to deal with a problem reported in the field. When the jarred class files are not inside a java package directory, class files with a dollar sign ($) in their name are not included in the jar file because the shell expands $name as a shell variable when passing the filenames to the jar command.

Even though release lu3.6 will include jar support, an update for these rules are being provided for those who are not in a position to upgrade and still need the old rules. You can download the new jar rules and see Creating Jar Files for details on using the rules.

Here is an example of the problem. Notice a$xyz.class, c$x.class, c$y.class, and c$z.class are all missing in the generated jar file. Note that this only happens when the class files are not contained in a java package directory.

$ cat Makefile 
include jarrules.mk
JARROOT = classes
:ALL: abc.jar
abc.jar :JAR: classes

$ ls classes
a$xyz.class  b.class      c$y.class    c.class
a.class      c$x.class    c$z.class

$ nmake
+ mkdir -p abc.tmpjar
+ cp classes/a$xyz.class abc.tmpjar/a$xyz.class
+ cp classes/a.class abc.tmpjar/a.class
+ cp classes/b.class abc.tmpjar/b.class
+ cp classes/c$x.class abc.tmpjar/c$x.class
+ cp classes/c$y.class abc.tmpjar/c$y.class
+ cp classes/c$z.class abc.tmpjar/c$z.class
+ cp classes/c.class abc.tmpjar/c.class
+ cd abc.tmpjar
+ jar cf ../abc.jar a.class a.class b.class c.class c.class c.class c.class

$ jar tvf abc.jar
   403 Mon Apr 14 14:36:22 EDT 2003 META-INF/MANIFEST.MF
     8 Mon Apr 14 14:36:20 EDT 2003 a.class
     8 Mon Apr 14 14:36:20 EDT 2003 b.class
     8 Mon Apr 14 14:36:20 EDT 2003 c.class

Here is the same example using the updated jar rules. The missing class files are now included.

$ nmake
+ mkdir -p abc.tmpjar
+ cp classes/a$xyz.class abc.tmpjar/a$xyz.class
+ cp classes/a.class abc.tmpjar/a.class
+ cp classes/b.class abc.tmpjar/b.class
+ cp classes/c$x.class abc.tmpjar/c$x.class
+ cp classes/c$y.class abc.tmpjar/c$y.class
+ cp classes/c$z.class abc.tmpjar/c$z.class
+ cp classes/c.class abc.tmpjar/c.class
+ cd abc.tmpjar
+ jar cf ../abc.jar a$xyz.class a.class b.class c$x.class c$y.class c$z.class c.class

$ jar tvf abc.jar
   917 Mon Apr 14 14:42:08 EDT 2003 META-INF/MANIFEST.MF
    12 Mon Apr 14 14:42:08 EDT 2003 a$xyz.class
     8 Mon Apr 14 14:42:08 EDT 2003 a.class
     8 Mon Apr 14 14:42:08 EDT 2003 b.class
    10 Mon Apr 14 14:42:08 EDT 2003 c$x.class
    10 Mon Apr 14 14:42:08 EDT 2003 c$y.class
    10 Mon Apr 14 14:42:08 EDT 2003 c$z.class
     8 Mon Apr 14 14:42:08 EDT 2003 c.class

index

Stray Lock Files

We have had a few reports of nmake's .ml lock files not being removed after the build is finished. The behavior has been unpredictable and thus not easy to reproduce or study. At this point it appears to have only affected people using their own recurse rules rather than the default :MAKE: operator. We have had success in eliminating the problem by adding the special atoms .LOCAL and .RECURSE.SEMAPHORE as prerequisites to the definitions of the custom recurse rules. If you experience this problem and it is not practical for you to convert to :MAKE:, make sure your recurse rules are defined with these special atoms and please contact us about your status or to get more help.

index

lu3.5 -I flags

Many people have reported they get redundant -I flags on the compile lines after upgrading to release lu3.5. This problem occurs when the native compiler supports -I- (nmake will use the native preprocessor instead of nmake cpp,) and the code includes files using a directory prefix (eg. #include "prefix/file.h").

In the following example you see one -Iinclude/stc for each file in include/stc included by stc/hello.h:

$ cat Makefile 
CC = /opt/exp/gnu/bin/gcc
.SOURCE.h : include
hello :: hello.c

$ cat hello.c
#include "stc/hello.h"
#include <stdio.h>
int main(){
    printf("hello worlds\n");
    return(0);
}

$ ls include/stc
a.h      b.h      c.h      hello.h

$ nmake
+ /opt/exp/gnu/bin/gcc -O -Iinclude -Iinclude/stc -Iinclude/stc -Iinclud
e/stc -I- -c hello.c
+ /opt/exp/gnu/bin/gcc -O -o hello hello.o

This problem was introduced from an enhancement in lu3.5 to support prefixinclude for native compilers and will be fixed in lu3.6. In the mean time the old behavior (pre-lu3.5) can be restored by setting prefixinclude=0 in the makefiles or on the command line. You may also need to add the prefix directory to .SOURCE.h as shown below.

$ cat Makefile 
CC = /opt/exp/gnu/bin/gcc
prefixinclude = 0
.SOURCE.h : include include/stc
hello :: hello.c

$ nmake 
+ /opt/exp/gnu/bin/gcc -O -Iinclude -Iinclude/stc -I- -c hello.c
+ /opt/exp/gnu/bin/gcc -O -o hello hello.o

index


Tidbits

Exporting Variables to the Shell

Sometimes it is convenient to export nmake variables to the shell. There are three ways this can be accomplished.

MAKEEXPORT

The MAKEEXPORT feature was introduced in release lu3.3, but had a critical fix in lu3.4-p01. Using MAKEEXPORT is the easiest way to export nmake variables to the shell environment. MAKEEXPORT is a variable containing a colon separated list of variables to be exported to the shell. The specified variables will be exported in every shell action including both user defined rules and predefined nmake rules.

$ cat Makefile 
ABC = abc
XYZ = xyz
MAKEEXPORT = ABC:XYZ

test.x : test.v
        mytool $(*) > $(<)

$ nmake
+ ABC=abc
+ XYZ=xyz
+ export ABC XYZ
+ mytool test.v
+ 1> test.x

In the Action Block

Another method is to explicitly export a variable in the action block that needs the shell variable. This works well if the variable is needed only for some specific tool for which you have very few action blocks defined. If the variable is needed any many actions throughout the build this method becomes difficult to manage.

$ cat Makefile 
ABC = abc
XYZ = xyz

test.x : test.v
        export ABC=$(ABC)
        export XYZ=$(XYZ)
        mytool $(*) > $(<)

$ nmake
+ export ABC=abc
+ export XYZ=xyz
+ mytool test.v
+ 1> test.x

.ACTIONWRAP

The final solution is to use .ACTIONWRAP, which was introduced in release lu3.2. .ACTIONWRAP allows you to wrap commands around all actions that are sent to the shell. This includes both user defined rules and predefined nmake rules. Note, if you are using the output serialization feature (ie. makelog) then you should avoid this method because .ACTIONWRAP is already being used to support output serialization.

$ cat Makefile 
ABC = abc
XYZ = xyz

.ACTIONWRAP:
        export ABC=$(ABC)
        export XYZ=$(XYZ)
        $(@)

test.x : test.v
        mytool $(*) > $(<)

$ nmake
+ export ABC=abc
+ export XYZ=xyz
+ mytool test.v
+ 1> test.x

index

Tracing Rule Dependencies

Here is a technique for tracing through rule dependencies to find all generated class files, including secondary class files, given a list of java source files. It also illustrates two useful but currently undocumented nmake features. We plan to document these features in a future version of the reference and user manuals.

Assume we are processing a list of java files, and we need to obtain a list of the associated class files. For example, we might want to build a jar containing all of the class files. Due to a requirement of the java language we know that the java compiler will always generate x.class from a source file x.java. However, the java compiler may generate additional class files since each class goes into its own separate class file. For example, inner classes and secondary, non-public top level classes will each go into their own class file. Consequently simply transforming the .java suffix into .class is not sufficient to produce all generated class files. For the same reason, suffix-driven metarules are not sufficient by themselves to properly manage java builds. .JOINT rules provide one way to correctly specify this one-to-many dependency relationship:

a.class a1.class : a.java .JOINT

The standard :JAVA: assertion defined in JAVA.mk automatically generates dependencies like these by scanning java source. Here is a complete example showing :processjava:, a user-defined assertion that needs to find the list of associated class files from a list of java files specified on the right hand side.

$ cat Makefile
":processjava:" : .MAKE .OPERATOR
	print javafiles=$(>)
	print classfiles=$(<$(>:D:B:S=.class))

targ:
	silent print done

a.class a1.class : a.java .JOINT

b.class b1.class b2.class : b.java .JOINT

c.class : c.java .JOINT

d.class : d.java

:processjava: a.java b.java c.java d.java

$ nmake
javafiles=a.java b.java c.java d.java
classfiles=a.class a1.class b.class b1.class b2.class c.class d.class
done

The first step is straightforward: $(>:D:B:S=.class) transforms the list of java files into the same list with each suffix changed to .class. This is guaranteed to find an associated class target due to the java rule that the source filename must be constructed from the class name. We then expand the single class target into the complete list of jointly generated targets using the < automatic variable applied to the known class target. This use of the < variable to find all jointly generated targets for a non-active target is not currently documented. Another undocumented usage illustrated here is the application of an automatic variable to a token list rather than just a single target.

index


Newsletter Feedback

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.

index

<<home / newsletters