2

我有这个似乎可以工作的 Makefile,但我不确定如何:

EXECUTABLE=hello
CC=gcc
OBJS = a.o

all: $(EXECUTABLE)

%.o : %.c
    $(CC) -o $@ -c $<

$(EXECUTABLE): $(OBJS)
    $(CC) -o $@ $<

我知道前 3 行是本地定义,当我输入“Make”时,它将构建all目标。现在从这里我有点迷路了......我猜:

  1. Make看到$(EXECUTABLE)标签并跳转到那个构建命令
  2. 它看到$(OBJS)标签并且由于a.o本地目录中不存在它跳转到模式匹配规则
  3. Make 查找a.c并运行规则以生成a.o
  4. 现在Make返回$(EXECUTABLE)命令并运行.o文件的组合以制作“hello”程序

问题:

  1. 我对该流程的理解是否正确?
  2. 此文件中“标签”的位置是否相关?
  3. 是否有一些我遗漏的 GNU 文档证实了我对它是如何工作的怀疑?
4

2 回答 2

1

你的流程基本上是正确的。如果您没有在命令行上显式传递一个目标,Make 将构建文件中列出的第一个目标。在大多数 makefile 中,人们会将all第一个目标作为第一个目标,因此就像在您的示例中一样,您只需键入make它就会自动构建all目标。make 内部所做的是构建一个您在 Makefile 中定义的依赖项列表。all取决于$(EXECUTABLE)哪个 取决于$(OBJS)。为了满足all目标的创建,它必须从该依赖项列表的底部开始并向上工作。如果您想在这里查看,制作手册实际上非常好:http ://www.gnu.org/software/make/manual/尤其是您的具体问题:http://www.gnu.org/software/make/manual/make.html#How-Make-Works

于 2013-03-08T15:15:19.493 回答
1

我找到了一种工具,至少可以帮助回答我的问题的一部分,所以我将其发布以供我自己和其他人参考:

可以通过$(warning <some string>)调用“调试”Makefile。

所以在我的例子中,我这样使用它:

all: $(warning All before exe call) $(EXECUTABLE)
    $(warning All warning after call)

%.o : %.c
    $(warning before pattern)
    $(CC) -o $@ -c $<
    $(warning after pattern)

$(EXECUTABLE): $(warning before obj) $(OBJS)
    $(warning after obj)
    $(CC) -o $@ $<

得到的输出显示了我的流程:

mike@mike-VirtualBox:~/C$ make
Makefile:6: All before exe call    // started at all
Makefile:14: before obj            // Jumped to EXECUTABLE label
Makefile:10: before pattern        // Jumped to pattern matching
Makefile:10: after pattern
gcc -o a.o -c a.c
Makefile:15: after obj             // back to EXECUTABLE label
Makefile:15: after build           // back to build command
gcc -o hello a.o
Makefile:7: All warning after call

使用它我发现我可以这样做:

$(EXECUTABLE): $(warning before obj) $(OBJS)

但不是:

$(EXECUTABLE): 
    $(warning before obj) 
    $(OBJS)

这是有道理的,因为空白在 Makefile 中很重要

于 2013-03-08T15:23:25.857 回答