help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Target dependent on input maybe rebuilt by recursive make


From: Jonathan Lennox
Subject: Target dependent on input maybe rebuilt by recursive make
Date: Tue, 27 Jan 2015 21:35:14 +0000

Hi —

I’m trying to structure a Makefile for a situation where a target depends on 
inputs that are in a subdirectory, which can be rebuilt by recursive make.

The specific case is a top-level Makefile which builds a binary, which links 
with static libraries built in a subdirectory.  The top-level Makefile doesn’t 
have visibility into the inputs to the libraries, so it needs to invoke the 
recursive make always.

The problem I’m having is that Make’s decision as to whether or not to rebuild 
the binary seems to depend on whether the files are old *before* the 
subdirectory make is invoked, not afterwards.  Thus, if an input to a library 
changes, I have to invoke make twice in order to get my binary rebuilt.

Here is my top-level Makefile:

all: bin

bin_libs = lib/libfoo.a lib/libbar.a lib/libbaz.a

bin: bin.o $(bin_libs)
$(CC) -o $@ $^

$(bin_libs) : | build-bin-libs

.PHONY: build-bin-libs

build-bin-libs:
$(MAKE) -C lib $(notdir $(bin_libs))

clean:
rm -f bin *.o
$(MAKE) -C lib clean

And here is lib/Makefile:

all: libfoo.a libbar.a libbaz.a libquux.a

ARFLAGS = cru

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@

lib%.a: %.o
rm -f $@
$(AR) $(ARFLAGS) $@ $^

clean:
rm -f *.o *.a

(Obviously this is a simplification of my real build environment.)

When I do an initial build, everything’s fine:

$ make
cc    -c -o bin.o bin.c
make -C lib libfoo.a libbar.a libbaz.a
make[1]: Entering directory `/home/jonathan/Cvs/scratch/Make-Recursive-Test/lib'
cc  -c foo.c -o foo.o
rm -f libfoo.a
ar cru libfoo.a foo.o
cc  -c bar.c -o bar.o
rm -f libbar.a
ar cru libbar.a bar.o
cc  -c baz.c -o baz.o
rm -f libbaz.a
ar cru libbaz.a baz.o
rm baz.o foo.o bar.o
make[1]: Leaving directory `/home/jonathan/Cvs/scratch/Make-Recursive-Test/lib'
cc -o bin bin.o lib/libfoo.a lib/libbar.a lib/libbaz.a

However, a change that causes one of the libraries to be rebuilt doesn’t cause 
bin to be rebuilt, so I have to invoke make twice.

$ touch lib/foo.c
$ make
make -C lib libfoo.a libbar.a libbaz.a
make[1]: Entering directory `/home/jonathan/Cvs/scratch/Make-Recursive-Test/lib'
cc  -c foo.c -o foo.o
rm -f libfoo.a
ar cru libfoo.a foo.o
make[1]: `libbar.a' is up to date.
make[1]: `libbaz.a' is up to date.
rm foo.o
make[1]: Leaving directory `/home/jonathan/Cvs/scratch/Make-Recursive-Test/lib'
$ make
make -C lib libfoo.a libbar.a libbaz.a
make[1]: Entering directory `/home/jonathan/Cvs/scratch/Make-Recursive-Test/lib'
make[1]: `libfoo.a' is up to date.
make[1]: `libbar.a' is up to date.
make[1]: `libbaz.a' is up to date.
make[1]: Leaving directory `/home/jonathan/Cvs/scratch/Make-Recursive-Test/lib'
cc -o bin bin.o lib/libfoo.a lib/libbar.a lib/libbaz.a

What can I do about this?  What’s the best (most idiomatic) way to structure my 
makefile such that it does what I want — always rebuild both the relevant 
library and the binary whenever one of the inputs to a library changes?

Note that I don’t just want to do a ‘make all’ in lib — I want it to only build 
the libraries needed by bin, not (in the example) lib/libquux.a.  (In our 
actual development environment, some irrelevant libraries may be temporarily 
broken by other developers, or just take a long time to build.)

I’m using GNU Make 3.81, on Ubuntu 14.04, if that’s relevant.

Thank you for any help!

—
Jonathan Lennox




reply via email to

[Prev in Thread] Current Thread [Next in Thread]