Reputation: 33
Is there a way to get the prerequisite corresponding to a target in the Makefile (GNU Make)?
For instance, consider the following Makefile:
CXX = g++
CFLAGS = -Wall
MODULE_NAME = myRenderer
BUILD_DIR = bin
SOURCE_FILES = renderer/tracer.cpp renderer/lights/DiffuseLight.cpp renderer/materials/ScatterUtils.cpp
OBJECT_FILES = $(patsubst %,$(BUILD_DIR)/%, $(notdir $(SOURCE_FILES:.cpp=.o)))
$(BUILD_DIR)/$(MODULE_NAME): $(OBJECT_FILES)
$(CXX) -o $@ $^
$(OBJECT_FILES): $(SOURCE_FILES)
@mkdir -p "$(BUILD_DIR)"
$(CXX) $(CFLAGS) -I. -c $< -o $@
when I run make, I can see that the following commands get executed:
g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/DiffuseLight.o
g++ -Wall -I. -c renderer/tracer.cpp -o bin/ScatterUtils.o
g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o
And obviously, this fails to build the executable as it's using only the first prerequisite i.e. renderer/tracer.cpp
to generate all the object files because I am using the $<
automatic variable in the recipe command for the $(OBJECT_FILES)
target.
I wish to know how to fix my Makefile to be able to execute these commands:
g++ -Wall -I. -c renderer/tracer.cpp -o bin/tracer.o
g++ -Wall -I. -c renderer/lights/DiffuseLight.cpp -o bin/DiffuseLight.o
g++ -Wall -I. -c renderer/materials/ScatterUtils.cpp -o bin/ScatterUtils.o
g++ -o bin/myRenderer bin/tracer.o bin/DiffuseLight.o bin/ScatterUtils.o
I cannot seem to find the right automatic variable or a way to fetch the right source file to build a given object file.
Upvotes: 0
Views: 1580
Reputation: 28920
As suggested by Matt you have (at least) two options:
A compilation rule:
# $(1): source file
define MY_RULE
$$(patsubst %.cpp,$$(BUILD_DIR)/%.o,$$(notdir $(1))): $(1)
@mkdir -p "$$(BUILD_DIR)"
$$(CXX) $$(CFLAGS) -I. -c $$< -o $$@
endef
$(foreach f,$(SOURCE_FILES),$(eval $(call MY_RULE,$(f))))
Note the $$
used to escape the first expansion (see The eval Function for a detailed explanation).
The vpath
directive:
vpath %.cpp $(dir $(SOURCE_FILES))
$(BUILD_DIR)/%.o: %.cpp
@mkdir -p "$(BUILD_DIR)"
$(CXX) $(CFLAGS) -I. -c $< -o $@
Upvotes: 1