Это будет сделано (в GNUMake 3.81):
BINS := $(patsubst apps/%,bin/%,$(programs)) # bin/prog1 bin/prog2 ...
release_bins := $(addsuffix _release,$(BINS)) # bin/prog1_release ...
debug_bins := $(addsuffix _debug,$(BINS)) # bin/prog1_debug ...
$(release_bins): bin/%_release: src/%.cpp
#build the binaries according to the release rule
$(debug_bins): bin/%_debug: src/%.cpp
#build the binaries according to the debug rule
release: $(release_bins)
debug: $(debug_bins)
.PHONY: release debug
# If it turns out that one of the progs needs something else too:
bin/prog20_debug: somethingElse.cpp
(Есть способы сделать это немного более кратким, но ценой ясности.)