我可以将 src/ 中的所有 .cpp 文件编译为 obj/ 中的 .o,然后链接到 ./ 中的二进制文件吗?

Posted

技术标签:

【中文标题】我可以将 src/ 中的所有 .cpp 文件编译为 obj/ 中的 .o,然后链接到 ./ 中的二进制文件吗?【英文标题】:Can I compile all .cpp files in src/ to .o's in obj/, then link to binary in ./? 【发布时间】:2011-02-23 21:11:39 【问题描述】:

我的项目目录如下所示:

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

我希望我的makefile 将/src 文件夹中的所有.cpp 文件编译为/obj 文件夹中的.o 文件,然后链接/obj 中的所有.o 文件进入***文件夹/project中的输出二进制文件。

我几乎没有使用 Makefile 的经验,并且不确定要搜索什么来完成此操作。

另外,这是一种“好”的方法吗,还是有一种更标准的方法来解决我正在尝试做的事情?

【问题讨论】:

gnu.org/software/make/manual/make.html,例如:gnu.org/software/make/manual/make.html#Simple-Makefile @aaa:我猜 OP 想要一个不需要明确列出每个源文件的解决方案。 我不想指定我拥有的每个源文件,并且我之前曾尝试阅读该手册,但我发现它杂乱无章且难以理解。我从一个实际示例中学到了很多东西,该示例执行了我的预期并且解释得很好,而不是枯燥的技术手册。 好的。但是使用好的示例制作文档非常好(它不是尝试技术手册)。您正在寻找模式规则:gnu.org/software/make/manual/make.html#Pattern-Rules 这看起来更像我想要的。虽然,恕我直言,make 手册有点枯燥,因为它似乎更针对于 make 中级水平的开发人员,除此之外,它非常庞大和深入。也许太多了。 【参考方案1】:

Makefile 部分问题

这很容易,除非你不需要概括 尝试类似下面的代码(但用 g++ 附近的制表符替换空格缩进)

SRC_DIR := .../src
OBJ_DIR := .../obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...

main.exe: $(OBJ_FILES)
   g++ $(LDFLAGS) -o $@ $^

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
   g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

自动生成依赖图

大多数品牌系统的“必备”功能。通过将-MMD 标志添加到CXXFLAGS -include $(OBJ_FILES:.o=.d) 到makefile 主体的末尾,可以在编译过程中一次性完成GCC in:

CXXFLAGS += -MMD
-include $(OBJ_FILES:.o=.d)

正如大家已经提到的,总是有GNU Make Manual 在身边,这非常有帮助。

【讨论】:

啊,你秒杀我。但我建议OBJ_FILES = $(patsubst src/%.cpp,obj/%.o,$(CPP_FILES)) 我必须更改它才能使其正常工作:$&lt; 应该是 $^ 对于 main.exe 的规则,我认为 obj/%.o: src/%cpp 有一个错字。 @bobah 你少了一个“。”在您的 cpp 对象规则中 特殊变量可能值得解释,因为它们是特定于 makefile 且难以搜索:gnu.org/software/make/manual/html_node/Automatic-Variables.html 我知道这是一个老问题,但我根据我的项目进行了一些修改,但它不起作用。这是我的生成文件:pastebin.com/4CksG9Wc 我进入控制台:make: *** No rule to make target '/main.o', needed by 'bin/main'. Pare.【参考方案2】:

通配符也适用于我,但我想为那些使用目录变量的人提供一个旁注。文件夹树总是使用斜杠(不是反斜杠),否则会失败:

BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib

MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)

【讨论】:

你的意思是正斜杠吗?您的示例显示了传统上被认为是正斜杠的内容。具体来说,“向右倾斜”的被认为是“向前”,向左的被认为是“向后” 是的,你说得对,我的意思只是“斜线”。我更新了帖子。

以上是关于我可以将 src/ 中的所有 .cpp 文件编译为 obj/ 中的 .o,然后链接到 ./ 中的二进制文件吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual Studio 2010 Express 中将 cpp 编译为 dll

如何将文件 .cpp 编译为带有压缩功能的 exe? [关闭]

项目结构包编译为exe!

将 Zxing 库编译为 .a 文件并包含在项目中

如何将 C++ 文件编译为 WebAssembly?

Make-File:将多个 SRC 文件夹编译为单个 OBJ 文件夹