Ничего из того, что я знаю, но это потому, что вы пытаетесь заставить заставить работать и императивный язык, когда это не то, чем он является.
В GNU make вы, вероятно, захотите сделать что-то вроде:
pull_tail : SOUND=bark
pull_tail : dog.c
$(CC) $< -o $^
ln $@ $(SOUND)
chase : SOUND=quack
chase : duck.c
$(CC) $< -o $^
ln $@ $(SOUND)
...
Или, что еще лучше, переопределите правило по умолчанию для файлов .c, чтобы обрабатывать ссылки для вас, но странная структура ваших имен (имена программ не имеют лексической связи с именами источников) усложняет задачу.
Если вы хотите, чтобы это можно было быстро перестроить без большого количества ручного редактирования, вы, вероятно, захотите написать скрипт для регенерации фрагмента make-файла из данных и использовать функцию include
GNU make ...