How to use a variable list as a target in a Makefile?
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.
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.
You can do that, as per the following:
SRCS=a.c b.c
OBJS=$(SRCS:.c=.o)
$(OBJS): $(SRCS)
cc -c -o a.o a.c
cc -c -o b.o b.c
but you have to remember that the dependencies are complete - it assumes that a.o
depends on b.c
as well which is probably not the case.
What you're probably after is a single rule on how to turn one file type into another:
SRCS=a.c b.c
OBJS=$(SRCS:.c=.o)
all: $(OBJS)
.c.o:
gcc -c -o $@ $<
.c.o
is such a rule which states what commands to run to turn a .c
file into a .o
file. In the actual command, $@
is replaced with the specific target and $<
is replaced with the name of the first prerequisite.
There are many other automatic variables you can use, look them up with info make
or look for a good book on make
if you don't have the info
stuff available.
SRCS = a.c b.c
OBJS = $(SRCS:.c=.o)
.c.o:
${CC} ${CFLAGS} -c -o $@ $<
Though $<
isn't quite portable (IIRC, bsdmake has the meaning of $^
and $<
exactly swapped to what gmake uses), this is the default recipe for .c.o
that would be in effect in either implementation.
精彩评论