初识makefile结构

1,471 阅读3分钟

makefile的意义

  • makefile通过特定的语法定义源文件之间的依赖关系
  • makefile说明如何编译各个源文件并生成可执行文件

#依赖的定义:

targets:prerequisites;command1
'\t'command2

makefile中的元素含义

  • targets(目标)
    --通常是需要生成的目标文件名
    --make所需执行的命令名称
  • prerequisites(依赖条件,可以省略)
    --当前目标所依赖的其它目标或文件
  • command(命令)
    --完成目标所需要执行的命令

规则中的注意事项

  • targets可以包含多个目标 --使用空格对多个目标名进行分割
  • prerequisites可以包含多个依赖 --使用空格对多个依赖进行分割
  • [Tab]键:'\t'
    --每一个命令行必须以[Tab]字符开始 --[Tab]字符告诉make此行是一个命令行
  • 续行符:
    --可以将内容分开写到下一行,提高可读性
    ##makefile依赖示例:
all:test
        echo "make all"
test:
        echo "make test"

目标all依赖于test,当执行all的时候,执行过程为:先执行test依赖与命令,然后执行all内部的命令

依赖规则

  • 当目标对应的文件不存在,执行对应命令
  • 当依赖在时间上比目标更新,执行对应命令
  • 当依赖关系连续发生时,对比依赖链上的每一个目标

小技巧

makefile中可以在命令前加上@符,作用为命令无回显。

makefile依赖规则

  • 使用@符后,将不再打印命令语句,而是直接执行命令语句的内容
  • all依赖于test,故先执行test依赖与命令,然后才会执行all命令

makefile依赖示例1:使用@符

makefile依赖示例1

makefile依赖示例2:不使用@符

makefile依赖示例2

makefile依赖示例3:执行特定目标

makefile依赖示例3

第一个使用make的编译示例

hello.out:main.o func.o
        gcc -o hello.out main.o func.o 

mail.o:main.c
        gcc -o main.o -c main.c

func.o:func.c
        gcc -o func.o -c func.c

示例中的依赖关系如下:

  • hello.out依赖于main.o和func.o
  • main.o依赖于main.c
  • func.o依赖于func.c

小技巧

工程开发中可以将最终可执行文件名和all同时作为makefile中第一条规则的目标。

hello.out all:main.o func.o
        gcc -o hello.out main.o func.o 

make示例1:仅将all作为makefile中第一条规则的目标

  • make示例--func.c
    func.c
  • make示例--main.c
    main.c
  • make示例--makefile与编译执行结果
    makefile

从编译执行结果可知:
--第一次执行make命令的时候,编译器会根据依赖关系调用对应的命令,并同时生成目标文件func.o和main.o,
--第二次或者第三次执行make命令的时候,虽然目标文件func.o和main.o并没有做任何更改,但是因为编译器没有生成hello.out,故编译器每次都会执行all命令去生成目标文件hello.out。

make示例2:将最终可执行文件名hello.out和all同时作为makefile中第一条规则的目标

makefile
从编译执行结果可知:
当使用最终可执行文件名hello.out和all同时作为makefile中第一条规则的目标的时候,
--第一次执行make命令的时候,编译器会生成同时目标文件func.o、main.o、hello.out;
--第二次执行make命令的时候,由于目标文件hello.out已经存在,故编译器不会再执行all目标之后的命令。

#小结

  • makefile用于定义源文件间的依赖关系
  • makefile说明如何编译各个源文件并生成可执行文件
  • makefile中的目标之间存在连续依赖关系
  • 依赖存在并且命令执行成功是目标完成的充要条件