GNU Makefile treating each recipe line as sub-shell command without continuation character

限于喜欢 提交于 2019-12-20 07:06:46

问题


I am trying to get the target_compile to work.

copy_shared_object:
    cp shared_object.so ${CURRENT_DIR}
    PROJECT_SIM_OPTS += -LDFLAGS -L${CURRENT_DIR},-lm -load

target_compile: copy_shared_object actual_compile_with_sim_opts

.
.
.
actual_compile_with_sim_opts:
.
.
.

I am getting the Error despite the fact that I have not added ;\ on the first line starting with cp

make: PROJECT_SIM_OPTS: Command not found
makefile:282: recipe for target 'copy_shared_object' failed
make: *** [copy_shared_object] Error 127

回答1:


What you likely want is something like:

${CURRENT_DIR}/shared_object.so: shared_object.so
    cp $^ $@

target_compile: PROJECT_SIM_OPTS += -LDFLAGS -L${CURRENT_DIR},-lm -load

target_compile: copy_shared_object actual_compile_with_sim_opts
    @echo PROJECT_SIM_OPTS=${PROJECT_SIM_OPTS} ...

To explain a few things (and to reiterate @Beta's remarks): The variable ${CURRENT_DIR} is a makefile variable. It can come from either the environment or makefile. make will substitute the value for the variable name at its first phase (before it runs any rules). Therefore its value cannot be changed when running a rule. Makefile variables have a single $, and require braces around them if they're multi-character tokens.

${PROJECT_SIM_OPTS} is a target-specific makefile variable. It's still a makefile variable, so it cannot change its value when the make is executing the rules. That being said, its value is specific to the target_compile rule, and any rule that is being run as a result of that rule.

For shell variables, it's possible to set a value within a recipe, however, the scope of that value is that recipe line itself. In order to use shell variables you need to do $$shellvarname (with two $'s, as make expands $$ to $ before invoking the shell) That being said, each line of a recipe is run in a subshell, and any variable values will not be visible in other subshells. So, for example, if you have:

target: prereq
     @shellVar="value"; echo "recipe1: shellVar is $$shellVar"
     @echo "recipe2: shellVar is $$shellVar"

it will output:

recipe1: shellVar is value
recipe2: shellVar is

as recipe1's subshell does not communicate with recipe2's subshell, and therefore recipe2 is not aware of recipe1's value for the variable.



来源:https://stackoverflow.com/questions/49613186/gnu-makefile-treating-each-recipe-line-as-sub-shell-command-without-continuation

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