GNU Make 可以使用模式匹配来查找变量吗?
Can GNU Make use pattern matching to look up variables?
我正在尝试让 Make 构建一些数据分析,其中有由一个整体参数控制的文件列表。
明确地写成这样:
A_EXTS = a b c d e
B_EXTS = f g h i j
C_EXTS = k l m n o
A.dat : $(foreach EXT, ${A_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
B.dat : $(foreach EXT, ${B_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
C.dat : $(foreach EXT, ${C_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
显然这三个规则之间的唯一区别是 A
vs B
vs C
.
我想试试
%.dat : $(foreach EXT, ${%_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
…但这行不通;例如make B.dat
运行 B.dat
的规则但忽略依赖关系; $^
设置为空字符串。
prefix2_
开头的文件是由另一个配方生成的,所以我不能只在配方中指定它们,它们需要在这里标记为依赖项。
是否可以在不重复相同规则的情况下表达这些依赖关系?
好吧,你不能像你想的那样做,但这与查找变量名无关:这是因为扩展顺序。
目标和先决条件中的变量在解析 makefile 时扩展,但 make 直到很久以后才扩展模式规则中的模式。这意味着当 make 在解析 makefile 时扩展 ${%_EXTS}
变量时,它不知道 %
的值稍后会在它实际尝试构建东西时。
您可以使用 secondary expansion to delay expansion of variables until make's second pass where it is actually finding target names. I pulled the logic out into a separate variable and used call
使其更具可读性:
.SECONDEXPANSION:
EXPANDDEPS = $(foreach EXT,${_EXTS},prefix1_${EXT}.dat prefix2_${EXT}.dat)
%.dat : $$(call EXPANDDEPS,$$*)
python analyse.py $^ > $@
我正在尝试让 Make 构建一些数据分析,其中有由一个整体参数控制的文件列表。
明确地写成这样:
A_EXTS = a b c d e
B_EXTS = f g h i j
C_EXTS = k l m n o
A.dat : $(foreach EXT, ${A_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
B.dat : $(foreach EXT, ${B_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
C.dat : $(foreach EXT, ${C_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
显然这三个规则之间的唯一区别是 A
vs B
vs C
.
我想试试
%.dat : $(foreach EXT, ${%_EXTS}, prefix1_${EXT}.dat prefix2_${EXT}.dat)
python analyse.py $^ > $@
…但这行不通;例如make B.dat
运行 B.dat
的规则但忽略依赖关系; $^
设置为空字符串。
prefix2_
开头的文件是由另一个配方生成的,所以我不能只在配方中指定它们,它们需要在这里标记为依赖项。
是否可以在不重复相同规则的情况下表达这些依赖关系?
好吧,你不能像你想的那样做,但这与查找变量名无关:这是因为扩展顺序。
目标和先决条件中的变量在解析 makefile 时扩展,但 make 直到很久以后才扩展模式规则中的模式。这意味着当 make 在解析 makefile 时扩展 ${%_EXTS}
变量时,它不知道 %
的值稍后会在它实际尝试构建东西时。
您可以使用 secondary expansion to delay expansion of variables until make's second pass where it is actually finding target names. I pulled the logic out into a separate variable and used call
使其更具可读性:
.SECONDEXPANSION:
EXPANDDEPS = $(foreach EXT,${_EXTS},prefix1_${EXT}.dat prefix2_${EXT}.dat)
%.dat : $$(call EXPANDDEPS,$$*)
python analyse.py $^ > $@