Makefile:不同目录中的 Cpp 文件,将目标文件重定向到 ./obj 和可执行文件到 ./bin

Posted

技术标签:

【中文标题】Makefile:不同目录中的 Cpp 文件,将目标文件重定向到 ./obj 和可执行文件到 ./bin【英文标题】:Makefile: Cpp Files in Different Directories, Redirect Object Files to ./obj and Executable to ./bin 【发布时间】:2017-12-12 21:56:50 【问题描述】:

我的目录结构是这样的

-Project
|--bin
|--obj/
|--class1
  |--class1.h
  |--class1.cpp
|--test
  |--test-wrapper-class.h
  |--test-wrapper-class.cpp
  |--main.cpp

我想写一个 Makefile

1) 创建三个目标文件 main.o、class1.o 和 test-wrapper-class.o 并将这些文件放在 obj 目录中

2) 使用这些目标文件创建一个可执行文件,该可执行文件将放置在 bin 文件夹中

3) 进行清理,将删除 obj 和 bin 中的所有文件

我知道如何创建目标文件。我已经看到从位于同一目录中的所有 cpp 文件创建目标文件的示例,然后将它们全部放在 obj 目录中。我不知道该怎么做是

1) 在不同目录中从 cpp 源创建目标文件,将所有目标文件放在与每个源目录不同的目录中

2) 并使用这些目标文件从目标文件和源文件创建位于另一个目录中的可执行文件。

处于当前状态。我的 Makefile 甚至没有完成这项工作。

CXX=g++
INC=-I/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include ./test_bench/ ./src/
LIB=-L/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/lib-linux64
LIBS=-lsystemc
OBJDIR=obj
_OBJS = main.o test_bench.o
OBJS = $(addprefix $(OBJDIR), _OBJS)


all: $(OBJS)
    $(CXX) $(OBJS) $(INC) $(LIB) $(LIBS) -o out

$(OBJDIR) obj/%.o : %.cpp test_bench.h
    $(CXX) $(OBJS) $(INC) $(LIB) $(LIBS) $< -o $@

我想我非常了解如何包含头文件(库)目录以及如何包含链接器文件。它只是在我不太了解的编译阶段移动文件。

谢谢。

【问题讨论】:

OBJS = $(addprefix $(OBJDIR), _OBJS) 是语法错误,您还想将_OBJS 放在$() 中,因为没有它的字符串只是字符串本身,而不是变量内容。 $(OBJDIR) obj/%.o 也是错误的。你想说$(OBJDIR)/%.o。最后,将您的第一个目标命名为out 而不是all。它会创建这个文件,因此无需将 make 和 reader 与不生成其目标的规则混淆。 【参考方案1】:

让我们从这个问题的一个简单版本开始:

src/
  foo.cpp
  bar.cpp
inc/
  bar.h
obj/
bin/

我想在obj/中构建foo.obar.ofoo.cpp包括bar.h(所以bar.h应该是foo.obar.o的先决条件),我想要链接这些对象以在bin/ 中构建app

技巧一,使用目标的完整路径名:

SRCDIR := src
INCDIR := inc
OBJDIR := obj
BINDIR := bin

OBJECTS:= $(addprefix $(OBJDIR)/, foo.o bar.o)

bin/app: $(OBJECTS)
    $(CXX) $^ -o $@

$(OBJECTS): $(OBJDIR)/%.o: $(SRCDIR)/%.cpp
    $(CXX) -I$(INCDIR) $< -o $@

$(OBJDIR)/foo.o $(OBJDIR)/bar.o: $(INCDIR)/bar.h

现在让我们假设源在多个目录中,例如class1/test/

技巧2,使用vpath查找来源:

vpath %.cpp src

$(OBJECTS): $(OBJDIR)/%.o: %.cpp
    $(CXX) -I$(INCDIR) $< -o $@

不要忘记clean 规则:

.PHONY: clean
clean:
    @rm -fr $(BINDIR)/* $(OBJDIR)/*

其他改进是可能的,但这足以让您入门。

【讨论】:

以上是关于Makefile:不同目录中的 Cpp 文件,将目标文件重定向到 ./obj 和可执行文件到 ./bin的主要内容,如果未能解决你的问题,请参考以下文章

从stem中的文件名生成makefile目标依赖项

用于 c++ 的 Makefile,带有一个 .o 文件和一个 .CPP 文件

源文件具有不同编译器标志的 Makefile

Makefile 中的隐式规则

Makefile 更改以在不同格式的文件之间进行选择

makefile 中未定义的引用