Makefile - 将值设置为来自另一个规则的变量
Makefile - set value to variable from another rule
在下面的 makefile 中,wat
规则用于从 .c
文件生成 .wat
文件。
CC=emcc
CFLAGS= -O2 -s WASM=1 -s SIDE_MODULE=1
# flags are for not generating any emscripten glue code
# makes a .wat version of a .c file of specified name
# TARGET must be specified from command line
wat: $(TARGET).c
$(CC) $(CFLAGS) -o $(TARGET).wasm $(TARGET).c && wasm2wat $(TARGET).wasm > $(TARGET).wat && rm $(TARGET).wasm
struct: TARGET = struct
struct: wat
clear:
rm -f *.wasm *.wat
这样调用,效果很好:
[user@pc]$ make wat TARGET=struct
emcc -O2 -s WASM=1 -s SIDE_MODULE=1 -o struct.wasm struct.c && wasm2wat struct.wasm >
struct.wat && rm struct.wasm
现在我想要一个更具体的规则,struct
,如您所见。本质上,我想重用 wat
规则,只需确保在 运行 之前将 TARGET
设置为 'struct'。但是,运行 make struct
给我一个来自 emcc 的 no input file
错误,好像 TARGET
的值不存在:
[user@pc]$ make struct
emcc -O2 -s WASM=1 -s SIDE_MODULE=1 -o .c
shared:ERROR: no input files
实现我的目标的正确方法是什么?
问题是,当 make 评估如何制定目标以及先决条件是什么时,您的 TARGET
是未定义的,因此规则说:wat
需要 .c
。你可以尝试递归并说这样的话:
struct:
$(MAKE) TARGET=struct wat
开始真的不是很好,因为实际上没有生成文件 wat
所以目标总是过时的 Makefile
确实只是有点美化 shell 脚本.
您可能应该考虑编写一个模式规则如何从 .c
构建 .wat
,类似于(基于您的示例):
%.wat: %.c
$(CC) $(CFLAGS) -o $(*F).wasm $< \
&& wasm2wat $(*F).wasm > $@.wat \
&& rm $(*F).wasm
然后您可以调用 make struct.wat
,如果您仍然希望(为了方便起见)只有 struct
目标,您可以添加:
.PHONY: struct
struct: struct.wat
您似乎在尝试使用特定于目标的变量,尤其是它们的继承功能来实现您的目标。
但是,由于 the documentation 中的语句,这无法工作:
As with automatic variables, these values are only available within the context of a target’s recipe (and in other target-specific assignments).
这意味着先决条件中的$(TARGET)
:
wat: $(TARGET).c
在解析 makefile 时计算,而不是在调用 struct
规则时计算,并扩展为:
wat: .c
我看到 Ondrej 提供了答案,所以我就到此为止了:)
在下面的 makefile 中,wat
规则用于从 .c
文件生成 .wat
文件。
CC=emcc
CFLAGS= -O2 -s WASM=1 -s SIDE_MODULE=1
# flags are for not generating any emscripten glue code
# makes a .wat version of a .c file of specified name
# TARGET must be specified from command line
wat: $(TARGET).c
$(CC) $(CFLAGS) -o $(TARGET).wasm $(TARGET).c && wasm2wat $(TARGET).wasm > $(TARGET).wat && rm $(TARGET).wasm
struct: TARGET = struct
struct: wat
clear:
rm -f *.wasm *.wat
这样调用,效果很好:
[user@pc]$ make wat TARGET=struct
emcc -O2 -s WASM=1 -s SIDE_MODULE=1 -o struct.wasm struct.c && wasm2wat struct.wasm >
struct.wat && rm struct.wasm
现在我想要一个更具体的规则,struct
,如您所见。本质上,我想重用 wat
规则,只需确保在 运行 之前将 TARGET
设置为 'struct'。但是,运行 make struct
给我一个来自 emcc 的 no input file
错误,好像 TARGET
的值不存在:
[user@pc]$ make struct
emcc -O2 -s WASM=1 -s SIDE_MODULE=1 -o .c
shared:ERROR: no input files
实现我的目标的正确方法是什么?
问题是,当 make 评估如何制定目标以及先决条件是什么时,您的 TARGET
是未定义的,因此规则说:wat
需要 .c
。你可以尝试递归并说这样的话:
struct:
$(MAKE) TARGET=struct wat
开始真的不是很好,因为实际上没有生成文件 wat
所以目标总是过时的 Makefile
确实只是有点美化 shell 脚本.
您可能应该考虑编写一个模式规则如何从 .c
构建 .wat
,类似于(基于您的示例):
%.wat: %.c
$(CC) $(CFLAGS) -o $(*F).wasm $< \
&& wasm2wat $(*F).wasm > $@.wat \
&& rm $(*F).wasm
然后您可以调用 make struct.wat
,如果您仍然希望(为了方便起见)只有 struct
目标,您可以添加:
.PHONY: struct
struct: struct.wat
您似乎在尝试使用特定于目标的变量,尤其是它们的继承功能来实现您的目标。
但是,由于 the documentation 中的语句,这无法工作:
As with automatic variables, these values are only available within the context of a target’s recipe (and in other target-specific assignments).
这意味着先决条件中的$(TARGET)
:
wat: $(TARGET).c
在解析 makefile 时计算,而不是在调用 struct
规则时计算,并扩展为:
wat: .c
我看到 Ondrej 提供了答案,所以我就到此为止了:)