1.GCC编译器 使用VIM编辑器编程程序后,Ubuntu使用gcc编译 gcc mian.c -o main (将mian.c 编译成main可执行程序) 执行main : ./main gcc 命令: 执行的方法很简单使用命令:’ ./+可执行文件’
格式: gcc [选项] [文件名字]
选项参数:
-c: 只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。
-o: 用来指定编译结束以后的输出文件名,如果不使用这个选项的话 GCC 默
认编译出来的可执行文件名字为 a.out。
-g: 添加调试信息,如果要使用调试工具(如 GDB)的话就必须加入此选项,此选项指示编
译的时候生成调试所需的符号信息。
-O: 对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进
行优化,这样产生的可执行文件执行效率就高。
-O2: 比-O 更幅度更大的优化,生成的可执行效率更高,但是整个编译过程会很慢。
GCC 编译器的编译流程是:预处理、编译、汇编和链接。预处理就是展开所有的头文件、替换程序中的宏、解析条件编译并添加到文件中。编译是将经过预编译处理的代码编译成汇编代码,也就是我们常说的程序编译。汇编就是将汇编语言文件编译成二进制目标文件。链接就是将汇编出来的多个二进制目标文件链接在一起,形成最终的可执行文件,链接的时候还会涉及到静态库和动态库等问题。
2.make和Makefile
make:一般说GNU Make,是一个软件,用于将源代码文件编译为可执行的二进制文件,make工具主要用于完成自动化编译。make工具编译的时候需要Makefile文件提供编译文件。
Makefile文件:make工具所使用的文件,Makefile指明了编译规则。 在工程目录下创建名为“Makefile”的文件,文件名一定要叫做“Makefile”!!!区分大小写的哦!
Makefile:(后面有更简单的格式)
Makefile语法规则:
目标…... : 依赖文件集合……
命令 1
命令 2
……
命令列表中的每条命令必须以 TAB 键开始,不能使用空格!
make 命令会为 Makefile 中的每个以 TAB 开始的命令创建一个 Shell 进程去执行
目标 目标即要生成的文件。如果目标文件的更新时间晚于依赖文件的更新时间,则说明依赖文件没有改动,目标文件不需要重新编译。否则重新编译并更新目标。
依赖 即目标文件由哪些文件生成。如果依赖条件中存在不存在的依赖条件,则会寻找其它规则是否可以产生依赖条件。 例如:规则一是生成目标 hello.out 需要使用到依赖条件 hello.o,但是 hello.o 不存在。则 Makefile 会寻找到一个生成 hello.o 的规则二并执行。
命令 即通过执行该命令,由依赖文件生成目标文件。 注意每条命令前必须有且仅有一个 tab 保持缩进,这是语法要求。
Makefile 变量:Makefile 中的变量都是字符串 第 1 行是注释, Makefile 中可以写注释,注释开头要用符号“#”, 第 2 行我们定义了一个变量 objects,并且赋值字符串“main.o input.o calcu.o”, 第 3 和 4 行使用到了变量 objects,**Makefile 中变量的引用方法是“
(
变
量
名
)
”
∗
∗
,
比
如
本
例
中
的
“
(变量名)”**,比如本例中的“
(变量名)”∗∗,比如本例中的“(objects)”就是使用变量 objects。
变量的引用方式: ” ( 变 量 名 ) “ 或 者 ” ¥ 变 量 名 “ 例 如 : (变量名)“或者”¥{变量名}“ 例如: (变量名)“或者”¥变量名“例如:{Objs}就是取变量Objs的值 注意:当变量名为单字符是可以采用:“$a”的方式引用,多字符则不行
赋值符:”= “ ,“ := ” 和 “ ?= ” ,“ += ”
(1)" = " :借助另外一个变量,可以将变量的真实值推到后面去定义。
也就是变量的真实值取决于它所引用的变量的最后一次有效值
(2)" := " 不会使用后面定义的变量,只能使用前面已经定义好的,
(3)" ?= " 如果前面已经赋过值了,那么就使用前面赋的值。
没有赋值的话就是 等号后面的值
(4)" += " 添加等号后面的值
Makefile 模式规则
模式规则中,至少在规则的目标定定义中要包涵“%”,否则就是一般规则,目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的文件,类似与通配符, a.%.c 就表示以 a.开头,以.c 结束的所有文件。
当“%”出现在目标中的时候,**目标中“%”所代表的值决定了依赖中的“%”**值,使用方法如下:
%.o : %.c
命令
Makefile 自动化变量
自动化变量就是这种变量会把模式中所定义的一系列的文件自动的挨个取出,直至所有的符合模式的文件都取完,自动化变量只应该出现在规则的命令中
结合模式规则和自动化变量Makefile文件如下:
Makefile 伪目标
一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,在执行 make 命令的时候通过指定这个伪目标来执行其所在规则的定义的命令
使用伪目标主要是为了避免 Makefile 中定义的执行命令的目标和工作目录下的实际文件出现名字冲突,有时候我们需要编写一个规则用来执行一些命令,但是这个规则不是用来创建文件的
在调用 make clean 是确保目录下没有clean ,否则不会执行命令 我们可以将clean声明为伪目标 声明方式如下:
.PHONY : clean
声明 clean 为伪目标以后不管当前目录下是否存在名为“clean”的文件,输入“make clean”的话规则后面的 rm 命令都会执行。
Makefile 条件判断 条件判断语法:
(1)
endif
(2)
else
endif
关键字有 4 个: ifeq、 ifneq、 ifdef 和 ifndef ifeq 用来判断是否相等, ifneq 就是判断是否不相等 用法:
ifeq (, )
比较“参数 1”和“参数 2”是否相同,如果相同则为真,“参数 1”和“参数 2”可以为函数返回值。 ifneq 的用法类似,
ifdef 和 ifndef 的用法:
ifdef
如果“变量名”的值非空,那么表示表达式为真,否则表达式为假。“变量名”同样可以是一个函数的返回值。 ifndef 用法类似
Makefile 函数使用 Makefile 支持函数,但是是被定义好的,不支持自定义。 用法:
(1)
$(函数名 参数集合)
(2)
${函数名 参数集合}
调用函数和调用普通变量一样,使用符号“ ” 来 标 识 。 参 数 集 合 是 函 数 的 多 个 参 数 , 参 数 之 间 以 逗 号 “ , ” 隔 开 , 函 数 名 和 参 数 之 间 以 “ 空 格 ” 分 隔 开 , 函 数 的 调 用 以 “ ”来标识。参数集合是函数的多个参数,参数之间以逗号“,”隔开,函数名和参数之间以“空格”分隔开,函数的调用以“ ”来标识。参数集合是函数的多个参数,参数之间以逗号“,”隔开,函数名和参数之间以“空格”分隔开,函数的调用以“”开头。
常用函数: (1)函数 subst 用来完成字符串替换
格式:
$(subst pat,repl,string)
用repl替换 string中的pat匹配项 (留的是中间的,因为中间在中心)
(2)函数 patsubst 函数 patsubst
$(patsubst ,,)
此函数查找字符串 中的单词是否符合模式,如果匹配就用来替换掉, 可以使用通配符“%”,表示任意长度的字符串,函数返回值就是替换后的字符串。如果中也包涵“%”,那么中的“%”将是中的那个“%”所代表的字符串,
$(patsubst %.c,%.o,a.c b.c c.c)
将字符串“a.c b.c c.c”中的所有符合“%.c”的字符串,替换为“%.o”,
替换完成以后的字符串为“a.o b.o c.o”。
(3)函数 dir 用来获取目录
$(dir )
此函数用来从文件名序列中提取出目录部分,
返回值是文件名序列的目录部分,
比如:
$(dir )
提取文件“/src/a.c”的目录部分,也就是“/src”。
(4)函数 notdir 去除文件中的目录部分,也就是提取文件名
$(notdir )
此函数用与从文件名序列中提取出文件名非目录部分,
比如:
$(notdir )
提取文件“/src/a.c”中的非目录部分,也就是文件名“a.c”。
(5)函数 foreach 用于循环
$(foreach , ,)
把参数中的单词逐一取出来放到参数中,然后再执行 所 包含的表达式。 每次 都会返回一个字符串 ,循环的过程中, 中所包含的每个字符串会以空格隔开,最后当整个循环结束时, 所返回的每个字符串所组成的整个字符串将会是函数 foreach 函数的返回值。
(6)函数 wildcard
通配符“%”只能用在规则中,只有在规则中它才会展开,如果在变量定义和函数使用时,通配符不会自动展开,这个时候就要用到函数 wildcard,
$(wildcard PATTERN…)
比如:
$(wildcard *.c)
上面的代码是用来获取当前目录下所有的.c 文件,类似“%”。