GNU Makefile将每个配方行视为没有连续符的子shell命令

时间:2018-04-02 14:31:08

标签: makefile gnu-make

我想让target_compile工作。

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:
.
.
.

我收到错误,尽管我没有在;\开头的第一行添加cp

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

1 个答案:

答案 0 :(得分:0)

您可能想要的是:

${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} ...

解释一些事情(并重申@ Beta的评论):变量${CURRENT_DIR} makefile 变量。它可以来自环境或makefile。 make将替换变量名称的值first phase(在运行任何规则之前)。因此,运行规则时无法更改其值。 Makefile变量只有一个$,如果它们是多字符标记,则需要围绕它们。

${PROJECT_SIM_OPTS}是一个target-specific makefile变量。它仍然是一个makefile变量,因此当make执行规则时它不能改变它的值。话虽这么说,它的值特定于target_compile规则,以及由于该规则而运行的任何规则。

对于 shell 变量,可以在配方中设置值,但是,该值的范围是配方行本身。为了使用shell变量,您需要执行$$shellvarname(使用两个$,因为make会在调用shell之前将$$扩展为$。说,配方的每一行都在子shell中运行,任何变量值都不会在其他子shell中可见。所以,例如,如果你有:

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

它会输出:

recipe1: shellVar is value
recipe2: shellVar is

由于recipe1的子shell不与recipe2的子shell通信,因此recipe2不知道recipe1的变量值。