help-make
[Top][All Lists]
Advanced

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

A question about order-only dependencies.


From: Evan Bigall
Subject: A question about order-only dependencies.
Date: Sun, 7 Sep 2008 15:03:13 -0700 (PDT)

Consider the following rule:

.phony : objs_built

objs_built : | $(objs)
        @echo objs built

The idea is to be able to have a phony target "objs_built", that when included 
in a list of other targets could tell you when all of the objects that were 
going to be built had been built.

The problem is, that when make is invoked with objs_built as a target it puts 
all of the $(objs) on the list of things to built.  I was expecting that 
because $(objs) is an order-only dependency, of objs_built building objs_built 
would not imply building objs.  I know that's a little bit backwards, but it's 
what I at least was expecting. 

Does my expectation make sense?  Was I incorrect?

Here is a complete example makefile, (also attached to avoid problems with 
white space).  Just download this makefile to an empty directory to try these 
examples:

-----------------

ALL = a b c d

define template

.phony : run_$(1)

run_$(1) : $(1)
        ./$(1)

$(1) : $(1).o
        gcc -o $(1) $(1).o

$(1).o : $(1).c
        gcc -c $(1).c

$(1).c :
        echo 'main() { printf("$(1)\n"); exit(0); }' > $(1).c

endef

$(foreach EXE, $(ALL), $(eval $(call template,$(EXE))))

.phony : all run_all objs_built built

all : $(foreach EXE, $(ALL), $(EXE))

run_all : $(foreach EXE, $(ALL), run_$(EXE))

objs=$(foreach EXE, $(ALL), $(EXE).o)

objs_built : | $(objs)
        @echo objs built

objs_built_file : | $(objs)
        @echo objs built file
        touch $@

clean :
        -rm list objs_built_file $(foreach EXE, $(ALL), $(EXE) $(EXE).o $(EXE).\
c)

define lister
        echo $(1) >> $(2)

endef

list : $(objs)
        -rm  $@
        $(foreach L, $?, $(call lister, $(L), $(@)))

-----------------

# get started:

> make -r -R run_all
echo 'main() { printf("a\n"); exit(0); }' > a.c
gcc -c a.c
gcc -o a a.o
./a
a
echo 'main() { printf("b\n"); exit(0); }' > b.c
gcc -c b.c
gcc -o b b.o
./b
b
echo 'main() { printf("c\n"); exit(0); }' > c.c
gcc -c c.c
gcc -o c c.o
./c
c
echo 'main() { printf("d\n"); exit(0); }' > d.c
gcc -c d.c
gcc -o d d.o
./d
d

# Make sure 'b' is up to date:

> make -r -R objs_built b
objs built
make: `b' is up to date.

#
# touch a.c, and then rebuild 'b' also including the objs_built target
#

> touch a.c
> make -r -R objs_built b
gcc -c a.c
objs built
make: `b' is up to date.

#
# I would not have expected building the objs_built target to imply 
# that all of the objs needed building as well.
#

> make -r -R -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i686-pc-linux-gnu

Thanks,
Evan

Attachment: Makefile
Description: Binary data


reply via email to

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