Nokia nmake Product Builder
Customer Support Newsletter

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

Issue No. 41 - August 2012
Contacts
Articles
  1. nmake 14 Released
  2. Javadeps alu2.3 Released
  3. nmake CDT Eclipse Plugin 1.0.0 Beta
  4. Customizing LDLIBRARIES
  5. Feedback and Suggestions

nmake 14 Released

We are pleased to announce availability of Alcatel-Lucent nmake 14. nmake 14 focuses on bug fixes and stability with over 25 fixes and enhancements including the following:

The release is coordinated with the release of Javadeps alu2.3 (see below) and is compatible with nmake Eclipse CDT plugin 0.5.0, both separately downloadable. With few exceptions, nmake 14 is upwardly compatible from nmake 13. See the nmake 14 Release Notes for more information including a complete list of changes from the nmake 13 release. Current customers may upgrade free of charge to nmake 14 using existing installed licenses, no license upgrade is required. See the nmake 14 release page for download information and documentation.


Javadeps alu2.3 Released

We are pleased to announce availability of Javadeps alu2.3. Javadeps is an optional package required only for projects building Java code using the nmake supplied :JAVA: operator. Javadeps alu2.3 adds support for the new Java 7 language features, including the following:

Note that previous Javadeps releases could already parse the new Strings in Switch Statements feature. For details on the language changes see Java Programming Language Enhancements in the Java 7 documentation. For Javadeps download packages and other details see the Javadeps page.


nmake CDT Eclipse Plugin 1.0.0 Beta

The beta release of the nmake CDT Eclipse Plugin 1.0.0 is targeted for release in September. The release adds nmake error parsers plus several productization enhancements to the current 0.5.0 prerelease version. Availability will be announced on the nmake web site. The plugin will be available from the nmake Eclipse plugin update site.


Customizing LDLIBRARIES

The LDLIBRARIES variable can be used to define a list of libraries to be linked to all executable targets built with the double colon (::) operator. This allows a common set of libraries to be specified once, for example in a global makefile, rather than repeating them on the right-hand-side of each executable target. Libraries specified in LDLIBRARIES are still treated as dependencies and will trigger executables to be updated when necessary. The following example shows all three targets linking with all the libraries in LDLIBRARIES.

$ cat Makefile
LDLIBRARIES = -laaa -lbbb -lccc

.SOURCE.a : $(VROOT)/lib

:ALL:

t1 :: t1.c
t2 :: t2.c
t3 :: t3.c

$ nmake
+ cc -O -I- -c t1.c
+ cc -O -o t1 t1.o ../lib/libaaa.a ../lib/libbbb.a ../lib/libccc.a
+ cc -O -I- -c t2.c
+ cc -O -o t2 t2.o ../lib/libaaa.a ../lib/libbbb.a ../lib/libccc.a
+ cc -O -I- -c t3.c
+ cc -O -o t3 t3.o ../lib/libaaa.a ../lib/libbbb.a ../lib/libccc.a

$ nmake

$ touch ../lib/libbbb.a

$ nmake -e
../lib/libbbb.a [Aug 28 15:46:08 2012] has changed [Aug 28 15:44:04 2012]
+ cc -O -o t1 t1.o ../lib/libaaa.a ../lib/libbbb.a ../lib/libccc.a
+ cc -O -o t2 t2.o ../lib/libaaa.a ../lib/libbbb.a ../lib/libccc.a
+ cc -O -o t3 t3.o ../lib/libaaa.a ../lib/libbbb.a ../lib/libccc.a

Customizing Per Target

Since LDLIBRARIES applies to all the executable targets in a makefile it isn't obvious how to customize it per target. This can be done using a function to check the current target name and return one or more libraries needed for that target. The following example links -lbbb to target names matching *_svc, -lccc to target names matching *_client and -lccc to all other targets. Notice -laaa is linked with all executables. The function uses the :N edit operator to match patterns with the current target name from the $(<<) variable. You could also customize for different directories by checking $(VOFFSET:N=pattern).

$ cat Makefile
LDLIBRARIES = -laaa $(CUSTOMLIBS)

CUSTOMLIBS :FUNCTION:
        if "$(<<:N=*_svc)"
                return -lbbb
        elif "$(<<:N=*_client)"
                return -lccc
        else
                return -lddd
        end

.SOURCE.a : $(VROOT)/lib

:ALL:

t1_svc    :: t1.c
t2_client :: t2.c
t3_cmd    :: t3.c

$ nmake
+ cc -O -I- -c t1.c
+ cc -O -o t1_svc t1.o ../lib/libaaa.a ../lib/libbbb.a
+ cc -O -I- -c t2.c
+ cc -O -o t2_client t2.o ../lib/libaaa.a ../lib/libccc.a
+ cc -O -I- -c t3.c
+ cc -O -o t3_cmd t3.o ../lib/libaaa.a ../lib/libddd.a

This works because CUSTOMLIBS does not get expanded immediately when LDLIBRARIES is set but is expanded when LDLIBRARIES is expanded for the target. It is important to note if += is used to add CUSTOMLIBS to LDLIBRARIES then the expansion of CUSTOMLIBS must be delayed with an extra "$" since += expands the right side immediately. So in this case it would look like, LDLIBRARIES += $$(CUSTOMLIBS). See Delaying Variable Expansion in issue 25 for more information.

If the target names don't lend themselves to pattern matching another option is to use attributes. In the following example an attribute is added to the right-hand-side of some targets and the function uses the :A edit operator to check the current target's attributes. Targets with the .L1 attribute get -lbbb, targets with .L2 get -lccc and other targets get -lddd.

$ cat Makefile
LDLIBRARIES = -laaa $(CUSTOMLIBS)

CUSTOMLIBS :FUNCTION:
        if "$(<<:A=.L1)"
                return -lbbb
        elif "$(<<:A=.L2)"
                return -lccc
        else
                return -lddd
        end

.L1 .L2 : .ATTRIBUTE

.SOURCE.a : $(VROOT)/lib

:ALL:

t1 :: t1.c .L1
t2 :: t2.c .L2
t3 :: t3.c

$ nmake    
+ cc -O -I- -c t1.c
+ cc -O -o t1 t1.o ../lib/libaaa.a ../lib/libbbb.a
+ cc -O -I- -c t2.c
+ cc -O -o t2 t2.o ../lib/libaaa.a ../lib/libccc.a
+ cc -O -I- -c t3.c
+ cc -O -o t3 t3.o ../lib/libaaa.a ../lib/libddd.a

It is not possible to remove libraries from LDLIBRARIES using this method. However for more control LDLIBRARIES itself can be defined as a function so the entire list of libraries is created dynamically based on the current directory, target name, etc.

LDLIBRARIES :FUNCTION:
        local L
        L =
        if "$(VOFFSET:N=src/cmd/abc)"
                L += -labc
        elif "$(VOFFSET:N=src/cmd/xyz)"
                L += -lxyz
        end
        if "$(<<:N=*_svc)"
                L += -lbbb
        elif "$(<<:N=*_client)"
                L += -lccc
        else
                L += -lddd
        end
        return $(L)

Feedback and Suggestions

We are interested in any feedback you might have about nmake. Please send comments / suggestions to nmake@alcatel-lucent.com.

We're also open to suggestions for future articles. If there is anything you would like to see in the newsletter please send us a note to nmake@alcatel-lucent.com. Thanks for your support!

<<home / newsletters