Make chooses the same source file for different object files. Both are a list of files, only with different filenames. Make switches between the object files but not the source
The pattern rule does not put all objects in root directory, consider
CFILES := path/to/a.c b.c
OBJFILES := $(foreach f,$(CFILES),$(f:%.c=%.o))
all: $(OBJFILES)
%.o: %.c
$(CC) $(CCFLAGS) -c $< -o $@
Here is what you get:
cc -c path/to/a.c -o path/to/a.o
cc -c b.c -o b.o
The following is not a recommendation, but kind of an exercise in makefile programming.
If you have $(SRCFILES)
and want to compile them one at a time, you can use:
define compile
$1.o: $1.c
$(CC) $(CCFLAGS) -c $$< -o $$@
endef
$(foreach src,$(SRCFILES),$(eval $(call compile, $(src:%.c=%))))
If the correspondence of lists of sources and objects is not by name, but only by placement in list, you can destroy the CFILES
list
define compile
src := $(CFILES)
CFILES := $(wordlist 2, $(words $(CFILES)), $(CFILES))
$1: $(src)
$(CC) $(CCFLAGS) -c $$< -o $$@
endef
$(foreach obj,$(OBJFILES),$(eval $(call compile, $(obj))))
Or you may use a helper list, to keep CFILES
unchanged:
helperlist := $(CFILES)
define compile
src := $(firstword $(helperlist))
helperlist := $(wordlist 2, $(words $(helperlist)), $(helperlist))
$1: $(src)
$(CC) $(CCFLAGS) -c $$< -o $$@
endef
$(foreach obj,$(OBJFILES),$(eval $(call compile, $(obj))))