我正在尝试编写一个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.
我想引用当前目标的名称(例如粒度)并依赖于它的相应目标文件(例如grainize.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.
解决方法
问题是这个:
$(TARGETS): %.o ...
不是一个模式规则;先决条件列表中有一个’%’,但不在目标中.所以Make从字面上解释’%’,并且没有%.o这样的文件.
试试这个:
$(TARGETS): % : %.o $(CXX) $(CFLAGS) $^ $(LIBS) -o $@
这是一个static pattern rule.此外,我已经将$@.o(它可以工作但是是一个kludge)更改为$^(这意味着“所有先决条件”,并且更加强大且更容易看到).