如何遇到这个 Makefile?

如何遇到这个 Makefile?

这是我的简单 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命令部分中的提及runmake命令寻找link.o并再次是因为它main.o sum.o的依赖关系link.o寻找提及依赖关系,或者因为main.o sum.o在命令部分中,然后目标中的第一个命令main.o是分别遇到sum.olink.o?是因为依赖项中提到的文件还是命令中提到的文件?

答案1

这可能与您之前的问题重复,到底是什么导致了 make 中“系统找不到指定的文件”问题?,但让我们用这个来详细解释发生了什么。

Make 从字面上理解你的 Makefile 声明:

  1. run: link告诉它run需要link,并且关联的配方告诉它要创建run,它应该执行gcc link.o -o run
  2. link.o: main.o sum.o告诉它link.o需要main.osum.o,并且关联的配方告诉它要创建link.o,它应该执行ld -r main.o sum.o -o link.o
  3. main.o: main.c告诉它main.o需要main.c,并且关联的配方告诉它要创建main.o,它应该执行gcc -c main.c -o main.o
  4. sum.o: sum.csum.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.osum.o
  • main.omain.c存在的需求
  • sum.osum.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.osum.o
  • main.omain.c存在的需求
  • sum.osum.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

相关内容