Makefile学习记录

参考<跟我一起写Makefile>
概述:
文件命名为Makefile或者makefile

目录

  • Makefile的形式:
  • 组成
  • 包含其他Makefile
  • 条件判断
    • 1.ifeq
    • 2.ifneq
    • 3.ifdef
    • 4.ifndef
  • 使用函数
    • 1.字符串处理函数
    • 2.文件名操作函数
    • 3.foreach函数
    • 4.if函数
    • 5.call函数
    • 6.origin 函数
  • 隐含规则
    • 1.使用隐含规则
    • 2.隐含规则一览
    • 3.隐含规则使用的变量
    • 4.隐含规则链
    • 5.定义模式规则

Makefile的形式:

targets:prerequisites
	command

targest:prerequisites;command
	command
	

组成

  1. 显示规则:必须显示指示的命令。
  2. 隐晦规则:Makefile内部支持的隐藏用法,可以省却我们很多工作
  3. 变量定义:定义一个变量x,使用$(x)。Makefile中的变量其实就是C/C++中的宏
  4. 文件指示:包含其他Makefile,
  5. 注释: “#”开头

包含其他Makefile

用法:include ,支持通配符? * … 以及其他的Shell支持的命令
当前目录无法找到的话,再去以下路径查找。若使用 -include 会忽略找不到文件的错误继续往下执行

  1. 指定了 “-I"选项,大写的i,如Make -I dir,会到dir下寻找

GNU的make工作时的执行步骤入下:(想来其它的make也是类似)

1、读入所有的Makefile。 
2、读入被include的其它Makefile。 
3、初始化文件中的变量。 
4、推导隐晦规则,并分析所有规则。 
5、为所有的目标文件创建依赖关系链。 
6、根据依赖关系,决定哪些目标要重新生成。 
7、执行生成命令。 

条件判断

1.ifeq

2.ifneq

3.ifdef

4.ifndef

使用函数

$( )

1.字符串处理函数

$(subst ,,)
功能:把字串中的字符串替换成

$(patsubst ,,)
查找中的单词(单词以“空格”、“ Tab”或“回车”“换行”分隔)是否
符合模式,如果匹配的话,则以替换。

$(strip )
去掉字串中开头和结尾的空字符。

$(findstring ,)
在字串中查找字串

$(filter ,)
模式过滤字符串中的单词,保留符合模式的单
词。可以有多个模式。

$(filter-out ,)
模式过滤字符串中的单词,去除符合模式的单
词。可以有多个模式。

$(sort )
给字符串中的单词排序(升序)。

$(word ,)
取字符串中第个单词。(从一开始)

$(wordlist ,,)
从字符串中取从开始到的单词串。 是一个数字

$(words )
统计中字符串中的单词个数。

$(firstword )
取字符串中的第一个单词

2.文件名操作函数

$(dir )

从文件名序列中取出目录部分。目录部分是指最后一个反斜杠( “ /”)
之前的部分。如果没有反斜杠,那么返回"./"

$(notdir )
从文件名序列中取出非目录部分。非目录部分是指最后一个反斜杠(“ /”)
之后的部分

$(suffix )
从文件名序列中取出各个文件名的后缀,返回文件名序列的后缀序列,如果文件没有后缀,则返回空字串

$(basename )
从文件名序列中取出各个文件名的前缀部分。

$(addsuffix ,)
名称:加后缀函数——addsuffix。
功能:把后缀加到中的每个单词后面。
返回:返回加过后缀的文件名序列。
示例: $(addsuffix .c,foo bar)返回值是“ foo.c bar.c”。

$(addprefix ,)
名称:加前缀函数——addprefix。
功能:把前缀加到中的每个单词后面。
返回:返回加过前缀的文件名序列。
示例: $(addprefix src/,foo bar)返回值是“ src/foo src/bar”。

$(join ,)
名称:连接函数——join。
功能:把中的单词对应地加到的单词后面。如果的单词个
数要比的多,那么, 中的多出来的单词将保持原样。如果的单
词个数要比多,那么, 多出来的单词将被复制到中。
返回:返回连接过后的字符串。
示例: $(join aaa bbb , 111 222 333)返回值是“ aaa111 bbb222 333”

3.foreach函数

$(foreach ,,)
把参数中的单词逐一取出放到参数所指定的变量中,然后再执行 所包含的表达式。

names := a b c d
files := $(foreach n,$(names),$(n).o)
上面的例子中, $(name)中的单词会被挨个取出,并存到变量“ n”中,“ $(n).o”每次根
据“ $(n)”计算出一个值,这些值以空格分隔,最后作为 foreach 函数的返回,所以,
$(files)的值是“ a.o b.o c.o d.o”。

4.if函数

$(if ,)
$(if ,,)

5.call函数

$(call ,,,…).

当 make 执行这个函数时, 参数中的变量,如$(1), $(2), $(3)等,会被
参数依次取代。而的返回值就是 call 函
数的返回值

6.origin 函数

隐含规则

“隐含规则”也就是一种惯例, make 会按照这种“惯例”心照不喧地来运行,那怕我们的
Makefile 中没有书写这样的规则

