Because of bash's export -f function-name feature to export a bash function definition into the environment where it will be picked up by sub-child invocations of bash, we can define a bash variable in the environment in the same form in the Makefile.
If we define bash functions in the Makefile using the same format bash does, and export them into the environment, and set SHELL=bash then we can use these bash functions in the make recipe.
Let's see how bash formats functions exported in the environment:
$ # define the function
$ something() { echo do something here ; }
$ export -f something
$ # the Makefile
$ cat > Makefile <<END
SHELL=bash
all: ; something
END
$
Try it out
$ make
something
do something here
$
How does this look in the environment?
$ env | grep something
BASH_FUNC_something%%=() { echo do something here
The pattern is (currently):
BASH_FUNC_function-name%%=() { function-body }
So we do this in the Makefile:
SHELL=bash
define BASH_FUNC_something-else%%
() {
echo something else
}
endef
export BASH_FUNC_something-else%%
all: ; something-else
and try it:
$ make
something-else
something else
It's a bit ugly in the Makefile but presents no ugliness for make -n