首页 文章

将目标名称传递给makefile中的依赖项列表

提问于
浏览
6

我正在尝试编写一个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.

1 回答

  • 16

    问题是这个:

    $(TARGETS): %.o
        ...
    

    不是一个模式规则;先决条件列表中有'%',但目标中没有 . 因此,从字面上解释'%',并且没有 %.o 这样的文件 .

    试试这个:

    $(TARGETS): % : %.o
        $(CXX) $(CFLAGS) $^ $(LIBS) -o $@
    

    这是static pattern rule . 另外,我已经改变 $@.o (这可能会有效,但是它是一个kludge) $^ (这意味着"all of the prerequisites",并且在眼睛上更加强大和容易) .

相关问题