svv
svv

Reputation: 446

Makefile: Executing builtin function passed as a parameter to call

I'm writing the following Makefile:

CHECK = $($1 $2)
$(info $(call CHECK,dir,a/b/c))

stop:

and executing it in GNU Make 4.3 as make without args. What I expect in output is a/b/ but I get empty line instead.

My actual question is how may I pass/get/use builtin functions in other macros to make those passed functions work? Is this possible?

Note: Actual Makefile is slightly more complex, but this short example demonstrates the idea. I know I may just write $(dir a/b/c) but this is not what I want.

UPD: My actual use case is the following. I have a list of files processed in pipeline of template (having %) rules. Some of those files have spaces in their names and in order to get their names interpreted correctly I use the following trick:

ESCAPE_IN_SHELL = sed -E 's,_,_1,g;s, ,_2,g'
ESCAPE = $(subst $() ,_2,$(subst _,_1,$1))
UNESCAPE = $(subst _1,_,$(subst _2, ,$1))
MAP = $(foreach A,$2,$(call $1,$A))

# Names acquisition
NAMES != ls in_dir | ${ESCAPE_IN_SHELL}

trans_dir/% : in_dir/%
    mkdir -p $(dir $@)
    ...

out_dir/% : trans_dir/%
    ...

main_rule : $(call MAP,UNESCAPE,${NAMES})

The problem is in that mkdir -p $(dir $@) precisely in how $@ is interpreted by $(dir ...) when it contains spaces. What I do to fix this is replacing $(dir $@) with $(call UNESCAPE,$(dir $(call ESCAPE,$@)))

But I've found that it is possible to generalize and shorten solution by creating additional function like this:

SAFE = $(call UNESCAPE,$($1 $(call ESCAPE,$2)))

It should be used like $(call SAFE,dir,$@). And here I faced the problem that dir doesn't get expanded as expected.

Upvotes: 0

Views: 63

Answers (1)

MadScientist
MadScientist

Reputation: 100816

I didn't read all the details of the issue but if documentation for the call function is pretty clear about this:

If variable is the name of a built-in function, the built-in function is always invoked (even if a make variable by that name also exists).

So if you want to call a function, including a built-in function, you can't use:

CHECK = $($1 $2)

you have to use:

CHECK = $(call $1,$2)

Upvotes: 1

Related Questions