Question

My question concerns GNU's make.

If you have a sequence of commands that are useful as a recipe for several targets, a canned recipe comes in handy. I might look like this:

define run-foo
# Here comes a
# sequence of commands that are
# executed line by line
endef

Now you can use the canned recipe like this:

file1: input1:
    $(run-foo)

$(pattern) : sub/% : %.inp
    $(run-foo)

and so on. I wonder if it is possible to define canned recipes (or something similar) that take parameters, so that I could execute them like this:

file2: input2
    $(run-foo) specific-parameter2 "additional"

file3: input3
    $(run-foo) another-parameter3 "text"

Is this possible? Any hints welcome :)

Was it helpful?

Solution

You do this by:

  • Using parameters $1,$2... etc in your define-ed macro
  • Invoking the macro via $(call ...)

e.g:

define recipe
echo $1
endef

all: t1 t2

t1:
    $(call recipe,"One")

t2:
    $(call recipe,"Two")

OTHER TIPS

Nearly 8 years. Okay, Necromancer mode on.
Despite answer by Mike Kinghan mitigates an issue, there's a solution for exact thing being asked.

Almost no black magic takes precedence here.

Simple example for an idea to be clear; just prints out all args:

define myrecipe-args
dummy() { printf 'arg: %s\n' "$$@"; }; dummy
endef

mytarget:
    $(myrecipe-args) foo bar baz

Complex example, prints out automatic variables as well as args:

define myrecipe-full
_() { \
printf '$$@ (target): %s\n' $@; \
printf '$$< (first prereq): %s\n' $<; \
printf '$$^ (all prereqs):'; printf ' %s' $^; echo; \
printf '$$| (order-only prereqs):'; printf ' %s' $|; echo; \
printf 'argv[]: %s\n' "$$@"; \
}; _
endef

mytarget : pa pb | oa ob
        $(myrecipe-full) groovy defaulty targetty
        @echo finally made $@!

pa pb oa ob:
        @echo dummy: $@

As you can see it's just cheating on shell functions. The downside, however, is a requirement for recipe to be one-liner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top