В мелких проектах совершенно не хочется мучиться с cmake, но и Makefile в том виде, что у меня был, далек от совершенства. Полтора часа убил, чтобы автоматом генерировать зависимости. До этого у меня было правило, делающее @touch сишному файлу, если изменился соответствующий заголовочный файл, и это вызывало проблемы с другими сишными файлами, включающими этот же заголовок. Другой проблемой было постоянное напоминание geany, что файл был обновлен извне (то, что содержимое после touch не изменилось, его не волнует).
Множество решений с SO выдавало всякие разные проблемы. Основной было то, что как только я изменю какой-нибудь файл (.h или .c - в разных вариантах по-разному), как make переставал удовлетворяться предыдущей сборкой после обновления и постоянно пересобирал совершенно все!
Вот это решение вроде как спасает ситуацию.
# run `make DEF=...` to add extra defines
PROGRAM = readwfs
LDFLAGS = -lm
SRCS = $(wildcard *.c)
DEFINES = $(DEF) -D_XOPEN_SOURCE=1111
# DEFINES += -DEBUG
CFLAGS = -Wall -Werror -Wextra -std=gnu99
OBJDIR = mk
OBJS = $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o))
DEPS := $(OBJS:.o=.d)
CC = gcc
all : $(PROGRAM)
$(PROGRAM) : $(OBJS)
@echo -e "\t\tLD $(PROGRAM)"
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(PROGRAM)
$(OBJDIR):
mkdir $(OBJDIR)
$(OBJS): $(OBJDIR) $(DEPS)
$(OBJDIR)/%.d: %.c $(OBJDIR)
$(CC) -MM -MG $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
$(OBJDIR)/%.o: %.c
@echo -e "\t\tCC $<"
$(CC) -c $(CFLAGS) -o $@ $<
clean:
@echo -e "\t\tCLEAN"
@rm -f $(OBJS)
@rm -f $(DEPS)
@rmdir $(OBJDIR) 2>/dev/null || true
xclean: clean
@rm -f $(PROGRAM)
(оно, правда, тоже пересобирает все подряд, но уже не постоянно, а лишь несколько последующих запусков).