Use make variable in builtin shell function in a M

2019-07-24 23:49发布

问题:

I have this make file

all : CONFIG=config.ini
debug : CONFIG=config-debug.ini

CONFIG_FILES := $(shell python parse_config.py -i $(CONFIG))

all: $(CONFIG) $(CONFIG_FILES)
    echo $(CONFIG) $(CONFIG_FILES)

When I run make all it shows some python error saying -i option param is missing. So it seems $(CONFIG) is not going through shell function.

How can make all invoke python parse_config.py -i 'config.ini'?

same way make debug invoke python parse_config.py -i 'config-debug.ini'?

Update:

After running make all SHELL+=-x I get following output.

+ python parse_config.py -p static -i
usage: parse_config.py [-h] -i INPUT_JSB3 [-p PREFIX]
parse_config.py: error: argument -i: expected one argument

But after that I get

+ python parse_config.py -p static -i static/config.ini

And make seems to continue to work.

回答1:

The problem is that this:

all : CONFIG=config.ini

all: $(CONFIG) $(CONFIG_FILES)
        ...

will not work. The value of target-specific variables are only available inside the recipe. You cannot use target-specific variables as prerequisites. That's also why it's not set within the $(CONFIG_FILES) variable when you use it in the prerequisites list.

ETA:

You can do something like this:

CONFIG_FILES = $1 $(shell python parse_config.py -i $1)

all: $(call CONFIG_FILES,config.ini)
debug: $(call CONFIG_FILES,config-debug.ini)

perhaps. You could write it out explicitly. You could run a recursive make invocation overriding CONFIG_FILES. You could auto-generate included files. You could define some variables then use secondary expansion. There are a lot of ways to do this.

You just can't do it with target-specific variables in the prerequisites list.



回答2:

You can't use target-specific variables and simple assignment together like that. You are telling make to run the shell command at make parse time but also telling it to only set the contents of the $(CONFIG) variable during specific target contexts.

You can either use a recursive variable (and run the shell command once for each time you use the variable) or stick CONFIG_FILES assignments into each target-specific context along with CONFIG.



回答3:

Drop the : from the CONFIG_FILES := … line. That forces make to evaluate the CONFIG_FILES at that point in the makefile, and it doesn't have the context of a target (all or debug) to allow it to provide a value for $(CONFIG) so it doesn't provide one, which leads to the error you see.

Use:

CONFIG_FILES = $(shell python parse_config.py -i $(CONFIG))


回答4:

This can be done using MAKECMDGOALS variable.

ifeq ($(findstring debug,$(MAKECMDGOALS)),debug)
CONFIG=config-debug.ini
else
CONFIG=config.ini
endif

CONFIG_FILES := $(shell python parse_config.py -i $(CONFIG))

all: $(CONFIG) $(CONFIG_FILES)
    echo $(CONFIG) $(CONFIG_FILES)