views:

151

answers:

3

Our make file compiles .c source files with a static pattern rule like this:

OBJECTS = foo.o bar.o baz.o

$(OBJECTS): %.o: %.c
    $(CC) $< $(C_OPTIONS) -c -o $@

I need to change one of the .c files to an Objective-C .m file. Invoking the compiler is the same for both source types, so I'd like to use the same rule and just tweak it to be more flexible. I'd rather not change the OPTIONS variable because it's also used for the linking step, etc.

Is there a way to make the rule above more flexible to accommodate both .c and .m files?

Thanks

+1  A: 

Not really just copy to

$(OBJECTS): %.o: %.m
  $(CC) $< $(C_OPTIONS) -c -o $@
Mark
It will yield errors. For the first instance no `%.m` files will be found (error!), and for the second--no `%.c` (another error!)
Pavel Shved
Sorry make only looks at what is there if there is no .c file then it will not invoke the %.c rule
Mark
A: 

The call to the same compiler is just a happy occasion. Normally you do not compile objective-c code with $(CC). That just feels strange.

But since you go in a harsh way, I won't post do-it-right solution, where you separate objective-C targets from C targets into two different $(OBJECTS)-like variables and make two rules (which you should really do). Too boring. Instead, take a hack!

OBJC_FILES:=$(subst $(wildcard *.m))

real_name = `(test -h $(1) && readlink $(1) ) || echo $(1)`

$(OBJECTS): %.o: %.c
  $(GCC) $< $(C_OPTIONS) -c -o $(call real_name,$@)

$(OBJC_FILES): %.c: %.m
  ln -s $< $@

And God help those who maintains it!

Btw, this obviously won't work if your m-files are generated.

Pavel Shved
+2  A: 
Beta
I agree with the more robust method - I'd use that. But the OBJECTS = macro needs some $(...) on the RHS.
Jonathan Leffler
Ack! You're right, I should have been more careful.
Beta