0
votes

I have this working Makefile and I would like to improve it:

CXX = g++
RM = rm -f
CXXFLAGS = -O2 -s -Wall -std=c++11
LDFLAGS = -Wl,-z,relro

SRCS = target1.cpp target2.cpp target3.cpp utils.cpp
OBJS = $(subst .cpp,.o,$(SRCS))

.PHONY: all target1 target2 target3 clean

all: target1 target2 target3

target1: target1.o utils.o
    $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) 

target2: target2.o utils.o
    $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS)

target3: target3.o utils.o
    $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) 

clean:
    $(RM) $(OBJS)

My questions are:

  1. Every target needs utils.o. Is it possible to avoid writing 3 times the same lines for target1/target2/target3?
  2. I would like to separate sources, objects and binaries (Makefile in ./, binaries in ./, sources in src/, objects in obj/). What is the best solution in order to avoid writing target1: obj/target1.o obj/utils.o and so on?

Thanks!

1

1 Answers

0
votes

1) Yes, you can use a pattern rule:

target%: target%.o utils.o
    $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS)

2) It really isn't that bad:

target%: obj/target%.o obj/utils.o
    $(CXX) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS)

You can avoid those two obj/ prefixes, but it really isn't worth the trouble.