Этого можно добиться с помощью разумного использования шаблонных правил в вашем make-файле благодаря двум функциям сопоставления шаблонных правил gmake. Во-первых, gmake пытается сопоставить шаблоны в порядке их объявления; во-вторых, шаблон соответствует тогда и только тогда, когда все предварительные требования в шаблоне могут быть выполнены (либо они уже существуют в виде файлов, либо существует правило для их создания). Итак, если вы напишите свой make-файл так:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
$(CPPC) -c $(FLAGS_DEV) $< -o $@
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CPPC) -c $(FLAGS_DEV) $< -o $@
gmake будет соответствовать первому шаблону для тех файлов, которые имеют соответствующий .h файл, и второму - для тех, у которых его нет. Конечно, современные проверки также будут работать так, как ожидается (например, «foo.o» будет считаться устаревшим, если «foo.h» существует и новее).
Возможно, вы захотите использовать другую переменную, чтобы устранить избыточность между этими двумя правилами; например:
COMPILE=$(CPPC) -c $(FLAGS_DEV) $< -o $@
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
$(COMPILE)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(COMPILE)