j3d
j3d

Reputation: 9724

How to invoke a function in a shell script from a Makefile

I've a Makefile that contains a target to print a given variable:

print-%:
    @echo $*=$($*)

For example to print the value of variable CURDIR I just issue the following command:

make print-CURDIR

And here's the result:

CURDIR=/Users/j3d/Projects/myproject

Now I'd like to create a shell script that contains a set of common functions to be invoked from any Makefile... and here's the modified version of the target above:

print-%:
    . ./make-util printvar $@

And here's make-util:

#!/bin/sh

printvar()
{
    @echo $*=$(*)
}

Finally, running the script above...

j3d@j3ds-macbook-pro myproject % make print-CURDIR

... doesn't produce the expected result:

. ./make-utils CURDIR

How should I invoke the script function so that the given variable gets printed correctly?

Upvotes: 0

Views: 852

Answers (2)

MadScientist
MadScientist

Reputation: 100816

You can create a suite of make recipes (if you're using GNU make) that you can include and use in multiple makefiles, but you have to do it with make syntax, not shell syntax, because they are make recipes even if the recipe becomes a shell script after expansion.

You can investigate the GNU make define statement and eval and call functions for ways to create user-defined functions in GNU make. For example you could write a makefile like this:

$ cat macros.mk
print-%:
        @echo $*=$($*)

then in your other makefiles you could use:

include macros.mk

and you'd automatically get that rule available.

There are lots and lots of possibilities here but the details depend on what you want to do.

Upvotes: 2

user1934428
user1934428

Reputation: 22225

You are nearly there:

Since you are passing the name of the function as first parameter, you could do a

#!/bin/sh
printvar()
{
  @echo $*=$(*)
}
"$1"

to execute the function. If you want more safety (to catch cases where you pass by mistake some dangerous command instead of a function name), you could do a

[ "$1" = printvar ] && printvar
[ "$1" = other_function ] && other_function

instead.

If you want to process your script Make-variables, you can pass them as additional parameters:

func=$1
shift
[ "$func" = printvar ] && printvar "$@"
[ "$func" = other_function ] && other_function "$@"

Upvotes: 1

Related Questions