makefile简略笔记

原文链接:http://blog.chinaunix.net/uid-9407839-id-3063717.html

如果要使用其他文件作为 makefile,则可利用类似下面的 make 命令选项指定 makefile 文件:

$ make -f Makefile.debug

例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件LS编译生成,这三个文件还分别包含自己的头文件a.h 、b.h和c.h。通常情况下,C编译器将会输出三个目标文件filea.o、fileb.o和filec.o。假设filea.c和fileb.c都要声明用到一个名为defs的文件,但filec.c不用。即在filea.c和fileb.c里都有这样的声明:
  #include “defs”
  那么下面的文档就描述了这些文件之间的相互联系:

   #It is a example for describing makefile 
   prog : filea.o fileb.o filec.o 
   cc filea.o fileb.o filec.o -LS -o prog 
   filea.o : filea.c a.h defs 
   cc -c filea.c 
   fileb.o : fileb.c b.h defs 
   cc -c fileb.c 
   filec.o : filec.c c.h 
   cc -c filec.c 

Makefile文件作为一种描述文档一般需要包含以下内容:

  • 宏定义
  • 源文件之间的相互依赖关系
  • 可执行的命令

宏定义:

在引用宏时只需在变量前加$符号,如果变量名的长度超过一个字符,在引用时就必须加圆括号()。 下面都是有效的宏引用:
  $(CFLAGS)
  $Z
  $(Z)

一些宏的预定义变量,在Unix系统中,$*、$@、$?和$<四个特殊宏的值在执行命令的过程中会发生相应的变化,而在GNU make中则定义了更多的预定义变量。

   # Define a macro for the object files 
   OBJECTS= filea.o fileb.o filec.o 
   # Define a macro for the library file 
   LIBES= -LS 
   # use macros rewrite makefile 
   prog: $(OBJECTS) 
   cc $(OBJECTS) $(LIBES) -o prog 
   …… 

如果在make命令后带有新的宏定义:

make “LIBES= -LL -LS”

则命令行后面的宏定义将覆盖makefile文件中的宏定义。若LL也是库文件,此时make命令将连接三个目标文件以及两个库文件LS和LL。

Make命本身可带有四种参数:标志宏定义描述文件名目标文件名。其标准形式为:

Make [flags] [macro definitions] [targets]

flags:

  -i   忽略命令执行返回的出错信息。 
  -s   沉默模式,在执行之前不输出相应的命令行信息。 
  -r   禁止使用build-in规则。 
  -n   非执行模式,输出所有执行命令,但并不执行。 
  -t   更新目标文件。 
  -q   make操作将根据目标文件是否已经更新返回"0"或非"0"的状态信息。 
  -p   输出所有宏定义和目标文件描述。 
  -d   Debug模式,输出有关文件和检测时间的详细信息。 
  Linux下make标志位的常用选项与Unix系统中稍有不同,下面我们只列出了不同部分: 
  -C dir   在读取 makefile 之前改变到指定的目录dir。 
  -I dir   当包含其他 makefile文件时,利用该选项指定搜索目录。 
  -h   help文挡,显示所有的make选项。 
  -w   在处理 makefile 之前和之后,都显示工作目录。

通常,makefile 中还定义有 clean 目标,可用来清除编译过程中的中间文件,例如:

clean:
  rm -f *.o

运行 make clean 时,将执行 rm -f *.o 命令,最终删除所有编译过程中产生的所有中间文件。

示例:

   #Description file for the Make command 
   #Send to print 
   P=und -3 | opr -r2 
   #The source files that are needed by object files 
   FILES= Makefile version.c defs main.c donamc.c misc.c file.c \ 
   dosys.c gram.y lex.c gcos.c 
   #The definitions of object files 
   OBJECTS= vesion.o main.o donamc.o misc.o file.o dosys.o gram.o 
   LIBES= -LS 
   LINT= lnit -p 
   CFLAGS= -O 
   make: $(OBJECTS) 
   cc $(CFLAGS) $(OBJECTS) $(LIBES) -o make 
   size make 
   $(OBJECTS): defs 
   gram.o: lex.c 
   cleanup: 
   -rm *.o gram.c 
   install: 
   @size make /usr/bin/make 
   cp make /usr/bin/make ; rm make 
   #print recently changed files 
   print: $(FILES) 
   pr $? | $P 
   touch print 
   test: 
   make -dp | grep -v TIME>1zap 
   /usr/bin/make -dp | grep -v TIME>2zap 
   diff 1zap 2zap 
   rm 1zap 2zap 
   lint: dosys.c donamc.c file.c main.c misc.c version.c gram.c 
   $(LINT) dosys.c donamc.c file.c main.c misc.c version.c \ 
   gram.c 
   rm gram.c 
   arch: 
   ar uv /sys/source/s2/make.a $(FILES) 

执行了make命令之后,输出结果为:

  $ make 
  cc -c version.c 
  cc -c main.c 
  cc -c donamc.c 
  cc -c misc.c 
  cc -c file.c 
  cc -c dosys.c 
  yacc gram.y 
  mv y.tab.c gram.c 
  cc -c gram.c 
  cc version.o main.o donamc.o misc.o file.o dosys.o gram.o \ 
  -LS -o make
  13188+3348+3044=19580b=046174b

最后的数字信息是执行"@size make"命令的输出结果。之所以只有输出结果而没有相应的命令行,是因为"@size make"命令以"@"起始,这个符号禁止打印输出它所在的命令行。

目标依赖规则:

当目标不存在时,执行对应命令。
当依赖在时间上比目标更新时,执行对应命令。
当依赖关系连续存在时,要依次向上回溯每个目标。

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

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

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

上面那个Makefile中,all和main都是目标。all是没有规则的终极目标,他可以用作生成多个目标。把main和all写在一起的话,make就会检查main的依赖,如果main是最新的就不会执行编译。

上述Makefile文件,执行make all或 make 命令的时候,先检查,main是否存在,如果不存在则检查main的依赖项,main.o和func.o这两个目标,依次向上检查,生成目标。
如果目标存在,但依赖项比目标时间要新,则也要向上检查,生成目标。
————————————————
版权声明:本文为CSDN博主「Corline」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/naughfy/article/details/98775750

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值