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

时间:2019-07-08 07:09:50

标签: makefile

我在不同目录中有多个源文件。现在,我要将其对象编译到其他目录中。 我该怎么办?

我尝试了这个,但是它给了我错误

`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

1 个答案:

答案 0 :(得分:0)

这是一个非常简单的示例,其中一个文件src/main.cpp被编译为obj/main.o中的目标文件:

OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o

build: $(OBJS)

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
    gcc -c $< -o $@

类似于您的makefile,您可以指定obj和src目录。然后,在变量OBJS中指定要创建的目标文件。

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

最后,我们需要一个模式规则,内容为:

类似obj/%.o(%是通配符)的东西,它们取决于源文件src/%.cpp(用.c或.cxx或其他替换.cpp)。在规则的主体中,我们添加了生产线。

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/中获得目录结构。

您可以通过在生成文件中添加一些“智能”来使其变得更加复杂-但现在您可以将源文件添加到任意数量的子文件夹或子文件夹等中。...< / p>