Существует несколько способов сделать это, ни один из них не идеален (пока кто-то не помещает обработку регулярных выражений в Make).
Во-первых, я замечаю, что одна команда делает все цели для данной камеры, но она запускается для каждой цели, что является пустой тратой. Итак, давайте начнем с целями для САМ1
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)
Пусть я думаю: каждый бит начал жизнь как инструмент * ad hoc *, и вы склеивали их вместе, чтобы сформировать больший и лучший анализ? Мой дискурс начался именно так. В конце концов он рухнул под собственным весом, и мне пришлось переписать его с нуля. Не то чтобы я сожалел об этом, инструменты * ad hoc * были необходимы, и я извлек ценные уроки на этом пути. – dmckee
Как вы догадались ?! : -P Да, инструменты на самом деле не настолько дружелюбны, что имеют дело с абстрактными вещами, которые Make действительно не хочет думать (т. Е. Они не являются файлами). – rescdsk
Я закончил создание глобальной структуры для отправки данных для каждой последовательной задачи. Я думаю, что у моделей люди даже имеют название для этого подхода. – dmckee