Reputation: 86313
I want to write a (gmake) makefile for a compiler that - unlike gcc - puts all output files into a specific directory. Unfortunately this behavior cannot be changed.
My sources are in multiple directories. How do I write a pattern-rule that lets me compile the sources.
Okay, that's a bit unclear. Here is an example. My sources look may like this:
./folder1/foo.c
./folder2/bar.c
and the output files will end up like this:
./obj/foo.obj
./obj/bar.obj
How should my rule to compile my sources look like?
%.obj : %.c
$(COMPILER) -c $<
will not work.
Any ideas? I'd like to avoid an implicit rule for each source file...
Upvotes: 14
Views: 8959
Reputation: 70204
Extracted from some Makefile of mine:
OBJS := $(sort $(patsubst %.cpp,$(OBJECT_DIRECTORY)/%.o,$(patsubst %.c,$(OBJECT_DIRECTORY)/%.o,$(notdir $(SRCS)))))
Where OBJECT_DIRECTORY
points to the object directory and SRCS
is the list of source files (which you can even populate using $(wildcard)
).
Then in the Makefile, I have:
define define_compile_rules
$(OBJECT_DIRECTORY)/%.o: $(1)%.c
@echo " + Compiling '$$<'"
@mkdir -p $$(@D)
$(CC) $$(CFLAGS) -o $$@ -c $$<
endef
$(foreach directory,$(sort $(dir $(SRCS))),$(eval $(call define_compile_rules,$(directory))))
See the $(eval)
function.
Upvotes: 25