@@ -625,13 +625,11 @@ all: prog1 prog2 prog3 prog4
625
625
626
626
# ## 检查规则
627
627
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 | 如果目标不存在,会打印出一条出错信息 |
635
633
636
634
# ## make 的参数
637
635
@@ -640,7 +638,7 @@ all: prog1 prog2 prog3 prog4
640
638
| -b, -m | 忽略和其它版本 make 的兼容性 |
641
639
| -B, --always-make | 认为所有的目标都需要更新(重编译) |
642
640
| -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,只输出简单的调试信息。即输出不需要重编译的目标 |
644
642
| -d | 相当于“–debug=a” |
645
643
| -e, --environment-overrides | 指明环境变量的值覆盖 makefile 中定义的变量的值 |
646
644
| -f <file>, --file=<file>, --makefile=<file> | 指定需要执行的 makefile |
@@ -662,10 +660,200 @@ all: prog1 prog2 prog3 prog4
662
660
| -v, --version | 输出 make 程序的版本、版权等关于 make 的信息 |
663
661
| -w, --print-directory | 输出运行 makefile 之前和之后的当前目录 |
664
662
| --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”的时间戳为当前时间,但不改变文件实际的最后修改时间 |
666
664
| --warn-undefined-variables | 只要 make 发现有未定义的变量,那么就输出警告信息 |
667
665
668
666
669
667
670
668
# 9 隐含规则
671
669
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