I am trying to write a makefile to create a set of C ++ programs in the same directory that has independent source code, but similar compilation rules and common dependencies (common headers).
/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
I want to compile sources in the tests folder, each of which corresponds to a corresponding executable file. Below is the makefile I am trying to use; on line $(TARGETS): %.o there is a problem.
I want to refer to the current target name (for example, grainsize ) and depend on its corresponding object file (for example, grainsize.o ), neither %.o nor $@.o work. I could change the line to $(TARGETS): $(OBJECTS) , but then each target will depend on all objects, causing a lot of unnecessary recompilation with each change.
So basically: how to refer to the target name in its list of dependencies? I know this related question: Passing the target name into a dependency in a makefile , but I cannot figure out how this applies to this problem.
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 $@ $<
This is the error message on the command line:
$ make make: *** No rule to make target `%.o', needed by `grainsize'. Stop.
source share