Skip to content

Commit ec97bc9

Browse files
committed
隐含规则
1 parent ac53616 commit ec97bc9

4 files changed

+197
-9
lines changed
776 KB
Binary file not shown.

电子书/GNU Make 中文手册.pdf

1.34 MB
Binary file not shown.

电子书/make.pdf

887 KB
Binary file not shown.

跟我一起学makefile笔记.md

+197-9
Original file line numberDiff line numberDiff line change
@@ -625,13 +625,11 @@ all: prog1 prog2 prog3 prog4
625625

626626
### 检查规则
627627

628-
| 参数 | 描述 |
629-
| :----------------------------------------------------------: | :------------------------------------: |
630-
| -n, --just-print, --dry-run, --recon | 不执行参数,只是打印命令 |
631-
| -t, --touch | 把目标文件的时间更新,但不更改目标文件 |
632-
| -q, --question | 如果目标不存在,会打印出一条出错信息 |
633-
| -W <file>, --what-if=<file>, --assume-new=<file>, --new-file=<file> | |
634-
| -p -v | |
628+
| 参数 | 描述 |
629+
| :----------------------------------: | :------------------------------------: |
630+
| -n, --just-print, --dry-run, --recon | 不执行参数,只是打印命令 |
631+
| -t, --touch | 把目标文件的时间更新,但不更改目标文件 |
632+
| -q, --question | 如果目标不存在,会打印出一条出错信息 |
635633

636634
### make 的参数
637635

@@ -640,7 +638,7 @@ all: prog1 prog2 prog3 prog4
640638
| -b, -m | 忽略和其它版本 make 的兼容性 |
641639
| -B, --always-make | 认为所有的目标都需要更新(重编译) |
642640
| -C <dir>, --directory=<dir> | 指定读取 makefile 的目录 |
643-
| -debug[=<options>] | 输出 make 的调试信息<br />a: 也就是 all,输出所有的调试信息<br />b: 也就是 basic,只输出简单的调试信息。即输出不需要重编译的目标<br /> |
641+
| -debug[=<options>] | 输出 make 的调试信息<br />a: 也就是 all,输出所有的调试信息<br />b: 也就是 basic,只输出简单的调试信息。即输出不需要重编译的目标 |
644642
| -d | 相当于“–debug=a” |
645643
| -e, --environment-overrides | 指明环境变量的值覆盖 makefile 中定义的变量的值 |
646644
| -f <file>, --file=<file>, --makefile=<file> | 指定需要执行的 makefile |
@@ -662,10 +660,200 @@ all: prog1 prog2 prog3 prog4
662660
| -v, --version | 输出 make 程序的版本、版权等关于 make 的信息 |
663661
| -w, --print-directory | 输出运行 makefile 之前和之后的当前目录 |
664662
| --no-print-directory | 禁止“-w”选项 |
665-
| -W <file>, --what-if=<file>, --new-file=<file>, --assume-new=<file> | |
663+
| -W <file>, --what-if=<file>, --new-file=<file>, --assume-new=<file> | 设定文件“FILE”的时间戳为当前时间,但不改变文件实际的最后修改时间 |
666664
| --warn-undefined-variables | 只要 make 发现有未定义的变量,那么就输出警告信息 |
667665

668666

669667

670668
# 9 隐含规则
671669

