Есть несколько способов сделать это, но ни один из них не совершенен (пока кто-то не поместит обработку регулярных выражений в 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
Теперь, чтобы распространить это на две другие камеры. Мы можем переписать «первичное» правило как шаблонное правило:
$(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)