有几种方法可以做到这一点,没有一种是完美的(直到有人将regex处理放入Make中)。
首先,我注意到一个命令生成给定相机的所有目标,但它针对每个目标运行,这是一种浪费。所以让我们从cam1的目标开始
cam1_outputs := $(addprefix derived/cont_cam1_, $(seg_per_camera))
让第一个成为“主要的”(并从列表中删除)。这将是其余工作的先决条件,也是唯一真正需要运行脚本的工作。(使用更高级的方法可能会有更优雅的方法,但现在就可以了。)
cam1_primary := $(firstword $(cam1_outputs))
cam1_outputs := $(filter-out $(cam1_primary), $(cam1_outputs))
$(cam1_outputs): $(cam1_primary)
$(cam1_primary): /path/to/input/file_1.mat
run_a_script 1
现在把这个扩展到另外两个摄像头。我们可以将“primary”规则重写为模式规则:
$(cam1_primary) $(cam2_primary) $(cam3_primary): derived/cont_cam%_hands.mat: /path/to/input/file_%.mat
run_a_script $*
剩下的我们可以拼出所有三个摄像头,但那将意味着大量的冗余代码。我们可以
define
eval
但如果可能的话我会尽量避免。所以我们就用一个小技巧:
cam2_primary := $(subst cam1,cam2,$(cam1_primary))
# ...and the same for the rest...
(这有点多余,但也不太可怕。)
把它们放在一起,我们得到:
# Mention this first so it'll be the default target
segmentation:
seg_cams_nozero := cam1 cam2 cam3
# seg_per_camera := $(shell echo {,dyn_}{hands,obj{1,2,3,4,5}}.mat)
# Let's do this without the shell:
seg_per_camera := hands $(addprefix obj, 1 2 3 4 5)
seg_per_camera += $(addprefix dyn_, $(seg_per_camera))
seg_per_camera := $(addsuffix .mat, $(seg_per_camera))
cam1_outputs := $(addprefix derived/cont_cam1_, $(seg_per_camera))
# Now's a good time for this.
segmentation_outputs := $(cam1_outputs)
segmentation_outputs += $(subst cam1,cam2,$(cam1_outputs))
segmentation_outputs += $(subst cam1,cam3,$(cam1_outputs))
cam1_primary := $(firstword $(cam1_outputs))
cam1_outputs := $(filter-out $(cam1_primary), $(cam1_outputs))
$(cam1_outputs): $(cam1_primary)
cam2_primary := $(subst cam1,cam2,$(cam1_primary))
cam2_outputs := $(subst cam1,cam2,$(cam1_outputs))
$(cam2_outputs): $(cam2_primary)
cam3_primary := $(subst cam1,cam3,$(cam1_primary))
cam3_outputs := $(subst cam1,cam3,$(cam1_outputs))
$(cam3_outputs): $(cam3_primary)
$(cam1_primary) $(cam2_primary) $(cam3_primary): derived/cont_cam%_hands.mat: /path/to/input/file_%.mat
run_a_script $*
segmentation: $(segmentation_outputs)