Nokia nmake Product Builder
Customer Support Newsletter

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

Issue No. 35 - August 2010
Contacts
Articles
  1. nmake 12 Released
  2. Captured Explain Data
  3. warning: ... replaced by an older version
  4. Feedback and Suggestions

nmake 12 Released

We are pleased to announce availability of Alcatel-Lucent nmake 12. nmake 12 provides several features and enhancements, including the following:

The release is compatible with Javadeps alu2.2.5 and nmake Eclipse CDT plugin 0.5.0, both separately downloadable. See the nmake 12 Release Notes for more information including a complete list of changes from the nmake 11 release.

index

Captured Explain Data

Most of us have run an incremental build and then wondered why something rebuilt that wasn't expected. nmake has always supported the explain (-e) option to show explanations for its actions, however most folks don't run all their builds with the explain option enabled and sometimes you don't realize you need it until after a build is done.

A new feature has been introduced in nmake 12 that captures the explain data in the nmake statefile. Now the explain messages can be retrieved after a build is complete without using the explain option to run the build. The data is also associated with the affected targets which provides more context than the typical explain output.

In the following example two targets are built and each source file includes its own header file. The makefile has been built once and is up to date. We update a.h and rebuild.

$ cat Makefile
CC = gcc
.SOURCE.h : include
:ALL:
abc :: a.c b.c c.c
xyz :: x.c y.c z.c

$ touch include/a.h

$ nmake
+ gcc -O -Iinclude -I- -c a.c
+ gcc -O -o abc a.o b.o c.o
+ gcc -O -Iinclude -I- -c z.c
+ gcc -O -o xyz x.o y.o z.o

Oh no, why was z.c compiled? Now we can dump the explain messages from the statefile using the list and explain options along with the file option to specify the statefile instead of the makefile.

$ nmake -lef Makefile.ms  

/* Explain */

a.o :
  include/a.h [Aug 18 14:44:14 2010] has changed [Aug 18 14:40:50 2010]

abc :
  include/a.h [Aug 18 14:44:14 2010] has changed [Aug 18 14:40:50 2010]

z.o :
  include/a.h [Aug 18 14:44:14 2010] has changed [Aug 18 14:40:50 2010]

xyz :
  include/a.h [Aug 18 14:44:14 2010] has changed [Aug 18 14:40:50 2010]

Targets z.o and xyz were updated because a.h changed. It looks like we forgot z.c also includes a.h.

This feature allows you to retroactively get the explain data for the last build. In a build where nothing is updated the explain dump will be empty. This feature is controlled by the explainlog option and is enabled by default. To disable it use --noexplainlog.

Variable Edit Operators

The explain data can be referenced in a makefile using new variable edit operators. This allows your own custom rules to output or collect the data. The variable edit operators are not affected by the --noexplainlog option.

edit operator description
$(VAR:T=QE) Query the Explain Message. Returns the explain message, if it has been set, for each token in a useful presentation format, otherwise returns null. Typically the explain message is set for targets that have been triggered.
$(VAR:T=QEU) Query the Unformatted Explain Data. Returns the raw explain data, if it has been set, for each token, otherwise returns null. Same as QE but the message is returned in a compact fielded format allowing easy extraction of data using standard nmake tokenization operations.
$(VAR:F=%(explain)S) Formats the raw explain data in a useful presentation format.

The following makefile shows a custom metarule using the :T=QE edit operator to output the reason the current target was triggered. Again the makefile is up to date and we run an incremental build.

$ cat Makefile
%.o : %.c (CC) (CCFLAGS)
        silent echo reason: $(<:Q) - $(<:T=QE:Q)
        $(CC) $(CCFLAGS) -c $(>)

CC = gcc
.SOURCE.h : include
:ALL:
abc :: a.c b.c c.c
xyz :: x.c y.c z.c

$ touch include/b.h

$ touch x.c

$ rm z.o

$ nmake
reason: b.o - include/b.h [Aug 18 15:51:37 2010] has changed [Aug 18 14:40:17 2010]
+ gcc -O -Iinclude -I- -c b.c
+ gcc -O -o abc a.o b.o c.o
reason: x.o - x.c [Aug 18 15:51:41 2010] has changed [Aug 18 14:39:33 2010]
+ gcc -O -Iinclude -I- -c x.c
reason: z.o - z.o [not found] has changed [Aug 18 15:51:08 2010]
+ gcc -O -Iinclude -I- -c z.c
+ gcc -O -o xyz x.o y.o z.o

The next example changes the makefile slightly to capture the unformatted explain data with the :T=QEU edit operator. The unformatted data is in a fielded format that can be easily parsed and used with local scripts and tools.

$ cat Makefile
%.o : %.c (CC) (CCFLAGS)
        silent echo reason: $(<:Q) - $(<:T=QEU:Q)
        $(CC) $(CCFLAGS) -c $(>)

CC = gcc
.SOURCE.h : include
:ALL:
abc :: a.c b.c c.c
xyz :: x.c y.c z.c

$ touch a.c       

$ nmake
reason: a.o - "6 a.c 1282161524 1282161287"
+ gcc -O -Iinclude -I- -c a.c
+ gcc -O -o abc a.o b.o c.o

The first field is an integer reason code, in this case code 6. The remaining fields are parameters for this specific explain message. The code numbers and corresponding messages can be looked up in the file nmake_install_root/lib/make/explain.map. The message parameters are shown as %s for a string and %t for a time stamp.

$ grep ^6 nmake_install_root/lib/make/explain.map
6       %s [%t] has changed [%t]

Here we see the first parameter for reason 6 is a string, in our case "a.c". And the remaining two parameters are time stamps recorded in seconds from epoch. Local tools can parse the data and use explain.map to format the messages. The new :F=%(explain)S edit operator can also be used to format the unformatted data. Here is a one-liner:

$ nmake -n -f - . 'print $("6 a.c 1282161524 1282161287":@F=%(explain)S)'
a.c [Aug 18 15:58:44 2010] has changed [Aug 18 15:54:47 2010]

More Information

For more examples and information see the nmake 12 release notes. The explain data is also captured by default in the structured build logs created with the xmakelog command and included in the web build logs generated with the buildlog2html command. See the Build Log documentation for details.

index

warning: ... replaced by and older version

If you are new to nmake but have used other build tools you might be surprised to see a warning that a file has gotten older. For example:

$ nmake
make: warning: hello.c has been replaced by an older version
+ gcc -O -I- -c /home/richb/newsletter/n35/v3/hello.c
+ gcc -O -o hello hello.o

What does this mean? Unlike other build tools nmake does not simply compare time stamps and check if the prerequisite is newer than the target to trigger an update. The time stamps of the files are stored in the nmake statefile (eg. Makefile.ms). The current time stamps are compared with the time stamps from the statefile so nmake can tell if any of the files have changed since the previous build. If a file's current time stamp is older than the time stamp in the statefile nmake issues the warning and updates the affected targets.

The warning message is issued because it is fairly unusual for the time stamp to go backwards and may indicate a configuration error or another problem in the environment. One possible cause could be a change to the viewpath, such as removing a node from the viewpath so older files are seen or adding a node with older files in front of other nodes. If the warning is for system headers or libraries then perhaps the previous build was on a different machine running a different version of the OS.

There is also a known issue that may cause this warning when the first prerequisite file of a :: assertion is also the prerequisite of a :cc: assertion that comes before the :: in the makefile. To work around this issue move the :cc: assertion to come after :: in the makefile.

index

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!

index

<<home / newsletters