Set newly created file as variable in makefile

淺唱寂寞╮ 提交于 2019-12-20 07:47:14

问题


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 /output/1.txt >> /output/2.txt
    $(eval s := $(shell cat /output/2.txt)) 
    $(eval FILENAME_BIN=$(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).bin) 
    $(eval FILENAME_JFFS2=$(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).jffs2)        
endef

If 2.txt exists before running this the variables will be set to the data prior to running make (not the new redirected data), if 2.txt doesn't exist then the variables are not set. It looks like it is evaluating what the file is like when make is first run, which is not what I want...


回答1:


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.



来源:https://stackoverflow.com/questions/41609184/set-newly-created-file-as-variable-in-makefile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!