Reputation: 65
Currently the shell script checks for the existence of intended object directory right before each compiler call. How do I modify my Makefile so that the code checks only once before it moves on to compiling all the prerequisites?
Here is my Makefile:
#########################################################
## BUILD TASKS ##
#########################################################
HDIR := hdr
SDIR := src
ODIR := obj
EXET := a
OBJS := main.o mainhdr.o testcode.o
OSRC := $(addprefix $(ODIR)/, $(OBJS))
CXX := g++
CXXFLAGS := -I$(HDIR) -g -Wall -std=c++17
## BUILD DIRECTIVE:
all: $(EXET)
$(EXET): $(OSRC)
$(CXX) $(CXXFLAGS) $^ -o $@
$(ODIR)/%.o: $(SDIR)/%.cpp
if [ ! -d "$(ODIR)" ]; then mkdir $(ODIR); fi
$(CXX) -c $(CXXFLAGS) $^ -o $@
## foo.bak: foo.bar
## if [ ! -d "$(ODIR)" ]; then mkdir $(ODIR); fi
#########################################################
## CLEAN TASK ##
#########################################################
.PHONY: clean
clean:
rm -r $(EXET) $(ODIR)
I have tried putting:
foo.bak: foo.bar
if [ ! -d "$(ODIR)" ]; then mkdir $(ODIR); fi
as suggested here right before the clean task, but that doesn't seem to work. I could be understanding it wrong, but isn't that the Makefile is executed recursively so by putting that block of code at the end it should be at the tip of recursion and thus executed before everything else?
Upvotes: 0
Views: 168
Reputation: 14468
On newer gnu-make, you can use 'order-only-prerequisites`. This eliminate the timestamp checking, and only required that the prerequisite will exists. This works well to ensure that directories will be created before files are stored into them, and can significantly speedup build jobs
$(ODIR):
mkdir $(ODIR)
# Note pipe '|' to separate order only prereq.
$(ODIR)/%.o: $(SDIR)/%.cpp | $(ODIR)
$(CXX) -c $(CXXFLAGS) $^ -o $@
See: https://www.gnu.org/software/make/manual/make.html#Prerequisite-Types
Upvotes: 1