我可以将 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))
。
我必须更改它才能使其正常工作:$<
应该是 $^
对于 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