[Top][All Lists]

[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)

%.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)

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

$(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.


reply via email to

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