I am trying to create a file and set the contents of a file to a variable but the variable is always seen as empty.
An example:
define FILE_VAR
cat
You are unclear as to what is done by GNU make, and when, and what is done by the shell, and when, to execute a recipe.
Anything anywhere in a makefile of the form $(...)
is evaluated by make
unless it escaped as $$(...)
in a shell command.
A shell command, unless in the context of the make-function $(shell ...)
or
back-ticks can only be a command within a recipe:
target: [prerequisite...]
command
...
The commands composing a recipe are executed in sequence, each in a distinct shell, to execute the recipe.
Nothing of the unescaped form $(...)
is a command in the command-sequence
of a recipe unless it is the expansion of a variable or macro you have defined that expands to a command.
A line in the scope of a target need not be a command or expand to a command. It
may also consist of an $(...)
expression that expands to nothing,
and simply instructs make
to do something, e.g.
$(info ...)
expands to nothing and tells make
to print ...
on the standard output.
$(eval ...)
expands to nothing and tells make
to evaluate ...
This recipe has just two commands, not four:
target: prereq...
$(eval TARGET=$@)
command1
$(info $(TARGET))
command2
Any make-expressions, $(...)
in the scope of a recipe are evaluated in
sequence when make decides to run the recipe and the command-sequence is what
is left after they have all been evaluated. Then
the command-sequence is run. For example:
Makefile
target:
echo Hello > hello.txt
$(info Begin {)
$(eval s := $(shell cat hello.txt))
$(eval WORD=$(word 1, $(s)))
$(info [$(WORD)])
$(info } End)
Run that:
$ make
Begin {
cat: hello.txt: No such file or directory
[]
} End
echo Hello > hello.txt
Observe that all of the make-expressions are evaluated before the commands of the target are run.
Your FILE_VAR
macro is evidently intended to be expanded in recipe scope, since the first line is a shell command.
The remaining lines must therefore achieve their purposes by shell commands if they depend upon the
the effects of running the first line. None of them does so. The remaining 3 lines
are evaluated before 2.txt
exists, if it doesn't already exist at make-time.