这是我的简单 Makefile:
#create an exe file
run: link
gcc link.o -o run
#sketch link.o
link.o: main.o sum.o
ld -r main.o sum.o -o link.o
#sketch main.o
main.o: main.c
gcc -c main.c -o main.o
#sketch sum.o
sum.o: sum.c
gcc -c sum.c -o sum.o
#make clean recipie
clean:
rm *.o
rm run
这个 makefile 可能有点不成熟或薄弱。但我真正关心的是目标被击中的过程。在说出实际问题之前,让我们首先看看它的输出。
gcc -c main.c -o main.o
gcc -c sum.c -o sum.o
ld -r main.o sum.o -o link.o
cc link.o -o link
gcc link.o -o run
我的问题是:这是因为命令部分的link
依赖关系run
还是因为link.o
命令部分中的提及run
,make
命令寻找link.o
并再次是因为它main.o
sum.o
的依赖关系link.o
寻找提及依赖关系,或者因为main.o
sum.o
在命令部分中,然后目标中的第一个命令main.o
是分别遇到sum.o
和link.o
?是因为依赖项中提到的文件还是命令中提到的文件?
答案1
这可能与您之前的问题重复,到底是什么导致了 make 中“系统找不到指定的文件”问题?,但让我们用这个来详细解释发生了什么。
Make 从字面上理解你的 Makefile 声明:
run: link
告诉它run
需要link
,并且关联的配方告诉它要创建run
,它应该执行gcc link.o -o run
link.o: main.o sum.o
告诉它link.o
需要main.o
和sum.o
,并且关联的配方告诉它要创建link.o
,它应该执行ld -r main.o sum.o -o link.o
main.o: main.c
告诉它main.o
需要main.c
,并且关联的配方告诉它要创建main.o
,它应该执行gcc -c main.c -o main.o
sum.o: sum.c
sum.c
对和做同样的事情sum.o
当你跑步时
make
Make 尝试满足 Makefile 中的第一个目标run
.它发现没有link
文件,并且 Makefile 中没有指定如何构建link
.然而Make“知道”如何从.o
文件构建无扩展名文件,因此它使用该内置规则来构建link
;决定
cc link.o -o link
这是cc
命令的来源(严格来说,它是 Make 变量的默认值$(CC)
)。
一旦link
可用,Make 就会认为run
满足了先决条件,并运行相应的配方:
gcc link.o -o run
注意link
并未实际使用这里。它只会让事情变得混乱;你应该将第一条规则写为
run: link.o
具体来说,Make 解析run
如下:
run
需要link
link
没有明确的规则,但可以使用内置规则来构建link.o
link.o
需要main.o
和sum.o
main.o
main.c
存在的需求sum.o
sum.c
存在的需求
现在先决条件已解决,Make 可以运行配方:
gcc -c main.o -o main.o
建造main.o
gcc -c sum.c -o sum.o
建造sum.o
ld -r main.o sum.o -o link.o
建造link.o
cc link.o -o link
建造link
gcc link.o -o run
建造run
如果将run
规则重写为run: link.o
,则分辨率更改为
run
需要link.o
link.o
需要main.o
和sum.o
main.o
main.c
存在的需求sum.o
sum.c
存在的需求
和构建
gcc -c main.o -o main.o
建造main.o
gcc -c sum.c -o sum.o
建造sum.o
ld -r main.o sum.o -o link.o
建造link.o
gcc link.o -o run
建造run