How to use a variable list as a target in a Makefile?

Nathan Osman picture Nathan Osman · Dec 1, 2010 · Viewed 53.2k times · Source

Suppose I am working on a makefile and I have the following variable declaration at the top:

FILES = file1.cpp file2.cpp file3.cpp

Now suppose I want to compile each of those with a special command without specifying each target like this:

file1.o : file1.cpp
    custom_command file1.cpp
file2.o : file2.cpp
    custom_command file2.cpp
file3.o : file3.cpp
    custom_command file3.cpp

Is there a better way to do this using the $(FILES) variable I declared above?

Something like:

$(FILES:.cpp=.o) : $(FILES)
    custom_command $(FILES)

...only it needs to do this for each file in the $(FILES) variable.

Answer

Chris picture Chris · Dec 1, 2010

Yes. There are what are known as pattern rules. An example is the easiest to understand:

%.o: %.cpp
       $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

(remember that Makefiles require tabs). This rule describes how to make an object file from a cpp file.

If you do not want such a broad rule, you can use what are called static patterns:

objects = file1.o file2.o file3.o

all: $(objects)

$(objects): %.o: %.cpp
        $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

Here's the section on static pattern rules and pattern rules in the GNU Make manual.