2
votes

The following part is commonly found in makefiles.

OBJS := $(SRCS:%.c=$(OBJDIR)/%.o)

$(OBJDIR)/%.o : %.c
    $(CC) $(DEFS) $(CFLAGS) -o$@ $<

Now my source folder contains both C and C++ files, and I want to link all object files created together using g++. But how do I specify to also also include *.cpp files to get compiled. I mean how do I modify OBJS to also include *.cpp files.

For OBJDIR, maybe, I can do the C++ equivalent like this. I guess the makefile would guess correctly when to use CXX (g++ for C++ files) and when to use CC (gcc for C files).

$(OBJDIR)/%.o : %.cpp
        $(CXX) $(DEFS) $(CFLAGS) -o$@ $<

But then, how do I add this rule to OBJS?

2
I believe you can just specify two rules (i.e. $(OBJDIR)/%.o: %.c ... $(OBJDIR)/%.o: %.cpp ...).Oliver Charlesworth
Can you elaborate a bit more. If I have $(OBJDIR_CXX/%.o for C++, and $(OBJDIR)/%.o for C, how do I modify OBJS here?pythonic

2 Answers

2
votes

You want to use:

OBJS := $(addsuffix .o,$(basename $(SRCS)))

then add your pattern rule for building .o from .cpp (unless, as mentioned here, you can just use the built-in rules).

The above strips off the suffix, regardless of what it is, then adds .o to the end.

1
votes

You may not need a rule for building .o files from corresponding .cpp or .c files at all, as Make comes with default rules for that, and those look a lot like what you present. The key is probably to specify which .o files need to be built in the first place.

I often see that approached by classifying the C sources separately from the C++ sources. Then you might have something like this:

C_SRCS = ...
CPP_SRCS = ...

OBJS = $(C_SRCS:.c=.o) $(CPP_SRCS:.cpp=.o)

all: myprog

myprog: $(OBJS)
    $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

If you do need your own rules for building .o files from sources, then you could of course add those.

Note also that the above has no dependencies on GNU make extensions, and if that's important to you then you'll want to avoid GNU style pattern rules for building the object files. That's what traditional suffix rules are for.