help-make
[Top][All Lists]
Advanced

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

Re: Rule-specific variables


From: Brian Dessent
Subject: Re: Rule-specific variables
Date: Tue, 11 Mar 2008 01:43:09 -0700

Brendan Heading wrote:

> Are there any other ways to solve this ?

The simplest is probably what you're already doing, i.e. do it all in
one shell command.  But you can also do it using make's functions:

-----
define compile
        @echo rule to make $@ with $(if $(findstring c++,$(1)),\
                [c++ specific stuff],\
                [c specific stuff])\
                [common stuff] where foo=$(2) and bar=$(3)
endef

%.o: %.c
        $(call compile,c,foo_for_c,bar_for_c)

%.o: %.cxx
        $(call compile,c++,for_for_c++,bar_for_c++)

all: one.o two.o

one.o: one.c
two.o: two.cxx

one.c: ;
two.cxx: ;
-----

Results in:

$ make 
rule to make one.o with [c specific stuff] [common stuff] where
foo=foo_for_c and bar=bar_for_c
rule to make two.o with [c++ specific stuff] [common stuff] where
foo=for_for_c++ and bar=bar_for_c++

The problem with the above is your 'compile' rule has to do all its
logic in a functional manner, i.e. one long expression that uses $(if
..) style of logic.  Sometimes you want to be able to just declare the
different cases.  Here's another example, similar to one in the manual:

-----
CC := c-compiler
CXX := c++-compiler

tool_c := $(CC)
tool_cxx := $(CXX)
foo_c := [c specific value for foo]
bar_c := [c specific value for bar]
foo_cxx := [c++ specific value for foo]
bar_cxx := [c++ specific value for bar]

define commonparts
        @echo rule to make $@ from $< by invoking $(1) with foo=$(2)\
              and bar=$(3)
endef

define template
%.o: %.$(1)
        $$(call commonparts,$$(tool_$(1)),$$(foo_$(1)),$$(bar_$(1)))
endef

$(foreach lang,c cxx,$(eval $(call template,$(lang))))

all: one.o two.o

one.o: one.c
two.o: two.cxx

one.c: ;
two.cxx: ;
-----

Results in:

$ make
rule to make one.o from one.c by invoking c-compiler with foo=[c
specific value for foo] and bar=[c specific value for bar]
rule to make two.o from two.cxx by invoking c++-compiler with foo=[c++
specific value for foo] and bar=[c++ specific value for bar]

In this technique you can define the per-language variables normally
rather than having to use a functional style of "$(if x,then,else)"
code.  The 'template' in conjunction with the foreach instantiates the
actual pattern rules for each language, and the 'commonparts' contains
all the stuff that's common to all.

Brian




reply via email to

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