Makefile:将对象编译到不同的目录并从那里构建

时间:2018-01-15 17:16:50

标签: c++ makefile subdirectory

我的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)

目录结构:

Makefile
sources/
    directory1
        ...cpp
    directory2
        ...cpp
    ...
    main.cpp
obj/

我尝试在目录make中创建*.o个创建obj/文件,然后从那里编译最终的可执行文件。我尝试了各种方法,但由于将*.cpp个文件存储在子目录中的项目结构,它们失败了。特别是,我尝试过以下方法:https://stackoverflow.com/a/26032630/2042546 我也试图操纵命令本身clang++ $< -o obj/$@,但它打破了make和它的依赖管理的整个想法。

如果我通过patsubstrnotdir修改OBJ,则无法通过其路径推断*.o对相应*.cpp的依赖关系,导致{{1} }}的路径丢失了它的目录部分,并且在执行*.o规则时无法找到它的*.cpp文件(我希望我能够正确地记下我的想法)。

1 个答案:

答案 0 :(得分:1)

如果您希望对象位于相同的源目录结构中但位于obj下,则只需更改模式规则(以及如何生成目标文件)。你应该首先创建目录:

OBJ := $(SRC:%.cpp=$(OBJDIR)/%.o)
  ...
$(OBJDIR)/%.o: %.cpp
        @echo "COMPILING SOURCE $< INTO OBJECT $@"
        @mkdir -p '$(@D)'
        @$(CXX) -c $(CXXFLAGS) $< -o $@