user578895
user578895

Reputation:

functions in makefiles?

I have a slew of makefile targets that do the same thing:

${SOME_FILE}:
    ${FILES} | ${DIST_DIR}

    @@cat ${FILES} |                     \
        sed 's/@DATE/'"${DATE}"'/' |     \
        sed 's/@VERSION/'"${CR_VER}"'/'  \
        > ${OUT_FILE};

where ${FILES} and ${OUT_FILE} are the only things changing. I'm trying to figure out if it's possible to simplify these targets to something like:

${SOME_FILE}:
    compile(${FILES},${OUT_FILE})

Thanks for any insight.

Upvotes: 34

Views: 55933

Answers (3)

Konstantin Smolyanin
Konstantin Smolyanin

Reputation: 19073

Links to docs (like in the accepted answer) are good but good example is better :)

define my_func
    $(eval $@_PROTOCOL = "https:")
    $(eval $@_HOSTNAME = $(1))
    $(eval $@_PORT = $(2))
    echo "${$@_PROTOCOL}//${$@_HOSTNAME}:${$@_PORT}/"
endef

my-target:
    @$(call my_func,"example.com",8000)

Take into consideration the following:

  • There are no custom "functions" in Makefile language. So "my_func" is actually a variable that simply contains a text.
  • That "function" doesn't have its own scope. All the content of that "function" is copied into the recipe as is. All variables in the body will be used after that as a part of the recipe.
  • Don't use spaces near the commas to prettify param list of "call" function.
  • Args are passed like $(1), $(2), ... that is not very handy, so re-declare them with meaningful names. This is optional but recommended for bigger "function" bodies.
  • Variables are declared with $@_ prefix that makes them "local" to the rule (actually not local but prefixed by the target name).

So we have imitation of functions with imitation of local variables but generally this works good.

Upvotes: 43

Jack Kelly
Jack Kelly

Reputation: 18667

If you don't want to restrict yourself to GNUmake, your best bet is probably to generate makefile fragments yourself and then include them.

Upvotes: 6

asdf
asdf

Reputation: 256

GNU make has this:

To define a multi-line function, you would use this syntax:

Upvotes: 20

Related Questions