如何使用makefile编译另一个目录中的.o文件?



我在不同的目录中有多个源文件。现在我想将它们的对象编译到不同的目录中。 我该怎么做?

我试过这个,但它给了我错误

`SRCDIR = ${SRC}/unix/fs
SRCDIR = ${SRC}/share/ch
SRCDIR = ${SRC}/linux/fs
SRCDIR = ${SRC}/unix/ch
OBJDIR = ${HOME}/build/libverify`
OBJS = ${OBJDIR}/check_format.o
OBJS += ${OBJDIR}/check_code.o
$(CC) $(CFLAGS) -c -o $(OBJS) $(SRCDIR)

它成功构建了一个 check_format.o 文件,但为另一个 .o 文件提供了错误

gcc: error: /home/build/libverify/check_code.o: No such file or directory

这是一个非常简单的示例,其中src/main.cpp一个文件在obj/main.o中编译成一个对象文件:

OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o
build: $(OBJS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
gcc -c $< -o $@

与生成文件类似,您可以指定 obj 和 src 目录。然后,在变量OBJS中指定要创建的对象文件。

但是你需要一个目标来调用。Make 使用它遇到的第一个目标是不传入参数。所以在这里我添加了build:这取决于OBJS.因此,当我运行make时,它会运行目标build,然后尝试在OBJS中构建每个项目。

最后,我们需要一个模式规则,它说:

看起来像obj/%.o(%是通配符),它们取决于源文件src/%.cpp(用.c或.cxx或其他方式替换.cpp)。在规则的正文中,我们添加了我们的 make 行。

gcc -c $< -o $@其中 $

注意:我没有指定源列表 (SRCS),因为它们是由对象的模式匹配所暗示的。 即,如果我想创建一个文件obj/test.o那么这取决于现有的文件 -src/test.cpp基于我在这里输入的模式规则。因此,我可以通过执行以下操作来修改我的makefile以添加更多源文件:

OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o
OBJS += $(OBJDIR)/fred.o
OBJS += $(OBJDIR)/bob.o
$(info objs: $(OBJS))
build: $(OBJS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
gcc -c $< -o $@

运行make的输出为:

$ make
objs: obj/main.o obj/fred.o obj/bob.o
gcc -c src/main.cpp -o obj/main.o
gcc -c src/fred.cpp -o obj/fred.o
gcc -c src/bob.cpp -o obj/bob.o

注意:我添加了行$(info objs: $(OBJS))以打印出OBJS的值

更新

这实际上只是如何拥有多个源文件夹的版本 - 但您需要不断改进,因为它非常基本

OBJ_DIR = obj
SOURCES = src1/bob.cpp
SOURCES += src2/fred.cpp
SOURCES += src3/main.cpp
OUT_DIRS = $(sort $(dir $(SOURCES)))    
# Calculate the objects files - should be: 
#   obj/src1/bob.o
#   obj/src2/fred.o
#   obj/src3/main.o
OBJS = $(addprefix $(OBJ_DIR)/,$(addsuffix .0,$(basename $(pathsubst %,%,$(SOURCES)))))
$(info objs: $(OBJS))
build: $(OBJS)
# Now this rule also requres the object sub-dirs to be created first
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OUT_DIRS)
gcc -c $< -o $@
# Rule to create the object dir folders
$(OUT_DIRS):
mkdir -p $@

注意:我没有测试这个 - 但我已经解释了应该如何形成 OBJS 列表 - 它"应该"工作。所以这里我们仍然使用相同的模式规则,但现在我们将源子文件夹包含在对象路径中,以便模式仍然匹配。您将在obj/内获得一个目录结构,如注释中所述。

您可以通过向makefile添加一点"智能"来查看它的速度会变得更加复杂 - 但是现在您可以将源文件添加到任意数量的子文件夹或子子文件夹中等。

最新更新