Programming Utilities Guide

Forcing a Nested make Command to Run

Because it has no dependencies, this target runs only when the file named ../lib/libpkg.a is missing. If the file is a library archive protected by .PRECIOUS, this could be a rare occurrence. The current make invocation neither knows nor cares about what that file depends on, nor should it. It is the nested invocation that decides whether and how to rebuild that file.

After all, just because a file is present in the file system does not mean it is up-to-date. This means that you have to force the nested make to run, regardless of the presence of the file, by making it depend on another target with a null rule (and no extant file):

Table 4-14 Target Entry for a Nested make Command
# Reliable target entry for a 
# nested make command.

../lib/libpkg.a:  FORCE
        	cd $(@D); $(MAKE) $(@F) 
FORCE:

In this way, make reliably changes to the correct directory ../lib and builds libpkg.a if necessary, using instructions from the makefile found in that directory. These lines are produced by the nested make run:

$ make ../lib/libpkg.a 
cd ../lib; make libpkg.a 
make libpkg.a 
`libpkg.a' is up to date.

The following makefile uses a nested make command to process local libraries that a program depends on.

Table 4-15 Makefile for C Program with User-Supplied Libraries
# Makefile for a C program with user-supplied 
# libraries and nested make commands. 

CFLAGS= -O 

.KEEP_STATE:

functions: main.o data.o ../lib/libpkg.a 
        	$(LINK.c) -o $@ main.o data.o
         ../lib/libpkg.a -lcurses -ltermlib 
         ../lib/libpkg.a:  FORCE
        	cd $(@D); $(MAKE) $(@F) 
FORCE: 

lint: main.ln data.ln 
        	$(LINT.c) main.ln data.ln 
clean: 
        	rm -f functions main.o data.o main.ln data.ln

When ../lib/libpkg.a is up to date, this makefile produces:

$ make 
cc -O -c main.c 
cc -O -c data.c 
cd ../lib; make libpkg.a 
`libpkg.a' is up to date.  
cc -O -o functions main.o data.o ../lib/libpkg.a -lcurses -l   termlib