we have some C++ code that we need to create a make file in. Each .h and .C pair create an object and then some objects are linked together to form a executable. Pretty standard
This is an example of a pattern rule, it should work fine in gmake
. For very simple builds like this you can mostly rely on the implicit rules. The main thing you have to specify in the target you want to build and its dependencies:
CXXFLAGS:=-g -O -Iincludes
LDFLAGS:=-lm
SRCS:=$(shell ls *.C) # select all .C files as source
OBJS:=$(substr .C,.o,$(SRCS) # list the corresponding object files
foo : $(OBJS)
Note the use of simply expanded variable assignment operator (:=
) rather than the recursive assignment operator (=
) which can reduce the amount of reprocessing make does in more complicated builds.
The syntax you've shown is called a pattern rule in GNU make parlance, and it forms the corner stone of your solution. All you need is to add a way to get the list of .C files dynamically. Others have shown solutions that use $(shell)
to do this, but that's needlessly inefficient. I suggest you instead use $(wildcard), which is a GNU make built-in function designed for just this purpose:
SRCS = $(wildcard *.C)
OBJS = $(patsubst %.C,%.o,$(SRCS))
foo: $(OBJS)
$(CC) -o $@ $^
%.o: %.C
$(CC) $(CPFLAGS) -c $<
If you are looking for something more concise, the following will work too:
foo: $(patsubst %.C,%.o,$(wildcard *.C))
This just eliminates the variables and takes advantage of the fact that GNU make provides a default %.o: %.C
pattern rule, as well as a default rule for linking an executable together from a set of objects. Personally I would use the more verbose version as I find it easier to read and maintain, but to each their own.
Hope that helps,
Eric Melski