Makefile-all命令

Makefile-all命令,makefile,Makefile,我正在学习c语言,并试图了解makefiles。我正在努力学习C语言 在练习2中,额外的积分表示在makefile中生成一个命令,该命令允许我只需键入“make”即可编译.c文件 我的makefile是: CLAGS=-WALL -g all: ex1 clean: rm ex1 这是可行的,即键入makeclean将删除ex1文件,键入make将ex1.c编译为可执行文件 但是,我不明白为什么在clean命令中,rm ex1必须缩进到clean下面的行中,但是对于all命令,如果

我正在学习c语言,并试图了解makefiles。我正在努力学习C语言

在练习2中,额外的积分表示在makefile中生成一个命令,该命令允许我只需键入“make”即可编译.c文件

我的makefile是:

CLAGS=-WALL -g

all: ex1

clean:
    rm ex1
这是可行的,即键入makeclean将删除ex1文件,键入make将ex1.c编译为可执行文件

但是,我不明白为什么在clean命令中,rm ex1必须缩进到clean下面的行中,但是对于all命令,如果我缩进ex1到all下面的行中,它会抛出一个错误。为什么会这样

我的另一个问题是——这到底是如何工作的?这一切仅仅是一个关键字,它的意思是“当make(没有命令)被键入时,执行此操作”

感谢您的帮助


谢谢。

因为
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)
OBJ = ex1.o ex2.o ... exn.o

因为
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)
OBJ = ex1.o ex2.o ... exn.o
这:

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

这:

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

这:

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

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

这是:

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

这:

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

这:

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


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

那么,如果我在下面的行中键入ex1,为什么它不起作用呢?到底有什么区别?你的意思是
makeex1
?这不是一条明确的规则。如果我执行
all:makeex1
操作,makeex1位于换行符上,则此操作有效,但如果执行
all:ex1
操作,其中
ex1
位于换行符上,则键入make时会抛出错误。错误为make:ex1:Command not found Makefile:4:recipe for target'all'生成失败:**[all]错误127。最让我困惑的是,当我键入make时,makefile如何知道要调用哪个命令(默认情况下是makefile中的第一个命令吗?@F.Tahir:是的,makefile中的第一个规则是默认规则。按照惯例,完成你想做的大部分事情的规则称为
all
,这是第一条规则。好的,这消除了我的大部分困惑,谢谢。仍然不确定为什么all命令像clean命令一样缩进时拒绝工作。那么,如果我在下面的行中键入ex1,为什么它不工作呢?到底有什么区别?你的意思是
makeex1
?这不是一条明确的规则。如果我执行
all:makeex1
操作,makeex1位于换行符上,则此操作有效,但如果执行
all:ex1
操作,其中
ex1
位于换行符上,则键入make时会抛出错误。错误为make:ex1:Command not found Makefile:4:recipe for target'all'生成失败:**[all]错误127。最让我困惑的是,当我键入make时,makefile如何知道要调用哪个命令(默认情况下是makefile中的第一个命令吗?@F.Tahir:是的,makefile中的第一个规则是默认规则。按照惯例,完成你想做的大部分事情的规则称为
all
,这是第一条规则。好的,这消除了我的大部分困惑,谢谢。仍然不确定为什么all命令像clean命令一样缩进时拒绝工作。谢谢,很好,很简单。最后一个问题-当键入
make
时,它将编译ex1,但是当我没有键入
gcc ex1 ex1.c
作为所有规则时,它如何知道编译ex1?@F.Tahir:“all”规则将“ex1”作为先决条件,因此make在执行“all”规则之前寻找一种方法来编译(或重建)
ex1
。在这个makefile中没有关于构建
ex1
的明确规则,但是有一个文件
ex1.c
,Make知道如何从
foo.c
中构建
foo
。谢谢