help-make
[Top][All Lists]
Advanced

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

Re: expanding $(%) in prerequisites


From: Paul D. Smith
Subject: Re: expanding $(%) in prerequisites
Date: Thu, 14 Dec 2000 14:55:02 -0500

%% "William F. Dowling" <address@hidden> writes:

  wfd> I have definitions and rules like this:

  wfd> foo_EXTRAOBJS = $(BIN)/bar.o
  wfd> goo_EXTRAOBJS = $(BIN)/baz.o

  wfd> $(BIN)/foo : foo.c $(foo_EXTRAOBJS)
  wfd>     $(CC) $(CFLAGS) -o $@ foo.c $(foo_EXTRAOBJS)
  wfd> $(BIN)/goo : goo.c $(goo_EXTRAOBJS)
  wfd>     $(CC) $(CFLAGS) -o $@ goo.c $(goo_EXTRAOBJS)

  wfd> Naturally, I'd like to keep my nice declarative style for specifying
  wfd> extra objects that need to be linked, while using a pattern rule for
  wfd> the build.  I've tried this:

  wfd> $(BIN)/% : %.c $(%_EXTRAOBJS)
  wfd>   $(CC) $(CFLAGS) -o $@ $< $(*_EXTRAOBJS)

  wfd> Although the command seems ok,

No.  It's not legal.  Variables in target and prerequisite lists are
expanded immediately as the makefile is read in, but obviously the value
of "%" in an implicit rule cannot be known until during the build, when
make tries to create a target and picks that implicit rule.

This expands the variable with the static name "%_EXTRAOBJS", which is a
perfectly legal make variable name, but is empty in this case.

In the newest versions of the GNU make manual is a section "How 'make'
Reads a Makefile" which explains all this.

  wfd> $(foo_EXTRAOBJS) is not being picked up as a prerequisite.  I've
  wfd> tried quite a few other strategems too, but I never seem to be
  wfd> able to get the prerequisite to work.

  wfd> Can someone suggest a way to make something like this work?

There is no way to do this in one make invocation without having to
write a line per target.  You can do a lot better than your initial
code, like this:

  foo_EXTRAOBJS = $(BIN)/bar.o
  goo_EXTRAOBJS = $(BIN)/baz.o

  $(BIN)/% : %.c
             $(CC) $(CFLAGS) -o $@ $^

  $(BIN)/foo : $(foo_EXTRAOBJS)
  $(BIN)/goo : $(goo_EXTRAOBJS)

This way you only have one rule, which is a lot better than what you had
before, but you still have to declare each prerequisite list explicitly.

The only way (currently) to avoid the line-per-target is to use the
auto-re-exec feature of GNU make.  You can do this:


  foo_EXTRAOBJS = $(BIN)/bar.o
  goo_EXTRAOBJS = $(BIN)/baz.o

  BINS = foo goo

  $(BIN)/% : %.c
             $(CC) $(CFLAGS) -o $@ $^

  include extra_objs.mk

  extra_objs.mk: Makefile
          rm -f $@
          for bin in $(BINS); do \
            echo "\$$(BIN)/$$bin : \$$($${bin}_EXTRAOBJS)" >> $@; \
          done

I think the quoting is right.  If you don't grok that, check the manual
for how make remakes makefiles, and if you still don't get it, let me
know and I'll elucidate :).

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://www.paulandlesley.org/gmake/
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist



reply via email to

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