help-gnu-utils
[Top][All Lists]
Advanced

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

Re: Multiple targets of pattern rules with GNU Make


From: Paul D. Smith
Subject: Re: Multiple targets of pattern rules with GNU Make
Date: 24 May 2004 15:40:54 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3

%% "Kevin B. McCarty" <kmccarty@NOSPAM.princeton.PLEASE.edu> writes:

  kbm> %.3.o: %.cc $(HEADERS)
  kbm>         $(CXX) -c $(CXXFLAGS) $< -DDEBUG3 -o ../build/$@

  kbm> %.2.o: %.cc $(HEADERS)
  kbm>  $(CXX) -c $(CXXFLAGS) $< -DDEBUG2 -o ../build/$@

  kbm> [likewise for %.1.o and %.0.o]

These rules are incorrectly formed.  You cannot say you're going to
build one thing ($@), but then really build ../build/$@.  That violates
the Second Rule of Makefiles.

  kbm> $(foreach num,0 1 2 3,%.$(num).o): %.cc $(HEADERS)
  kbm>  $(CXX) -c $(CXXFLAGS) $< -DDEBUG$(subst .,,$(suffix $(basename $@))) \
  kbm>          -o ../build/$@

  kbm> This of course does not work, since GNU Make assumes that the
  kbm> command will generate _all_ of the targets when multiple targets
  kbm> are present in a pattern rule.

  kbm> Is there any way to force Make to behave as if the above rule
  kbm> contained statically defined targets, so it would be equivalent
  kbm> to the set of rules listed at top?

No.

  kbm> Or some other reasonably non-obfuscated way to do what I want
  kbm> without so much redundancy, but compatible with Make 3.79.1?

I don't know about non-obfuscated, but the only way to do what you want
without writing it all out by hand, without using eval, is to use the
make "re-exec" feature (before eval, this is how everyone did any kind
of dynamic rule generation like that).

Have a rule that generates a makefile fragment containing the right
rules, then include it, something like this (note, completely untested):

    targets.mk: Makefile
            for i in 0 1 2 3; do \
              echo "../build/%.$$i.o: %.cc \$$(HEADERS)"; \
              echo "    \$$(CXX) -c \$$(CXXFLAGS) \$$< -DDEBUG$$i -o \$$@"; \
            done > $@

    include targets.mk


Now whenever targets.mk is out of date, it will get built then make will
automatically re-exec itself to read in the new contents.

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <psmith@gnu.org>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.paulandlesley.org
 "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]