Nokia Networks Home

Nokia nmake Product Builder

Quick Links

Related Products

Tutorial: A Little Help With Nokia nmake

[Table of Contents] [Previous Section] [Next Section]

8. Promises

We made some promises early in the paper that we haven't kept yet and now is a good time to deliver. The explanations depend on the .INIT, .ARGS, and .MAIN special atoms that we'll introduce in this section.

8.1 .INIT

There's a target named .INIT that's automatically built right before anything else in your makefile. It can be convenient when you're debugging and is important if you want to do something, like execute a shell script, every time nmake process runs.

We've already seen an example where .INIT would help. Remember the disappearing print message that we blamed on the objectfile? If we go back to print.mk, make a target named .INIT, mark it with the .MAKE special atom, and move the print command into .INIT's action block

     .INIT : .MAKE
        print this message comes from print

     hello :
        silent echo "hello, world"

then we get the message from print whenever we run nmake. The explanation is easy: the symbol tables written to the objectfile include our definition of .INIT, so the print command isn't lost because this time it's part of .INIT's action block.

8.2 .ARGS

nmake collects the targets from your command line, adds them to the prerequisite list of a special atom named .ARGS, and eventually goes back and builds everything it finds in .ARGS's prerequisite list. We'll need .ARGS to explain why we only get one message from,

     nmake -f message.mk hello hello

but first we have to show you how to look at a prerequisite list.

8.2.1 Another Automatic Variable

There's an automatic variable named $(~) that stands for all the explicit prerequisites [17] of the current target. We happen to be interested in the prerequisites of .ARGS, so $(~) isn't quite what we want, but there's an easy way to use automatic variables to look at any target. Follow the character that identifies the automatic variable by the name of a target, and nmake gives you information about that target. For example, $(~.ARGS) is how we ask for the explicit prerequisites of .ARGS, so if we put

     .INIT : .MAKE
        print .ARGS : $(~.ARGS)
                              
     goodbye hello :
      silent echo "$(<), world"

in args.mk and type

     nmake -f args.mk hello goodbye

we get:

     .ARGS : hello goodbye
     hello, world
     goodbye, world

The first line is from the print statement that we put in .INIT's action block, and the two prerequisites are the targets we named on the command line.

8.2.2 Disappearing Prerequisites

Mention the same target twice on the command line and we know something unexpected happens when we use message.mk. Try it with args.mk

     nmake -f args.mk hello hello

and the same thing happens,

     .ARGS : hello
     hello, world

but now we can understand why. There's only one hello in .ARGS's prerequisite list and that's why we only get one message. But that's usually how prerequisite lists work: no matter how many times we say a target depends on a prerequisite, we'll only see it once when we look through the list.

8.3 .MAIN

nmake usually builds the first target in your makefile that doesn't look like a special atom [18] when there aren't any command line arguments, but there's a target named .MAIN that lets you pick your own defaults. For example, if we put

     AUDIENCE = world

     .MAIN : hello

     goodbye hello :
        silent echo "$(<), $(AUDIENCE)"

in main.mk then all we have to do is type

     nmake -f main.mk

when we want to say hello, because the prerequisites of .MAIN end up as the default targets.

You have to be careful where you put .MAIN. Move it to the end of main.mk and see what nmake builds when you don't tell it what to do. The explanation is easy, so we'll leave it to you. Hint: $(~.MAIN) and the technique we just used in args.mk will show you the prerequisites.

FOOTNOTES:

[17]
Explicit prerequisites are the ones you see in assertions. They don't include the implicit prerequisites nmake finds by scanning source files.
[18]
Actually, nmake picks the first target that it finds while reading your makefile that begins with a letter, digit, or underscore, or includes a / or $ in the name, that's not also marked by the .SPECIAL or .OPERATOR special atoms.

[Table of Contents] [Previous Section] [Next Section]

Last Update: Friday,12-Aug-2016 12:19:31 EDT