我正在尝试编写一个makefile来在同一个目录中构建一组c ++程序,这些程序具有独立的源代码,但类似的编译规则和共享依赖项(公共头文件)。
/path/to/project/
peformance.h
vector.h
pqvm.cpp
quantum/
quantum-tbb.h
quantum-sequential.h
...
tests/
grainsize.cpp
kronecker.cpp
sigma-z.cpp
...
Makefile
我想编译tests
文件夹中的源代码,每个源代码都是相应的可执行文件。下面是我尝试使用的makefile;行$(TARGETS): %.o
中似乎存在问题。
我想引用当前目标的名称(例如grainsize
),并依赖于其对应的目标文件(例如grainsize.o
),%.o
和$@.o
似乎工作。我可以将行更改为$(TARGETS): $(OBJECTS)
但是每个目标都依赖于所有对象,在每次更改时触发大量不必要的重新编译。
基本上如何:如何正确引用其依赖关系列表中的目标名称? 我知道这个相关的问题:Passing target name to a dependency in makefile,但我看不出它会如何应用于这个问题。
CXX = g++
SOURCES = $(wildcard *.cpp)
DEPS = ../performance.h $(wildcard ../quantum/*.h) ../vector.h
TARGETS = $(basename $(SOURCES))
OBJECTS = $(addsuffix .o, $(TARGETS))
INCPATH = -I../../local/include
LIBPATH = -L../../local/lib
LIBS = -lpfm -lpapi -ltbb
OFLAGS = -Wall -O2
DFLAGS = -g3
CFLAGS = -march=native $(OFLAGS) $(DFLAGS) $(INCPATH) $(LIBPATH) -fopenmp
UNAME = $(shell uname)
ifeq ($(UNAME), Linux)
LIBS += -lrt
endif
.PHONY: all
all: $(TARGETS)
#for each target: link its object file to the libraries and produce an executable binary
#this does not work as expected
$(TARGETS): %.o
$(CXX) $(CFLAGS) $@.o $(LIBS) -o $@
#compile each target to its object file
#this works as expected
%.o: %.cpp $(DEPS)
$(CXX) -c $(CFLAGS) -o $@ $<
这是命令行上的错误消息:
$ make
make: *** No rule to make target `%.o', needed by `grainsize'. Stop.
答案 0 :(得分:19)
问题在于:
$(TARGETS): %.o
...
不是模式规则;先决条件列表中有一个'%',但不在目标中。所以Make从字面上解释'%',并且没有%.o
这样的文件。
试试这个:
$(TARGETS): % : %.o
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@
这是static pattern rule。此外,我已将$@.o
(这可能有效,但是是一个kludge)更改为$^
(这意味着“所有先决条件”,并且更加强大且更容易看到。)