【问题标题】:How to compile .o files in another directory using makefile?如何使用makefile编译另一个目录中的.o文件?
【发布时间】:2019-07-08 07:09:50
【问题描述】:

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

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

`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

【问题讨论】:

标签: makefile


【解决方案1】:

这是一个非常简单的示例,其中一个文件 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(将 .cpp 替换为 .c 或 .cxx 或其他)。在规则的主体中,我们添加了我们的 make 行。

gcc -c $&lt; -o $@ 其中 $

注意:我没有指定源列表 (SRCS),因为它们是由对象的模式匹配所暗示的。 IE。如果我想创建一个文件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 中添加一点“智能”来查看它是否会更快地变得更复杂 - 但现在您可以将源文件添加到任意数量的子文件夹或子子文件夹等中......

【讨论】:

  • 当我做 chganges 时,如果我在不同的目录中有源文件,我需要为每个 .c 编写“$(OBJDIR)/main.o $(OBJDIR)/fred.o”吗?文件
  • 那么你开始进入一个更复杂的 makefile - 我建议这是这个问题的一个变体,这就像一个线程,你将在此过程中回答许多问题。您将希望扩展您的简单 make 文件,每次迭代都在改进,直到您最终得到一个相当复杂的 makefile,但它很容易维护等......我将添加另一个示例 - 但一个简单的示例 - 以展示如何你可以有多个源文件,但你会希望在这方面不断改进......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
相关资源
最近更新 更多