38
votes

all. Let's say I have a program that contains a long list of C source files, A.c, B.c, ...., Z.c, now I want to compile A.c, B.c with certain CFLAGS, and compile the rest part of source files with a different CFLAGS value.

How to write a Makefile to do the above described job? currently what I am doing in my Makefile is:

OBJ=[all other .o files here, e.g. D.o, D.o, E.o .... Z.o]
SPECIAL_OBJS=A.o B.o

all: $(OBJ) $(SPECIAL_OBJS)

$(SPECIAL_OBJS): 
     @echo [Compiling]: $(@:.o=.c)
     $(CC) [SOME OTHER GCC OPTIONS HERE] $(CFLAGS) -c $(@:.o=.c) -o $@

%.o: %.c
     @echo [Compiling]: $<
     $(CC) $(CFLAGS) -o $@ -c $<

It works, but looks just stupid/complicated. Can anyone help to point out what is the recommended way of doing this in Makefile? thanks!

3
Is this Posix Make or GNU Make?jww

3 Answers

49
votes

Try using target-specific variables. A target-specific variable is declared like this:

TARGET: VAR := foo  # Any valid form of assignment may be used ( =, :=, +=, ?=)

Now when the target named TARGET is being made, the variable named VAR will have the value "foo".

Using target-specific variables, you could do this, for example:

OBJ=[all other .o files here, e.g. D.o, D.o, E.o .... Z.o]
SPECIAL_OBJS=A.o B.o

all: $(OBJ) $(SPECIAL_OBJS)

$(SPECIAL_OBJS): EXTRA_FLAGS := -std=c99   # Whatever extra flags you need

%.o: %.c
     @echo [Compiling]: $<
     $(CC) $(CFLAGS) $(EXTRA_FLAGS) -o $@ -c $<
14
votes

The approach taken by linux kernel build system:

CFLAGS += $(CFLAGS-$@)

And then,

CFLAGS-A.o += -DEXTRA
CFLAGS-B.o += -DEXTRA
2
votes

I can't answer the question for raw makefiles, but if you are willing to use automake it is trivial:

foo_CFLAGS = [options passed to CC only when building foo]