1、硅谷嵌入式教育 真实项目为依托Linux 的编程常识 用户程序、函数库、系统调用、内核硅谷嵌入式教育 真实项目为依托Linux 的编程常识 系统调用系统调用系统调用是操作系统提供给外部应用程序的一组特殊的接口。应用程序通过这组特殊“接口”来获得操作系统内核提供的服务。在 C 语言中,操作系统的系统调用通常通过函数调用的形式完成,这是因为这些函数封装了系统调用的细节,将系统调用的入口、参数以及返回值用 C 语言的函数调用过程实现。硅谷嵌入式教育 真实项目为依托Linux 的编程常识 应用编程接口应用编程接口API程序员并不是直接使用系统调用。程序员调用的是函数库中定义的应用编程接口API。也就是
2、,通过应用编程接口,使用系统调用,请求内核服务。一个API可能对应几个系统调用。通过系统调用就可以请求内核服务,为何还用引入应用编程接口API呢。硅谷嵌入式教育 真实项目为依托 C 函数库GNU 的C函数库glibc,是 Linux 上最重要的函数库。它定义了 ANSI C 标准指定的所有的库函数,以及由 POSIX 或其他 UNIX 操作系统统变种指定的附加特色,还包括有与 GNU 系统相关的扩展。ANSI C:C 编程语言的国际标准编程语言的国际标准 POSIX:GNU C 函数库实现了函数库实现了 POSIX.1(POSIX 系系统应用程序编程接口)指定的所有函数。同时,统应用程序编程接
3、口)指定的所有函数。同时,GUN C 函数库还支持部分由函数库还支持部分由 POSIX.2(POSIX Shell 和和 工工具标准具标准)指定的函数。)指定的函数。Berkeley Unix:BSD 和和 SunOS。GNU C 函数库定函数库定义了某些义了某些 UNIX 版本中尚未标准化的函数版本中尚未标准化的函数。Linux 的编程常识硅谷嵌入式教育 真实项目为依托库和头文件的保存位置 函数库 /lib:系统必备共享库:系统必备共享库 /usr/lib:标准共享库和静态库:标准共享库和静态库 /usr/i486-linux-libc5/lib:libc5 兼容性函数库兼容性函数库 /us
4、r/X11R6/lib:X11R6 的函数库的函数库 /usr/local/lib:本地函数库:本地函数库 头文件 /usr/include:系统头文件:系统头文件 /usr/local/include:本地头文件:本地头文件 Linux 的编程常识硅谷嵌入式教育 真实项目为依托C 语言编程风格在Linux上编程主要有两种编程风格:GNU风格和Linux内核风格。GNU风格 例如:例如:函数的开头的左花括号放到最左边函数的开头的左花括号放到最左边,避免把任,避免把任何其它的左花括号、左括号或者左方括号放到最左边。何其它的左花括号、左括号或者左方括号放到最左边。对于函数定义来说,把函数名的起始字
5、符放到最左边对于函数定义来说,把函数名的起始字符放到最左边也同样重要。也同样重要。int lots_of_args(int an_integer,long a_long,short a_short,double a_double,float a_float)Linux 的编程常识硅谷嵌入式教育 真实项目为依托C 语言编程风格 Linux 内核编程风格 缩进:缩进:LinuxLinux内核缩进风格是内核缩进风格是8 8个字符。个字符。括号的位置:将开始的大括号放在一行的最后,而将括号的位置:将开始的大括号放在一行的最后,而将结束的大括号放在一行的第一位。结束的大括号放在一行的第一位。命名:命名尽
6、量简洁。命名:命名尽量简洁。函数:函数最好短小精悍,函数:函数最好短小精悍,而且只能做一件事。而且只能做一件事。详见:详见:/usr/src/linux/Documentation/CodingStyleLinux 的编程常识硅谷嵌入式教育 真实项目为依托Linux 编程环境概述 主要涉及到编辑器、编译链接器、调试器及项目管主要涉及到编辑器、编译链接器、调试器及项目管理工具。理工具。编辑器编辑器Linux 中最常用的编辑器有 Vi(Vim)和 Emacs编译链接器编译链接器在在Linux中,最常用的编译器是中,最常用的编译器是Gcc编译器。它是编译器。它是GNU推出的功引导代码能强大、性能优越
7、的多平台编译器推出的功引导代码能强大、性能优越的多平台编译器.调试器调试器Gdb 是绝大多数是绝大多数 Linux 开发人员所使用的调试器,它开发人员所使用的调试器,它可以方便地设置断点、单步跟踪等可以方便地设置断点、单步跟踪等硅谷嵌入式教育 真实项目为依托Linux 编程环境概述 项目管理器项目管理器Linux 中的项目管理器中的项目管理器“make”是一种控制编译或者重是一种控制编译或者重复编译软件的工具。复编译软件的工具。它还能它还能自动管理软件编译的内容、方式和时机自动管理软件编译的内容、方式和时机,使程序,使程序员能够把精力集中在代码的编写上而不是在源代码的组员能够把精力集中在代码的
8、编写上而不是在源代码的组织上。织上。硅谷嵌入式教育 真实项目为依托 VI是Linux最常用的编辑器,Linux里提供的是VI的加强版VIM,但同VI是完全兼容。Vi 3种基本工作模式:命令模式、插入模式、末行模式。Linux下VIM的使用硅谷嵌入式教育 真实项目为依托 VI 3种基本工作模式:命令模式下,键入的每个字符都被当作一个命令处理。刚启动时,处于命令模式。在插入模式下按“ESC”,也可以回到指令模式。插入模式。在命令模式下按“a”、“i”、“o”进入插入模式。末行命令模式也是一种常用模式,用于输入命令进行文字编辑的辅助功能。通过冒号“:”进入末行模式。例如“:q”Linux下VIM的使
9、用硅谷嵌入式教育 真实项目为依托 VIM进入:在系统提示符“$”下键入命令vim,后面跟上想要编辑(或者建立)的文件名,VIM 可以自动载入所要编辑的文件或是开启一个新文件。VIM的退出:可以在命令行方式下使用命令“:wq”或者“:q!”,前者的功能是写文件并从VIM中退出,后者的功能是从VIM中退出,但不保存所作的修改(注意冒号)。Vim中的语法加亮::syntax enable,也可以在配置文件中激活该功能。Linux下VIM的使用硅谷嵌入式教育 真实项目为依托 Vimrc配置文件Vim在启动时会读取该文件。该文件可以放在用户目录下/.vimrc,/etc/vim/vimrc编写语法可参考
10、vi的用户手册的41章。Vim的使用教程:推荐使用vimtutor,学习vim的最好方式就是练习,而vimturor是非常好的教学平台。Vimtutor 使用系统默认语言Vimtutor en 英文教程 练习vim的使用Linux下VIM的使用硅谷嵌入式教育 真实项目为依托vi的常用命令命令命令说明说明功能键功能键h向左移一个字符向左移一个字符 I向右移一个字符向右移一个字符 J向上移一个字符向上移一个字符 k向下移一个字符向下移一个字符 0移至该行之首移至该行之首 Home$移至该行之末移至该行之末 End 硅谷嵌入式教育 真实项目为依托H 移至窗口的第一行移至窗口的第一行 M 移至窗口的中
11、间那行移至窗口的中间那行 L 移至窗口的最后一行移至窗口的最后一行 G 移至该文件的最后一行移至该文件的最后一行 nG 移至该文件的第移至该文件的第 n 行行 Ctrl+f 向后翻一页向后翻一页 PageDown Ctrl+b 向前翻一页向前翻一页 PageUp 移至该行的第一个非空白字移至该行的第一个非空白字符处符处 硅谷嵌入式教育 真实项目为依托命令命令 说明说明 功能键功能键 x 删除光标后的字符删除光标后的字符 Delete X 删除光标前的字符删除光标前的字符 dd 删除光标所在的行删除光标所在的行 ndd 删除包括光标所在行的删除包括光标所在行的n行文本行文本 r 修改光标所在字符
12、修改光标所在字符 硅谷嵌入式教育 真实项目为依托R 进入替换状态,直到按进入替换状态,直到按Esc回到回到命令模式为止命令模式为止 Insert s 删除光标所在字符,并进入输入删除光标所在字符,并进入输入模式模式 S 删除光标所在的行,并进入输入删除光标所在的行,并进入输入模式模式 u 恢复刚才被修改的文本恢复刚才被修改的文本 U 恢复光标所在行的所有修改恢复光标所在行的所有修改.重复上一次命令的操作重复上一次命令的操作 硅谷嵌入式教育 真实项目为依托命令命令 说明说明 Y 复制当前行至编辑缓冲区复制当前行至编辑缓冲区 nY 复制当前行开始的复制当前行开始的n行至编辑缓冲区行至编辑缓冲区 p
13、 将编辑缓冲区的内容粘贴到光标后的一行将编辑缓冲区的内容粘贴到光标后的一行 P 将编辑缓冲区的内容粘贴到光标前的一行将编辑缓冲区的内容粘贴到光标前的一行 a 从光标所在位置后面开始新增文本从光标所在位置后面开始新增文本 硅谷嵌入式教育 真实项目为依托命令命令 命令说明命令说明A 从光标所在行最后面的地方开始新增文本从光标所在行最后面的地方开始新增文本 i 从光标所在位置前面开始插入文本从光标所在位置前面开始插入文本 I 从光标所在列的第一个非空白字元前面开始插入文从光标所在列的第一个非空白字元前面开始插入文本本 o 在光标所在列下新增一行并进入输入模式在光标所在列下新增一行并进入输入模式 O
14、在光标所在列上方新增一行并进入输入模式在光标所在列上方新增一行并进入输入模式 硅谷嵌入式教育 真实项目为依托命令命令 说明说明:q 结束编辑结束编辑:q!强制离开强制离开vi,放弃存盘,放弃存盘:w 存盘存盘:w filename 将编辑内容保存为名为将编辑内容保存为名为filename的文件的文件:wq 存盘并退出存盘并退出 硅谷嵌入式教育 真实项目为依托 GNU C ANSI C(标准(标准 C)GNU C 支持支持GNU 扩展的扩展的C 语言。语言。GNC CC对对C 语语言提供了很多扩展,这些扩展对优化、目标代码布局、言提供了很多扩展,这些扩展对优化、目标代码布局、更安全的检查等方面提
15、供了很强的支持。更安全的检查等方面提供了很强的支持。Linux 内核代码使用了大量的内核代码使用了大量的 GNU C 扩展,以至于能扩展,以至于能够编译够编译 Linux 内核的唯一编译器是内核的唯一编译器是 GNU CC,以前甚至,以前甚至出现过编译出现过编译 Linux 内核要使用特殊的内核要使用特殊的 GNU CC 版本的版本的情况。情况。GCC编译器的使用硅谷嵌入式教育 真实项目为依托 GCC(GNU Compiler Collection)GNU CC(简称为(简称为 Gcc)是)是 GNU 项目中符合项目中符合 ANSI C 标准的编译系统,能够编译用标准的编译系统,能够编译用 C
16、、C+和和 Object C 等等语言编写的程序。语言编写的程序。Gcc 又是一个交叉平台编译器,在当前又是一个交叉平台编译器,在当前CPU平台上为平台上为多种不同体系结构的硬件平台开发软件。适合在嵌入式多种不同体系结构的硬件平台开发软件。适合在嵌入式领域的开发编译。领域的开发编译。GCC编译器的使用硅谷嵌入式教育 真实项目为依托 gcc则通过后缀来区别输入文件的类别。则通过后缀来区别输入文件的类别。gcc所遵循所遵循的部分后缀约定规则:的部分后缀约定规则:.c :C语言源代码文件;语言源代码文件;.a :是由目标文件构成的档案库文件;是由目标文件构成的档案库文件;.C,或,或.cxx:是是C
17、+源代码文件;源代码文件;.h :是程序所包含的头文件;是程序所包含的头文件;.i :是已经预处理过的是已经预处理过的C源代码文件;源代码文件;.ii :是已经预处理过的是已经预处理过的C+源代码文件;源代码文件;.o :是编译后的目标文件;是编译后的目标文件;.s :是汇编语言源代码文件;是汇编语言源代码文件;.S :是经过预编译的汇编语言源代码文件。是经过预编译的汇编语言源代码文件。GCC编译器的使用硅谷嵌入式教育 真实项目为依托 GCC通常通常gcc后跟一些选项和文件名来使用后跟一些选项和文件名来使用 GCC 编译器编译器 gcc options filenames 其中其中option
18、s就是编译器所需要的参数,就是编译器所需要的参数,filenames给给出相关的文件名称出相关的文件名称例如:例如:gcc o hello hello.cGCC编译器的使用硅谷嵌入式教育 真实项目为依托 Gcc的编译流程的编译流程预处理阶段:预处理阶段:gcc E hello.c o hello.i gcc E hello.c o hello.i编译阶段:编译阶段:gcc S hello.i o hello.sgcc S hello.i o hello.s汇编阶段:汇编阶段:gcc c hello.s o hello.ogcc c hello.s o hello.o链接阶段:链接阶段:gcc
19、hello.o o hellogcc hello.o o hello执行:执行:./hello./helloGCC编译器的使用硅谷嵌入式教育 真实项目为依托 GCCGCC的选项的选项 GCC GCC 有超过有超过100100个的编译选项可用个的编译选项可用.主要包括编译处理主要包括编译处理选项、警告选项、出错选项、优化选项、体系结构选选项、警告选项、出错选项、优化选项、体系结构选项。项。-c-c,只编译,不连接成为可执行文件,编译器只是由,只编译,不连接成为可执行文件,编译器只是由输入的输入的.c.c等源代码文件生成等源代码文件生成.o.o为后缀的目标文件,通为后缀的目标文件,通常用于编译不包
20、含主程序的子程序文件。常用于编译不包含主程序的子程序文件。-o-o output_filename output_filename,确定输出文件的名称为,确定输出文件的名称为output_filenameoutput_filename,同时这个名称不能和源文件同名。,同时这个名称不能和源文件同名。如果不给出这个选项,如果不给出这个选项,gccgcc就给出预设的可执行文件就给出预设的可执行文件a.outa.out。-S-S 编译选项告诉编译选项告诉 GCC GCC 在为在为 C C 代码产生了汇编语言文代码产生了汇编语言文件后停止编译件后停止编译.GCC.GCC 产生的汇编语言文件的缺省扩展产生
21、的汇编语言文件的缺省扩展名是名是.s.s.GCC编译器的使用硅谷嵌入式教育 真实项目为依托 GCC GCC 选项选项-g,产生符号调试工具,产生符号调试工具(GNU的的gdb)所必要的符号信所必要的符号信息,要想对源代码进行调试,我们就必须加入这个选息,要想对源代码进行调试,我们就必须加入这个选项。项。-O,对程序进行优化编译、连接,产生的可执行文件,对程序进行优化编译、连接,产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。应地要慢一些。-O2,比,比-O更好的优化编译、连接,当然整个编译、更好的优化编译、连接,当然整个
22、编译、连接过程会更慢。连接过程会更慢。GCC编译器的使用硅谷嵌入式教育 真实项目为依托 GCC GCC 选项选项-Idirname-Idirname,在头文件的搜索路径列表中添加,在头文件的搜索路径列表中添加dirnamedirname目目录。这个选项的作用是:到指定的录。这个选项的作用是:到指定的dirnamedirname目录中去寻目录中去寻找需要的头文件。找需要的头文件。-Ldirname-Ldirname,在库文件的搜索路径列表中添加,在库文件的搜索路径列表中添加dirnamedirname目目录。在预设状态下,连接程序录。在预设状态下,连接程序ldld在系统的预设路径中在系统的预设路
23、径中(如如/usr/lib)/usr/lib)寻找所需要的档案库文件,这个选项寻找所需要的档案库文件,这个选项 告告诉连接程序,诉连接程序,首先到首先到-L-L指定的目录中去寻找,然后到系指定的目录中去寻找,然后到系统预设路径中寻找。统预设路径中寻找。-lname-lname,在连接时,装载名字为,在连接时,装载名字为“libname.a”“libname.a”的函数的函数库,该函数库位于系统预设的目录或者由库,该函数库位于系统预设的目录或者由-L-L选项确定的选项确定的目录下。例如,目录下。例如,-lm-lm表示连接名为表示连接名为“libm.a”“libm.a”的数学函的数学函数库。数库。
24、GCC编译器的使用硅谷嵌入式教育 真实项目为依托 GCC GCC 选项选项更为详尽的资料可以参看更为详尽的资料可以参看Linux系统的联机帮助。系统的联机帮助。(man)很多的很多的 GCC GCC 选项包括一个以上的字符选项包括一个以上的字符.因此你必须为因此你必须为每个选项指定各自的连字符每个选项指定各自的连字符,并且就象大多数并且就象大多数 Linux Linux 命令一样你不能在一个单独的连字符后跟一组选项命令一样你不能在一个单独的连字符后跟一组选项.gcc g O2 o hello hello.c gcc包含的包含的c/c+编译器编译器 一般一般c程序就用程序就用gcc编译,编译,c
25、+程序就用程序就用g+编译编译 GCC编译器的使用硅谷嵌入式教育 真实项目为依托练习使用练习使用gcc编译编译C源文件源文件通过通过Hello worldHello world程序,熟悉程序,熟悉gccgcc及其选项的使及其选项的使用。用。Hello Worldhello.cint main(void)printf(“hello world!n”);return 0;编译$gcc-o hello hello.c$gcc-o hello hello.c GCC编译器的使用硅谷嵌入式教育 真实项目为依托多个c文件两个源文件 main.c 和 factorial.c 两个源文件,现在要编译生成一个计
26、算阶乘的程序。factorial.cint factorial(int n)if(n=1)return 1;else return factorial(n-1)*n;GCC编译器的使用硅谷嵌入式教育 真实项目为依托多个c文件 factorial.c main.c#include#include int factorial(int n);int main(int argc,char*argv)int n;if(argc 2)printf(Usage:%s nn,argv 0);return-1;else n=atoi(argv1);printf(Factorial of%d is%d.n,n,f
27、actorial(n);return 0;GCC编译器的使用硅谷嵌入式教育 真实项目为依托多个c文件编译:$gcc-o factorial main.c factorial.c 练习编译多个c文件GCC编译器的使用硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb 使用流程使用流程Gdb 调试器是一款调试器是一款GNU 开发组织并发布的开发组织并发布的 UNIX/Linux 下的程序调试工具。下的程序调试工具。Gdb让您能够看到一个程序的内部结构,指出变量的值,让您能够看到一个程序的内部结构,指出变量的值,设置断点并在源码中进行单步执行。设置断点并在源码中进行单步执行。硅谷嵌入式教育 真实项
28、目为依托Gdb 调试器 Gdb 使用流程使用流程要使用要使用gdb进行调试,一定要在编译时加上调试选项进行调试,一定要在编译时加上调试选项“-g”。gcc-g test.c-o testgdb test使用使用“help”命令查看帮助信息。命令查看帮助信息。硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb的简单使用的简单使用查看文件查看文件 l设置断点设置断点 b 行号行号查看断点情况查看断点情况 info b运行代码运行代码 r run查看变量值查看变量值“p”变量值变量值单步运行单步运行“n”(next)或)或“s”step)若有函数调用的时候,“s”会进入该函数而“n”不会进入该函数
29、。恢复程序运行恢复程序运行“c”(continue)硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb 基本命令基本命令通过查看通过查看 help 查找命令。查找命令。Gdb 的 help 将其分成了很多种类(class)。help Help“种类”查看该种类中的命令列表 Help 命令已知命令名:已知命令名:Help 命令命令硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb 基本命令基本命令工作环境相关命令工作环境相关命令对程序相关的工作环境进行相应的设定使用shell中的命令进行相关的操作硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb 基本命令基本命令设置断点与恢复命令设置断点
30、与恢复命令硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb 基本命令基本命令设置断点有多种方式:设置断点有多种方式:函数断点:“b 函数”此时的断点实际是在函数的定义处条件断点:b 行数或函数名 if 表达式b 8 if i=10硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb 基本命令基本命令Gdb 中源码查看相关命令中源码查看相关命令硅谷嵌入式教育 真实项目为依托Gdb 调试器 Gdb 基本命令基本命令Gdb 中查看运行数据相关命令中查看运行数据相关命令硅谷嵌入式教育 真实项目为依托 MakeMake介绍介绍MakeMake是一种控制编译或者重复编译软件的非常重要是一种控制编译或者
31、重复编译软件的非常重要的工具。的工具。Make 可自动决定一个大程序中哪些文件需可自动决定一个大程序中哪些文件需要重新编译,并执行重新编译它们的命令。要重新编译,并执行重新编译它们的命令。要使用要使用makemake,必须编写一个叫做,必须编写一个叫做MakefileMakefile的文件。的文件。MakefileMakefile文件是定义文件是定义makemake如何执行的规则文件,它如何执行的规则文件,它包含一些规则告诉包含一些规则告诉makemake工具编译哪些文件、怎么编工具编译哪些文件、怎么编译以及在什么条件下去编译。译以及在什么条件下去编译。MakefileMakefile写好之后
32、,每次改变了某些源文件,只要写好之后,每次改变了某些源文件,只要执行执行makemake命令,所有必要的重新编译将执行。命令,所有必要的重新编译将执行。MakeMake程序通过比较目标文件的生成时间和其所依赖程序通过比较目标文件的生成时间和其所依赖的源文件的最后修改时间和来决定是否执行的源文件的最后修改时间和来决定是否执行makefilemakefile中定义的命令来更新该目标文件。中定义的命令来更新该目标文件。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 MakefileMakefile文件的基本结构文件的基本结构MakefileMakefile包含一些规则来告诉包含一些规则来告
33、诉makemake处理哪些文件以及处理哪些文件以及如何处理这些文件。如何处理这些文件。这些规则主要是描述哪些文件(称为这些规则主要是描述哪些文件(称为targettarget目标文件,目标文件,不要和编译时产生的目标文件相混淆)是从哪些别的不要和编译时产生的目标文件相混淆)是从哪些别的文件(称为文件(称为dependencydependency依赖文件)中产生的,以及用依赖文件)中产生的,以及用什么命令(什么命令(commandcommand)来执行这个过程。)来执行这个过程。每条规则包含每条规则包含以下内容:以下内容:一个“目标体”。即可是可执行文件和目标文件,目标也可以是要执行的动作。一个
34、或多个依赖文件(dependency)列表。一系列命今(command),是make执行的动作,通常是把指定的相关文件编译成目标文件的编译命令,每个命令占一行,且每个命令行的起始字符必须为TAB字符。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 MakefileMakefile文件的基本结构文件的基本结构Makefile规则的一般形式如下:规则的一般形式如下:target:dependency dependency(tab)例子:例子:hello.o:hello.c hello.hgcc c hello.c o hello.o项目管理工具make的使用硅谷嵌入式教育 真实项目为依托
35、 MakefileMakefile文件的基本结构文件的基本结构Makefile规则的一般形式如下:规则的一般形式如下:target:dependency dependency(tab)target也就是一个目标文件,可以是也就是一个目标文件,可以是Object File,也,也可以是执行文件。还可以是一个标签(可以是执行文件。还可以是一个标签(Label)。)。dependency要生成要生成target所需要的文件或是目标。所需要的文件或是目标。command也就是也就是make需要执行的命令。可以是任需要执行的命令。可以是任意的意的Shell命令。命令。项目管理工具make的使用硅谷嵌入式
36、教育 真实项目为依托调用调用makemake命令可输入:命令可输入:#make target make targettargettarget是是MakefileMakefile文件中定义的目标之一,如文件中定义的目标之一,如果省略果省略targettarget,makemake就将生成就将生成MakefileMakefile文件中定义文件中定义的第一个目标。的第一个目标。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 make处理处理makefile文件的过程文件的过程首先首先make按顺序读取按顺序读取makefile中的规则,然后检查该规中的规则,然后检查该规则中的依赖文件与目标
37、文件的时间戳哪个比较新。则中的依赖文件与目标文件的时间戳哪个比较新。如果目标文件的时问戳比依赖文件还早,就按规则中定义的命令更新目标文件。如果该规则中的依赖文件又是其他规则中的目标文件,那么依照规则链不断执行这个过程,直到Makefile文件的结束,至少可以找到一个不是规则生成的最终依赖文件,获得此文件的时间戳,然后从下到上依照规则链执行目标文件的时间戳比此文件时间戳旧的规则,直到最顶层的规则。通过以上的分析过程,可以看到通过以上的分析过程,可以看到make的优点,因为的优点,因为.o目目标文件依赖标文件依赖.c源文件,源码文件里一个简单改变都会造源文件,源码文件里一个简单改变都会造成那个文件
38、被重新编译,并根据规则链依次由下到上执成那个文件被重新编译,并根据规则链依次由下到上执行编译过程,直到最终的可执行文件被重新连接。行编译过程,直到最终的可执行文件被重新连接。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 Makefile中的变量Makefile里的变量对大小写敏感,一般使用大写宇母。变里的变量对大小写敏感,一般使用大写宇母。变量的主要作用如下:量的主要作用如下:保存文件名列表。保存可执行命令名,如编译器。保存编译器的参数。在很多源代码编译时,gcc需要很长的参数选项,在很多情况下,所有的编译命令使用一组相同的选项,如果把这组选项使用一个变量代表,那么可以把这个变量放
39、在所有引用编译器的地方。当要改变选项的时候,只需改变一次这个变量的内容即可。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 Makefile中的变量Makefile中的变量是用一个文本串在中的变量是用一个文本串在Makefile中定义的,中定义的,这个文本串就是变量的值。只要在一行的开始写下这个这个文本串就是变量的值。只要在一行的开始写下这个变量的名字,后面跟一个变量的名字,后面跟一个“”号,以及要设定这个变量号,以及要设定这个变量的值即可定义变量,定义变量的语法:的值即可定义变量,定义变量的语法:VARNAME=string使用时,把变量用括号括起来,并在前面加上使用时,把变量用括
40、号括起来,并在前面加上$符号,就符号,就可以引用变量的值:可以引用变量的值:$VARNAME、$(VARNAME)make解释规则时,解释规则时,VARNAME在等式右端展开为定义它在等式右端展开为定义它的字符串。变量一般都在的字符串。变量一般都在Makefile的头部定义。的头部定义。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 利用变量把前面的利用变量把前面的Makefile重写一遍:重写一遍:OBJS=prog.o code.oCC=gcc test:$OBJS$CC o test$OBJS prog.o:prog.c prog.h code.h$CC c prog.c o
41、prog.o code.o:code.c code.h$CC c code.c o code.o clean:rm f*.o 项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 GNU make 的主要预定义变量 预定义变量含义预定义变量含义$*不包含扩展名的目标文件名称。不包含扩展名的目标文件名称。$+所有的依赖文件,以空格分开,并以出现的先后所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。为序,可能包含重复的依赖文件。$第一个依赖文件的名称。第一个依赖文件的名称。$?所有的依赖文件,以空格分开,这些依赖文件的所有的依赖文件,以空格分开,这些依赖文件的修改日期比
42、目标的创建日期晚。修改日期比目标的创建日期晚。$目标的完整名称。目标的完整名称。$所有的依赖文件,以空格分开,不包含重复的依所有的依赖文件,以空格分开,不包含重复的依赖文件。赖文件。$%如果目标是归档成员,则该变量表示目标的归档如果目标是归档成员,则该变量表示目标的归档成员名称。成员名称。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 GNU make 的主要预定义变量AR 归档维护程序的名称,默认值为归档维护程序的名称,默认值为 ar。ARFLAGS 归档维护程序的选项。归档维护程序的选项。AS 汇编程序的名称,默认值为汇编程序的名称,默认值为 as。ASFLAGS 汇编程序的选项
43、。汇编程序的选项。CC C 编译器的名称,默认值为编译器的名称,默认值为 cc。CCFLAGS C 编译器的选项。编译器的选项。CPP C 预编译器的名称,默认值为预编译器的名称,默认值为$(CC)-E。CPPFLAGS C 预编译的选项。预编译的选项。CXX C+编译器的名称,默认值为编译器的名称,默认值为 g+。CXXFLAGS C+编译器的选项。编译器的选项。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 Makefile的隐含规则make知道一些默认的动作,它有一些称作隐含规知道一些默认的动作,它有一些称作隐含规则的内置的规则,这些规则告诉则的内置的规则,这些规则告诉make
44、当用户没有当用户没有完整地给出某些命令的时候,应该怎样执行。完整地给出某些命令的时候,应该怎样执行。把生成把生成prog.o和和code.o的命令从规则中删除,的命令从规则中删除,make将会查找隐含规则,然后会找到并执行一个适当的将会查找隐含规则,然后会找到并执行一个适当的命令。命令。项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 在上面的例子中,利用隐含规则,可以简化为:在上面的例子中,利用隐含规则,可以简化为:OBJS=prog.o code.oCC=gcctest:$OBJS$CC o$prog.o:prog.c prog.h code.hcode.o:code.c code
45、.h clean:rm f*.o项目管理工具make的使用硅谷嵌入式教育 真实项目为依托 运行 make make makefile 命令行选项命令行选项 含义含义-C DIR -C DIR 在读取在读取 makefile makefile 之前改变到指定的目录之前改变到指定的目录 DIR DIR。-f FILE -f FILE 以指定的以指定的 FILE FILE 文件作为文件作为 makefile makefile-h -h 显示所有的显示所有的 make make 选项。选项。-i -i 忽略所有的命令执行错误。忽略所有的命令执行错误。-s -s 在执行命令时不显示命令。在执行命令时不显示命令。项目管理工具make的使用