670+
内嵌变量 `CFLAGS` 代表了 `gcc` 编译器编译源文件的编译选项
671+
672+
### 使用隐含规则
673+
674+
隐含规则所提供的依赖文件只是一个最基本的(通常它们之间的对应关系为:“EXENAME.o”对应“EXENAME.c”、“EXENAME”对应于“EXENAME.o”)
675+
676+
```makefile
677+
foo : foo.o bar.o
678+
cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
679+
```
680+
681+
隐含规则是:
682+
683+
```makefile
684+
foo.o : foo.c
685+
cc –c foo.c $(CFLAGS)
686+
bar.o : bar.c
687+
cc –c bar.c $(CFLAGS)
688+
```
689+
690+
```makefile
691+
# 要使用pascal编译器必须明确指出编译命令
692+
foo.o: foo.p
693+
pc $< -o $@
694+
```
695+
696+
```makefile
697+
# sample Makefile
698+
699+
CUR_DIR = $(shell pwd)
700+
INCS := $(CUR_DIR)/include
701+
CFLAGS := -Wall –I$(INCS)
702+
703+
EXEF := foo bar
704+
705+
.PHONY : all clean
706+
all : $(EXEF)
707+
708+
foo : CFLAGS+=-O2
709+
bar : CFLAGS+=-g
710+
711+
clean :
712+
$(RM) *.o *.d $(EXES)
713+
```
714+
715+
### 隐含规则一览
716+
717+
make 的默认后缀列表为:
718+
719+
`.out、.a、.ln、.o、.c、.cc、.C、.p、.f、.F、.r、.y、.l、.s、.S、.mod、.sym、.def、.h、.info、.dvi、.tex、.texinfo、.texi、txinfo、.w、.ch、.web、.sh、.elc、el`
720+
721+
| 隐含规则 | 依赖目标 | 命令 |
722+
| :------------------------: | :----------------------------- | ------------------------------------------------------------ |
723+
| 编译C 程序 | .o<-.c | $(CC) -c $(CPPFLAGS) $(CFLAGS) |
724+
| 编译C++ 程序 | .o<-.cc或.C | $(CXX) -c $(CPPFLAGS) $(CFLAGS) |
725+
| 编译Pascal 程序 | .o<-.p | $(PC) -c $(PFLAGS) |
726+
| 编译Fortran/Ratfor 程序 | .o<-.r<br />.o<-.F<br />.o<-.f | $(FC) –c $(FFLAGS) $(RFLAGS)<br />$(FC) –c $(FFLAGS) $(CPPFLAGS)<br />$(FC) –c $(FFLAGS) |
727+
| 预处理Fortran/Ratfor 程序 | .o<-.r<br />.o<-.F | $(FC) –F $(FFLAGS) $(RFLAGS)<br />$(FC) –F $(FFLAGS) $(CPPFLAGS) |
728+
| 编译Modula-2 程序 | .sym<-.def<br />.o<-.mod | $(M2C) $(M2FLAGS) $(DEFFLAGS)<br />$(M2C) $(M2FLAGS) $(MODFLAGS) |
729+
| 汇编和需要预处理的汇编程序 | .o<-.s<br />.s<-.S | $(AS) $(ASFLAGS)<br />$(CPP) $(CPPFLAGS) |
730+
| 链接单一的object 文件 | <-.o | $(CC) $(LDFLAGS) N.o $(LOADLIBES) $(LDLIBS) |
731+
| Yacc C 程序 | .c<-.y | $(YACC) $(YFLAGS) |
732+
| Lex C 程序 | .c<-.l | $(LEX) $(LFLAGS)” |
733+
734+
### 隐含规则使用的变量
735+
736+
**关于命令的变量**
737+
738+
| 变量名 | 对应命令 | 描述 |
739+
| -------- | -------- | ------------------------------------------ |
740+
| AR | ar | 函数库打包程序 可创建静态库.a 文档 |
741+
| AS | as | 汇编程序 |
742+
| CC | cc | C 编译程序 |
743+
| CXX | g++ | C++ 编译程序 |
744+
| CO | co | 从RCS 中提取文件的程序 |
745+
| CPP | $(CC) -E | C 程序的预处理器(输出是标准输出设备) |
746+
| FC | f77 | Fortran 和Ratfor 的编译器和预处理程序 |
747+
| GET | get | 从SCCS 中提取文件程序 |
748+
| LEX | lex | 将Lex 语言转变为C 或Ratfor 的程序 |
749+
| PC | pc | Pascal 语言编译程序 |
750+
| YACC | yacc | Yacc 文法分析器(针对于C 程序) |
751+
| YACCR | yacc –r | Yacc 文法分析器(针对于Ratfor 程序) |
752+
| MAKEINFO | makeinfo | 转换Texinfo 源文件(.texi)到Info 文件程序 |
753+
| TEX | tex | 从TeX 源文件创建TeX DVI 文件的程序 |
754+
| TEXI2DVI | texi2dvi | 从Texinfo 源文件创建TeX DVI 文件的程序 |
755+
| WEAVE | weave | 转换Web 到TeX 的程序 |
756+
| CWEAVE | cweave | 转换C Web 到TeX 的程序 |
757+
| TANGLE | tangle | 转换Web 到Pascal 语言的程序 |
758+
| CTANGLE | ctangle | 转换C Web 到C |
759+
| RM | rm -f | 删除文件命令 |
760+
761+
**关于命令参数的变量**
762+
763+
| 变量名 | 默认值 | 描述 |
764+
| -------- | ------ | ------------------------------------------------ |
765+
| ARFLAGS | rv | 函数库打包程序AR 命令的参数 |
766+
| ASFLAGS | | 汇编语言编译器参数(当明显地调用.s 或.S 文件时) |
767+
| CFLAGS | | C 语言编译器参数 |
768+
| CXXFLAGS | | C++ 语言编译器参数 |
769+
| COFLAGS | | RCS 命令参数 |
770+
| CPPFLAGS | | C 预处理器参数(C 和Fortran 编译器也会用到) |
771+
| FFLAGS | | Fortran 语言编译器参数 |
772+
| GFLAGS | | SCCS “get”程序参数 |
773+
| LDFLAGS | | 链接器参数 |
774+
| LFLAGS | | Lex 文法分析器参数 |
775+
| PFLAGS | | Pascal 语言编译器参数 |
776+
| RFLAGS | | Ratfor 程序的Fortran 编译器参数 |
777+
| YFLAGS | | Yacc 文法分析器参数 |
778+
779+
### 隐含规则链
780+
781+
除非中间的目标不存在, 才会引发中间规则
782+
783+
只要目标成功产生,所产生的中间目标文件会被以 `rm -f` 删除
784+
785+
使用特殊目标 `.INTERMEDIATE`来指除将那些文件作为中间过程文件来处理
786+
787+
需要保留的文件作为特殊目标 `.SECONDARY` 的依赖文件罗列
788+
789+
需要保留所有.o 的中间过程文件,可以将.o 文件的模式(%.o)作为特殊目标 `.PRECIOUS` 的依赖
790+
791+
同一个隐含规则在一个“链”中只能出现一次
792+
793+
Make会优化一些特殊的隐含规则,而不生成中间文件
794+
795+
### 定义模式规则
796+
797+
798+
799+
### 老式风格的“后缀规则”
800+
801+
802+
803+
### 隐含规则搜索算法
804+
805+
806+
807+
808+
809+
# 10 使用make 更新函数库文件
810+
811+
函数库文件也就是对Object 文件(程序编译的中间文件)的打包文件。在Unix 下,一般是由命令 `ar` 来完成打包工作
812+
813+
### 函数库文件的成员
814+
815+
```makefile
816+
foolib(hack.o): hack.o
817+
ar cr foolib hack.o
818+
819+
foolib(hack.o kludge.o)
820+
821+
foolib(*.o)
822+
```
823+
824+
### 函数库成员的隐含规则
825+
826+
```shell
827+
make foo.a(bar.o)
828+
# 等价于
829+
cc -c bar.c -o bar.o
830+
ar r foo.a bar.o
831+
rm -f bar.o
832+
```
833+
834+
`$%`
835+
836+
### 函数库文件的后缀规则
837+
838+
```makefile
839+
.c.a:
840+
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $*.o
841+
$(AR) r $@ $*.o
842+
$(RM) $*.o
843+
# 等价于
844+
(%.o) : %.c
845+
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $*.o
846+
$(AR) r $@ $*.o
847+
$(RM) $*.o
848+
```
849+
850+
### 注意事项
851+
852+
请小心使用make的并行机制( `-j` 参数)
853+
854+
855+
856+
857+
858+
859+

0 commit comments

Comments
 (0)