tags:

views:

742

answers:

2

Hi All,

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 stuff.

This non-gnu make command just builds all the files into object in a directory

%.o:%.C
    $(CC) $(CPFLAGS)  -c  $<

What this does is for each %.C file (ie every .C file) build a corresponding .o file.

Does anybody know how to do this with gmake?

Cheers

Mark

A: 

This is an example of a pattern rule, it should work fink 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.

dmckee
You're mistaken; the OP shows a standard pattern rule, not a static pattern rule, and there's no good reason for using $(shell) here where $(wildcard) will do the trick without the additional overhead.
Eric Melski
@Eric: Correct about the static pattern rule, of course. Fixed. I use $(shell ) a lot despite the extra fork because I often generalize the command. By using := assignment I suffer he extra only once.
dmckee
+2  A: 

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

Eric Melski