1.使用隐含规则

2.隐含规则一览

1、编译 C 程序的隐含规则。
.o”的目标的依赖目标会自动推导为“.c”,并且其生成命令是“$(CC) –c
$(CPPFLAGS) $(CFLAGS)”
2、编译 C++程序的隐含规则。
.o”的目标的依赖目标会自动推导为“ .cc”或是“ .C”,并且其生成命令是
“ $(CXX) –c $(CPPFLAGS) $(CFLAGS)”。(建议使用“ .cc”作为 C++源文件的后缀,
而不是“ .C”)
3、汇编和汇编预处理的隐含规则。
.o” 的目标的依赖目标会自动推导为“ .s”,默认使用编译品“ as”,并且其生
成命令是:“ $(AS) $(ASFLAGS)”。“ .s” 的目标的依赖目标会自动推导为“ .S”,
默认使用 C 预编译器“ cpp”,并且其生成命令是:“ $(AS) $(ASFLAGS)”。
4、链接 Object 文件的隐含规则。
”目标依赖于“ .o”,通过运行 C 的编译器来运行链接程序生成(一般是“ ld”),
其生成命令是:“ $(CC) $(LDFLAGS) .o $(LOADLIBES) $(LDLIBS)”。这个规则
对于只有一个源文件的工程有效,同时也对多个 Object 文件(由不同的源文件生成)的也
有效。

3.隐含规则使用的变量

1、关于命令的变量。
AR
函数库打包程序。默认命令是“ ar”。
AS
汇编语言编译程序。默认命令是“ as”。
CC
C 语言编译程序。默认命令是“ cc”。
CXX
C++语言编译程序。默认命令是“ g++”。
CO
从 RCS 文件中扩展文件程序。默认命令是“ co”。
CPP
C 程序的预处理器(输出是标准输出设备)。默认命令是“ $(CC) –E”。
FC
Fortran 和 Ratfor 的编译器和预处理程序。默认命令是“ f77”。
GET
从 SCCS 文件中扩展文件的程序。默认命令是“ get”。
LEX
Lex 方法分析器程序(针对于 C 或 Ratfor)。默认命令是“ lex”。
PC
Pascal 语言编译程序。默认命令是“ pc”。
YACC
Yacc 文法分析器(针对于 C 程序)。默认命令是“ yacc”。
YACCR
Yacc 文法分析器(针对于 Ratfor 程序)。默认命令是“ yacc –r”。
MAKEINFO
转换 Texinfo 源文件( .texi)到 Info 文件程序。默认命令是“ makeinfo”。
TEX
从 TeX 源文件创建 TeX DVI 文件的程序。默认命令是“ tex”。
TEXI2DVI
从 Texinfo 源文件创建军 TeX DVI 文件的程序。默认命令是“ texi2dvi”。
WEAVE
转换 Web 到 TeX 的程序。默认命令是“ weave”。
CWEAVE
转换 C Web 到 TeX 的程序。默认命令是“ cweave”。
TANGLE
转换 Web 到 Pascal 语言的程序。默认命令是“ tangle”。
CTANGLE
转换 C Web 到 C。默认命令是“ ctangle”。
RM
删除文件命令。默认命令是“ rm –f”

2、关于命令参数的变量
下面的这些变量都是相关上面的命令的参数。如果没有指明其默认值,那么其默认值都是空。
ARFLAGS
函数库打包程序 AR 命令的参数。默认值是“ rv”。
ASFLAGS
汇编语言编译器参数。(当明显地调用“ .s”或“ .S”文件时)。
CFLAGS
C 语言编译器参数。
CXXFLAGS
C++语言编译器参数。
COFLAGS
RCS 命令参数。
CPPFLAGS
C 预处理器参数。(C 和 Fortran 编译器也会用到)。
FFLAGS
Fortran 语言编译器参数。
GFLAGS
SCCS “ get”程序参数。
LDFLAGS
链接器参数。(如:“ ld”)
LFLAGS
Lex 文法分析器参数。
PFLAGS
Pascal 语言编译器参数。
RFLAGS
Ratfor 程序的 Fortran 编译器参数。
YFLAGS
Yacc 文法分析器参数

4.隐含规则链

有些时候,一个目标可能被一系列的隐含规则所作用。例如,一个[.o]的文件生成,可能会
是先被 Yacc 的[.y]文件先成[.c],然后再被 C 的编译器生成。我们把这一系列的隐含规
则叫做“隐含规则链”

5.定义模式规则

你可以使用模式规则来定义一个隐含规则。一个模式规则就好像一个一般的规则,只是在规
则中,目标的定义需要有“ %”字符。“ %”的意思是表示一个或多个任意字符。在依赖目标
中同样可以使用“ %”,只是依赖目标中的“ %”的取值,取决于其目标。
有一点需要注意的是,“ %”的展开发生在变量和函数的展开之后,变量和函数的展开发生在
make 载入 Makefile 时,而模式规则中的“ %”则发生在运行时
1、模式规则介绍

你可能感兴趣的:(004-Linux)