【问题标题】:Makefile all command生成文件所有命令
【发布时间】:2015-09-27 22:50:28
【问题描述】:

我正在学习 c,并试图了解 makefile。我正在学习 C the Hard way。

在练习 2 中,额外的功劳是在我的 makefile 中创建一个命令,允许我通过键入“make”来编译我的 .c 文件。

我的makefile是:

CLAGS=-WALL -g

all: ex1

clean:
    rm ex1

这可行 - 即输入 make clean 删除 ex1 文件,输入 make 将 ex1.c 编译为可执行文件。

但是,我很困惑为什么在 clean 命令中,rm ex1 必须在 clean 下的行上缩进,但是对于 all 命令,如果我在 all 下的行上缩进 ex1,则会引发错误。这是为什么呢?

我的另一个问题是 - 这究竟是如何工作的? all 是否只是一个关键字,类似于“输入 make(没有命令)时,执行此操作”?

感谢任何帮助。

谢谢。

【问题讨论】:

  • 与 C(CFLAGS 实际上不是这里的重点)或 C++ 无关。

标签: makefile


【解决方案1】:

这个:

clean:
    rm ex1

是一个规则。此规则包含一个命令rm ex1。该命令是一个shell 命令。规则中的每个命令都必须缩进一个 TAB 字符(否则 Make 会混淆)。

这个:

all: ex1

是没有命令的规则。这里的“ex1”不是命令,而是先决条件

这个:

all:
    ex1

是无效规则,因为它包含无效命令; “ex1”不是有效的 shell 命令。 (如果您不相信我,请在命令行上尝试。)

如果您在没有指定目标的情况下执行 Make(通过键入“make”),Make 将使用默认目标,这通常是 makefile 中的第一个目标。 (现在有一些例外情况您不必担心。)按照惯例,“all”是执行您想要完成的大部分操作的规则的名称,它通常是默认目标;这是一个约定,而不是 Make 内置的东西。

【讨论】:

  • 谢谢你,很好很简单。最后一个问题 - 当输入 make 时,它会编译 ex1,但是当我没有输入 gcc ex1 ex1.c 作为规则时,它怎么知道编译 ex1?
  • @F.Tahir:“all”规则以“ex1”为先决条件,因此 Make 在执行“all”规则之前寻找一种构建(或重建)ex1 的方法。在这个makefile中没有明确的构建ex1的规则,但是有一个文件ex1.c,并且Make知道如何在不被告知的情况下从foo.c构建foo
【解决方案2】:

因为ex1 是一个默认通过ex1.c 文件调用cc 的目标,所以您也可以将all: 设为这样的目标

all:
    $(CC) -o $(EXECUTABLE) $(CFLAGS) $(LDFLAGS) ex1.c

不要复制粘贴,因为我使用了空格,而Makefiles 需要制表符。

更好的方法是创建一个目标文件目标并在链接到另一个目标时只编译更改的文件,就像这样

CC      = gcc
CFLAGS  = -Wall -Wextra -Werror
LDFLAGS = # empty if you are not going to link to any library
OBJ     = ex1.o
PROGRAM = ex1

all: $(OBJ)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $(PROGRAM) $(OBJ)

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

clean:
    rm -fv *.o $(PROGRAM)

现在您可以轻松地添加更多 .c 文件,只需将它们附加到 OBJ 宏,就像这样

OBJ = ex1.o ex2.o ... exn.o

【讨论】:

  • 那么为什么我在下面一行输入 ex1 不起作用?到底有什么区别?
  • 你的意思是make ex1?这不是一个明确的规则。 Read this for more information.
  • 如果我执行all : make ex1,其中make ex1 位于换行符上,则此方法有效,但如果我执行all: ex1,其中ex1 位于换行符处,则在键入make 时会引发错误.错误是 make: ex1: Command not found Makefile:4: recipe for target 'all' failed make: *** [all] Error 127. 最让我困惑的是makefile如何知道当我启动什么命令时输入 make(默认情况下它是 makefile 中的第一个命令吗?)
  • @F.Tahir:是的,makefile 中的第一条rule 是默认的rule。按照惯例,完成大部分您想做的事情的规则称为all,并且是第一条规则。
  • 好的,这消除了我的大部分困惑,谢谢。仍然不确定为什么 all 命令在像 clean 命令一样缩进时拒绝工作。
猜你喜欢
  • 2021-05-13
  • 1970-01-01
  • 2019-05-27
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
  • 2022-01-07
相关资源
最近更新 更多