tags:

views:

389

answers:

2

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...

+5  A: 

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.

Gregory Pakosz
The eval and foreach functions are a severely under-used feature of gmake.
JesperE
maybe it's because of bugs prior to GNU Make 3.81?
Gregory Pakosz
looks good. I'll give it a try...
Nils Pipenbrinck
A: 

From the manual

  -r, --no-builtin-rules  
            Eliminate  use of the built-in implicit rules.  Also clear out the
            default list of suffixes for suffix rules.
dmckee