I need to get some external data to form an output file name in a Makefile.
In GNU Make I can do something like this :
NAME=$(shell some_commands)
$(NAME).out: file.in
compile "$<" -o "$@"
Some other rules have $(NAME).out
as a prerequisite so I need $(NAME).out
as a target. I can't use substitution+quotes here as this is not interpreted by a shell.
I see from the BSD Make man page that on Mac OS X I should be able to do something like this (I could not test it yet, though) :
NAME!=some_commands
$(NAME).out: file.in
compile "$<" -o "$@"
Is there a hack to do this kind of things in a portable way?
I do not want to generate the Makefile and clutter the build process. I though of includes, but they also have a different syntax across Make versions.
I can propose several tricks. All them are based on the outsourcing the execution of some_commands
to a rule body, and ensuring that their result will be utilized properly.
That's my favourite. Include a makefile, which you create on your own, that contains the rule for $(NAME)
. At the beginning of processing it will be re-created and the proper target will appear. The thing is that the process of creation of this makefile is done within shell commands:
include aux_makefile
.PHONY aux_makefile
aux_makefile:
NAME=`some_commands` ; ( \
echo $$NAME.out: file.in ; \
echo "\t rm aux_makefile" ; \
echo "\t compile ..." ) >$@
A variation of first one: make a wrapper makefile that first writes the auxilliary makefile and then recursively calls the original makefile, the auxilliary makefile being included into it. No special build target needed.
Make a dummy target with a static name; it will represent $(NAME).out
. I.e.:
all: dummy # Instead of all: $(NAME).out
dummy: file.in
NAME=`some_commands`; compile "$<" -o "$$NAME"
touch $@