Reputation: 685
My Makefile:
CXX = clang++
CXXFLAGS = -g -Wall -std=c++14
LDFLAGS = -lboost_system -lcrypto -lssl -lcpprest -lpthread
OBJDIR = obj
SRCDIR = .
SRC := $(shell find $(SRCDIR) -name "*.cpp")
OBJ := $(SRC:%.cpp=%.o)
APP = run
all: $(APP)
$(APP): $(OBJ)
@echo "== LINKING EXECUTABLE $(APP)"
@$(CXX) $^ $(LDFLAGS) -o $(APP)
%.o: %.cpp
@echo "COMPILING SOURCE $< INTO OBJECT $@"
@$(CXX) -c $(CXXFLAGS) $< -o $@
clean:
find . -name *.o -delete
rm -f $(APP)
Directory structure:
Makefile
sources/
directory1
...cpp
directory2
...cpp
...
main.cpp
obj/
I try to make make
create *.o
files in a directory obj/
and then compile the final executable from there. I tried various approaches and they fail because of the project structure that stores *.cpp
files in sub-directories. Particularly, I've tried the following: https://stackoverflow.com/a/26032630/2042546
I've also tried to manipulate the command itself clang++ $< -o obj/$@
but it breaks whole idea of make and it's dependency management.
If I modify OBJ via patsubstr
and notdir
, make becomes unable to deduce dependency of a *.o
on a corresponding *.cpp
by it's path, cause *.o
's path loses it's directory part and becomes unable to find it's *.cpp
file when executing %.o:%.cpp
rule (I hope I managed to write down my thoughts correctly).
Upvotes: 1
Views: 7775
Reputation: 101041
If you want objects to live in the same source directory structure but under obj
, then simply change your pattern rule (and how you generate the object files). And you should create the directory first:
OBJ := $(SRC:%.cpp=$(OBJDIR)/%.o)
...
$(OBJDIR)/%.o: %.cpp
@echo "COMPILING SOURCE $< INTO OBJECT $@"
@mkdir -p '$(@D)'
@$(CXX) -c $(CXXFLAGS) $< -o $@
Upvotes: 2