CorellianAle
CorellianAle

Reputation: 685

Makefile: compile objects to different directory and build from there

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

Answers (1)

MadScientist
MadScientist

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

Related Questions