linux 常用开发工具

37
Linux Linux 常常常常常常 常常常常常常

Upload: landis

Post on 19-Mar-2016

71 views

Category:

Documents


1 download

DESCRIPTION

Linux 常用开发工具. 主要内容 gcc 编译系统的概念和使用 gdb 程序调试工具的概念和使用 程序维护工具 make 的概念和使用. 6.1 gcc 编译系统 6.1.1 文件名后缀. 6.1.2 C 语言编译过程. 1 .预处理阶段 预处理是常规编译 之前预先进行的工作, 故此得名。它读取 C 语言 源文件,对其中以 “ # ” 开头的指令(伪指令) 和特殊符号进行处理。 主要包括文件包含、宏 定义和条件编译指令。. 2 .编译阶段 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Linux 常用开发工具

LinuxLinux 常用开发工具常用开发工具

Page 2: Linux 常用开发工具

主要内容主要内容• gccgcc 编译系统的概念和使用编译系统的概念和使用• gdbgdb 程序调试工具的概念和使用程序调试工具的概念和使用• 程序维护工具程序维护工具 make make 的概念和使用 的概念和使用

Page 3: Linux 常用开发工具

6.1 gcc6.1 gcc 编译系统编译系统6.1.1 6.1.1 文件名后缀文件名后缀文件名后缀 文件名后缀 文 件 类 型 文 件 类 型 文件名后缀 文件名后缀 文 件 类 型 文 件 类 型 .c.c CC 源文件源文件 .F .fpp .FPP.F .fpp .FPP FORTRANFORTRAN 源文源文件件 .i.i 预处理后的预处理后的 CC 源文件源文件 .s.s 汇编程序文件汇编程序文件 .ii.ii 预处理后的预处理后的 C++C++ 源文件源文件 .S.S 必须预处理的汇编程序文件必须预处理的汇编程序文件 .m.m Objective-CObjective-C 源文件源文件 .o.o 目标文件目标文件 .mi.mi 预处理后的预处理后的 Objective-CObjective-C 源文源文

件件 .a.a 静态链接库静态链接库 .h.h 头文件 头文件 .so.so 动态链接库动态链接库 .C .cc .cp ..C .cc .cp .cpp .c++ .ccpp .c++ .cxxxx

C++C++ 源文件 源文件

Page 4: Linux 常用开发工具

6.1.2 C6.1.2 C 语言编译过程语言编译过程 11 .预处理阶段.预处理阶段 预处理是常规编译预处理是常规编译之前预先进行的工作,之前预先进行的工作,故此得名。它读取故此得名。它读取 CC 语言语言源文件,对其中以“源文件,对其中以“ #”#”开头的指令(伪指令)开头的指令(伪指令)和特殊符号进行处理。和特殊符号进行处理。主要包括文件包含、宏主要包括文件包含、宏定义和条件编译指令。定义和条件编译指令。

Page 5: Linux 常用开发工具

22 .编译阶段.编译阶段• 编译程序(编译程序( CompilerCompiler )对预处理之后的输出文件进行词法分析和语)对预处理之后的输出文件进行词法分析和语

法分析,试图找出所有不符合语法规则的部分法分析,试图找出所有不符合语法规则的部分 33 .汇编过程.汇编过程• 汇编过程是汇编程序(汇编过程是汇编程序( AssemblerAssembler )把汇编语言代码翻译成目标机)把汇编语言代码翻译成目标机

器代码的过程器代码的过程 44 .连接阶段.连接阶段• 连接程序(连接程序( LinkerLinker )要解决外部符号访问地址问题)要解决外部符号访问地址问题• 连接模式分为静态连接和动态连接连接模式分为静态连接和动态连接

Page 6: Linux 常用开发工具

6.1.3 gcc6.1.3 gcc 命令行选项命令行选项• 在在 LinuxLinux 系统中,系统中, C/C++C/C++ 程序编译命令是程序编译命令是 gccgcc ,例如: ,例如: $ gcc f1.c f2.c $ gcc f1.c f2.c (针对(针对 CC 语言源程序)语言源程序) 执行完成后,生成默认的可执行文件执行完成后,生成默认的可执行文件 a.outa.out 。。11 .预处理选项.预处理选项 CC 语言预处理程序通常称为语言预处理程序通常称为 cppcpp ,它是宏处理程序,由,它是宏处理程序,由 CC 编译程序自编译程序自动调用,在真正的编译过程之前对程序进行转换。动调用,在真正的编译过程之前对程序进行转换。●● 几个预处理常用选项几个预处理常用选项:: -C -D name -D -C -D name -D namename==definitiondefinition -U -U namename -I -I dirdir -o -o filefile -E-E

Page 7: Linux 常用开发工具

22 .编译程序选项.编译程序选项• gccgcc 编译程序常用选项及其作用编译程序常用选项及其作用

选 项 选 项 格 式 格 式 功 能 功 能 -c -c 只生成目标文件,不进行连接。用于对源文件的分别编译 只生成目标文件,不进行连接。用于对源文件的分别编译 -S -S 只进行编译,不做汇编,生成汇编代码文件格式,其名与源只进行编译,不做汇编,生成汇编代码文件格式,其名与源文件相同,但扩展名为文件相同,但扩展名为 .s .s -o -o filefile 将输出放在文件将输出放在文件 filefile 中。如果未使用该选项,则可执行文件中。如果未使用该选项,则可执行文件放在放在 a.outa.out 中中-g -g 指示编译程序在目标代码中加入供调试程序指示编译程序在目标代码中加入供调试程序 gdbgdb 使用的附加使用的附加信息信息-v -v 在标准出错输出上显示编译阶段所执行的命令,即编译驱动在标准出错输出上显示编译阶段所执行的命令,即编译驱动程序及预处理程序的版本号 程序及预处理程序的版本号

Page 8: Linux 常用开发工具

33 .优化程序选项.优化程序选项• 优化程序常用的选项及其作用 优化程序常用的选项及其作用

选 项 格 式 选 项 格 式 功 能 功 能 -O-O-O1 -O1

试图减少代码大小和执行时间,但并不执行需要花费大量试图减少代码大小和执行时间,但并不执行需要花费大量编译时间的任何优化 编译时间的任何优化 -O2 -O2 在在 -O1-O1 级别的优化之上,还进行一些额外调整工作——除级别的优化之上,还进行一些额外调整工作——除不做循环展开、函数内联和寄存器重新命名外,几乎进行不做循环展开、函数内联和寄存器重新命名外,几乎进行所有可选优化 所有可选优化 -O3 -O3 除了完成所有除了完成所有 -O2-O2 级别的优化之外,还进行包括循环展开级别的优化之外,还进行包括循环展开和其他一些与处理器特性相关的优化工作 和其他一些与处理器特性相关的优化工作 -O0 -O0 不执行优化 不执行优化 -Os -Os 具有具有 -O2-O2 级别的优化,同时并不特别增加代码大小 级别的优化,同时并不特别增加代码大小

Page 9: Linux 常用开发工具

44 .连接程序选项.连接程序选项• 连接程序常用的选项及其功能连接程序常用的选项及其功能

选 项 格 式 选 项 格 式 功 能 功 能 object-object-file-namefile-name

不以专用后缀结尾的文件名就认为是目标文件名或库名。连接程序可不以专用后缀结尾的文件名就认为是目标文件名或库名。连接程序可以根据文件内容来区分目标文件和库 以根据文件内容来区分目标文件和库 -c -S --c -S -E E

如果使用其中任何一个选项,那么都不运行连接程序,而且目标文件如果使用其中任何一个选项,那么都不运行连接程序,而且目标文件名不应该用做参数 名不应该用做参数 -l-llibrarylibrary 连接时搜索由连接时搜索由 librarylibrary命名的库。连接程序按照在命令行上给定的顺序命名的库。连接程序按照在命令行上给定的顺序搜索和处理库及目标文件。实际的库名是搜索和处理库及目标文件。实际的库名是 liblibraryliblibrary,但按默认规则,,但按默认规则,开头的开头的 liblib 和后缀(和后缀( .a.a 或或 .so.so )可以被省略 )可以被省略 -static -static 在支持动态连接的系统中,它强制使用静态链接库,而阻止连接动态在支持动态连接的系统中,它强制使用静态链接库,而阻止连接动态库;而在其他系统中不起作用 库;而在其他系统中不起作用 -L-Ldirdir 把指定的目录把指定的目录 dirdir 加到连接程序搜索库文件的路径表中,即在搜索加到连接程序搜索库文件的路径表中,即在搜索 -l-l 后后面列举的库文件时,首先到面列举的库文件时,首先到 dirdir下搜索,找不到再到标准位置下搜索 下搜索,找不到再到标准位置下搜索 -B-Bprefixprefix 该选项规定在什么地方查找可执行文件、库文件、包含文件和编译程该选项规定在什么地方查找可执行文件、库文件、包含文件和编译程序本身数据文件 序本身数据文件 -o -o filefile 指定连接程序最后生成的可执行文件名称为指定连接程序最后生成的可执行文件名称为 filefile ,不是默认的,不是默认的 a.out a.out

Page 10: Linux 常用开发工具

• LinuxLinux 下库文件的命名有一个约定,所有的库名都以下库文件的命名有一个约定,所有的库名都以 liblib 开头。形如:开头。形如: libx.a libx.a 其中,其中, xx 是指定的库名是指定的库名 • 以以 .a.a (归档,(归档, archivearchive )结尾的库是静态库,以)结尾的库是静态库,以 .so.so (共享目标,(共享目标, sshared objecthared object )结尾的库是动态库)结尾的库是动态库

• 生成静态库的方法实际上可分为两步:生成静态库的方法实际上可分为两步:① ① 将各函数的源文件编译成目标文件 将各函数的源文件编译成目标文件 ② ② 使用使用 arar 工具将目标文件收集起来,放到一个归档文件中工具将目标文件收集起来,放到一个归档文件中

Page 11: Linux 常用开发工具

6.2 gdb6.2 gdb 程序调试工具程序调试工具• 程序中的错误可按性质分为三种:程序中的错误可按性质分为三种:(( 11 )编译错误,即语法错误。 )编译错误,即语法错误。 (( 22 )运行错误。 )运行错误。 (( 33 )逻辑错误。)逻辑错误。 查找程序中的错误,诊断其准确位置,并予以改正,这就查找程序中的错误,诊断其准确位置,并予以改正,这就是程序调试。是程序调试。 程序调试分为人工查错与机器调试。程序调试分为人工查错与机器调试。

Page 12: Linux 常用开发工具

6.2.1 6.2.1 启动启动 gdbgdb 和查看内部命令和查看内部命令• 当程序执行过程中忽然中止,屏幕上显示当程序执行过程中忽然中止,屏幕上显示 ××××-core dumped××××-core dumped 消息,消息,然后显示提示符,其中,然后显示提示符,其中,×××××××× 表示出错原因 表示出错原因 • 为了发挥为了发挥 gdbgdb 的全部功能,需要在编译源程序时使用的全部功能,需要在编译源程序时使用 -g-g 选项 。如:选项 。如: $ gcc -g prog.c -o prog $ gcc -g prog.c -o prog (针对(针对 CC 语言源程序语言源程序 prog.cprog.c )) $ gcc -g program.cpp -o program $ gcc -g program.cpp -o program (针对(针对 C++C++ 源程序源程序 program.cppprogram.cpp ))• 启动启动 gdbgdb 的方法有以下几种:的方法有以下几种: (( 11 )直接使用)直接使用 shellshell 命令命令 gdb gdb (( 22 )以一个可执行程序作为)以一个可执行程序作为 gdbgdb 的参数 的参数 (( 33 )同时以可执行程序和)同时以可执行程序和 corecore 文件作为文件作为 gdbgdb 的参数 的参数 (( 44 )指定一个进程号)指定一个进程号 PIDPID 作为作为 gdbgdb 的第二个参数的第二个参数一旦启动一旦启动 gdbgdb ,就显示,就显示 gdbgdb 提示符:提示符:(( gdbgdb ))并等待用户输入相应的内部命令 并等待用户输入相应的内部命令

Page 13: Linux 常用开发工具
Page 14: Linux 常用开发工具

6.2.2 6.2.2 显示源程序和数据显示源程序和数据11 .显示和搜索源程序.显示和搜索源程序(( 11 )显示源文件)显示源文件• 利用利用 listlist 命令可以显示源文件中指定的函数或代码行命令可以显示源文件中指定的函数或代码行 list list - list [list list - list [filefile:] :] numnum list list startstart , , endend list [list [filefile:]:]functionfunction (( 22 )模式搜索)模式搜索 forward-search forward-search regexpregexp search search regexpregexp reverse-search reverse-search regexpregexp

Page 15: Linux 常用开发工具

22 .查看运行时数据.查看运行时数据 (( 11 )) printprint 命令 一般使用格式是命令 一般使用格式是 :: print [/print [/fmt]fmt] expexp• 当被调试的程序停止时,可以用当被调试的程序停止时,可以用 printprint 命令(简写为命令(简写为 pp )或同义命令)或同义命令 inspinsp

ectect 来查看当前程序中运行的数据。来查看当前程序中运行的数据。 (( 22 )) gdbgdb 所支持的运算符所支持的运算符① ① { { typetype } }adrexpadrexp 表示一个数据类型为表示一个数据类型为 typetype 、存放地址为、存放地址为 adrexpadrexp 的数据。的数据。② ② @ @ 是一个与数组有关的双目运算符,使用形式如:是一个与数组有关的双目运算符,使用形式如:• print array@10print array@10 print array[3]@5print array[3]@5 ③ ③ filefile :: :: varvar (或者 (或者 functionfunction :: :: varvar ) 表示文件) 表示文件 filefile (或者函数(或者函数 functiofunctio

nn )中变量)中变量 varvar 的值的值

Page 16: Linux 常用开发工具

(( 33 )输出格式)输出格式• 在在 print /print /fmtfmt expexp 命令中,“命令中,“ /”/” 之后的之后的 fmtfmt 是表示输出格式的字母,是表示输出格式的字母,它由表示格式的字母和表示数据长度的字母组成 。如:它由表示格式的字母和表示数据长度的字母组成 。如:• 表示格式 的字母:表示格式 的字母: o x d u t f a i c so x d u t f a i c s• 表示长度的字母表示长度的字母 : : b w h gb w h g (( 44 )) whatiswhatis 命令显示出变量的数据类型 命令显示出变量的数据类型 (( 55 )) xx 命令可以查看内存地址中数据的值命令可以查看内存地址中数据的值 。其使用格式是:。其使用格式是: x [/x [/fmt]fmt] addressaddress(( 66 )) displaydisplay命令可以预先设置一些要显示的表达式。其一般格式是:命令可以预先设置一些要显示的表达式。其一般格式是: display [/display [/fmt]fmt] expexp • 要取消对先前设置的某些表达式的自动显示功能,可以使用以下命令:要取消对先前设置的某些表达式的自动显示功能,可以使用以下命令: undisplay [undisplay [disnum]disnum] delete display [delete display [disnum]disnum]

Page 17: Linux 常用开发工具

• (( 77)显示函数调用栈信息)显示函数调用栈信息• 显示函数调用栈信息的命令显示函数调用栈信息的命令• 格 式 格 式 功 能 功 能

backtrace [backtrace [nn | - | -nn]]bt [bt [nn | - | -nn]]where [where [nn | - | -nn] ]

打印当前的函数调用栈的所有信息。如果有参数打印当前的函数调用栈的所有信息。如果有参数 nn (正整(正整数),则只打印栈顶上数),则只打印栈顶上 nn层帧的信息;如果是层帧的信息;如果是 - n- n 的形式,的形式,则只打印栈底则只打印栈底 nn层帧的信息 层帧的信息 frame [frame [nn]]f [f [nn]]

其中,其中, nn 是栈中帧的编号,从是栈中帧的编号,从 00(表示栈顶)开始递增。(表示栈顶)开始递增。如果不带参数,则显示出当前栈帧的信息;如果给出参数如果不带参数,则显示出当前栈帧的信息;如果给出参数nn ,则选定帧号为,则选定帧号为 nn 的帧作为当前帧 的帧作为当前帧 up [up [nn] ] 表示向上移动表示向上移动 nn层栈帧。如果没有参数,则表示向上移动层栈帧。如果没有参数,则表示向上移动一层 一层 down [down [nn] ] 表示向下移动表示向下移动 nn层栈帧。如果没有参数,则表示向下移动层栈帧。如果没有参数,则表示向下移动一层 一层 info frameinfo frameinfo f info f

显示出当前栈帧的所有信息,如函数地址,调用函数的地显示出当前栈帧的所有信息,如函数地址,调用函数的地址,被调用函数的地址,目前函数的程序语言、函数参数址,被调用函数的地址,目前函数的程序语言、函数参数地址及值、局部变量的地址等。 地址及值、局部变量的地址等。

Page 18: Linux 常用开发工具

6.2.3 6.2.3 改变和显示目录或路径改变和显示目录或路径 • (( 11 )) directorydirectory命令一般格式是:命令一般格式是: directory [directory [ddir]ir] 或者 或者 dir [dir [dir]dir]• (( 22 )) cdcd 命令使用格式为: 命令使用格式为: cd cd dirdir• (( 33 )) pathpath命令使用格式是: 命令使用格式是: path path dirsdirs• (( 44 )) pwdpwd 命令命令• (( 55)) show directoriesshow directories• (( 66 )) show pathsshow paths

Page 19: Linux 常用开发工具

6.2.4 6.2.4 控制程序的执行控制程序的执行• 断点(断点( breakpointbreakpoint ),观察点(),观察点( watchpointwatchpoint ),捕捉点(),捕捉点( catchpcatchpointoint ) ) 它们统称为停止点它们统称为停止点 11 .设置和显示断点 .设置和显示断点 (( 11 )设置断点:用)设置断点:用 breakbreak 命令(其缩写形式为命令(其缩写形式为 bb )设置断点:)设置断点:• break break linenumlinenum break break linenumlinenum if if conditioncondition • break break functionfunction break break filefile::linenumlinenum• break break filefile::functionfunction break * break *addressaddress break break (( 22 )显示断点)显示断点• info breakpoints [info breakpoints [numnum]]• info break [info break [numnum]]

Page 20: Linux 常用开发工具

22 .设置和显示观察点.设置和显示观察点(( 11 )设置观察点)设置观察点watch watch exprexpr rwatch rwatch exprexpr awatch awatch exprexpr (( 22 )显示观察点)显示观察点

• info breakpoints info watchpointsinfo breakpoints info watchpoints 33 .设置捕捉点.设置捕捉点• 命令命令 catchcatch的格式是: 的格式是: catch catch eventevent• 另一个命令是另一个命令是 tcatch tcatch eventevent 44 .维护停止点.维护停止点• delete clear disable enable delete clear disable enable 55.运行程序.运行程序• runrun 命令的格式:命令的格式: run [run [argsargs]]

Page 21: Linux 常用开发工具

66 .程序的单步跟踪和连续执行.程序的单步跟踪和连续执行(( 11 )单步跟踪)单步跟踪• 实行单步跟踪的命令是实行单步跟踪的命令是 stepstep 和和 nextnext ,其格式是:,其格式是: step [step [N]N] next next [N][N] (( 22 )连续执行)连续执行 continuecontinue ,, cc 或或 fgfg 命令命令 77.函数调用.函数调用 call call exprexpr return [expr]return [expr]

Page 22: Linux 常用开发工具

6.2.5 6.2.5 其他常用命令其他常用命令11 .执行.执行 shellshell 命令命令• 其格式是: 其格式是: shell shell command-stringcommand-string22 .修改变量值.修改变量值• (gdb) print x=10(gdb) print x=10• (gdb) set variable x=10(gdb) set variable x=1033 .跳转执行.跳转执行• jump jump linenumlinenum• jump *jump *addraddr

Page 23: Linux 常用开发工具

6.2.6 6.2.6 应用示例应用示例 示例程序源代码

Page 24: Linux 常用开发工具

(( 11 )使用带)使用带 -g-g 选项的选项的 gccgcc 命令对该程序进行编译:命令对该程序进行编译:• $ gcc -g dbme.c -o dbme$ gcc -g dbme.c -o dbme• 程序运行时出现错误——段错误程序运行时出现错误——段错误 (( 22 )用程序名)用程序名 dbmedbme 作为参数启动作为参数启动 gdbgdb 。。

(( 33 )在)在 gdbgdb 环境下运行该程序。环境下运行该程序。

Page 25: Linux 常用开发工具

• 使用使用 backtracebacktrace 命令命令

• 使用使用 listlist 命令显示相关行的内容命令显示相关行的内容

Page 26: Linux 常用开发工具

• 利用利用 printprint 命令可以打印出任何合法表达式的值命令可以打印出任何合法表达式的值

Page 27: Linux 常用开发工具

• (( 44 )设置断点)设置断点

Page 28: Linux 常用开发工具

另外设置一个断点,另外设置一个断点, ii值等于值等于 9999。。

Page 29: Linux 常用开发工具

6.3 6.3 程序维护工具程序维护工具 makemake6.3.1 make6.3.1 make 的工作机制的工作机制• GNUGNU 的的 makemake 的工作过程如下:的工作过程如下: ① ① 依次读入各依次读入各 makefilemakefile 文件;文件; ② ② 初始化文件中的变量;初始化文件中的变量; ③ ③ 推导隐式规则,并分析所有规则;推导隐式规则,并分析所有规则; ④ ④ 为所有的目标文件创建依赖关系链;为所有的目标文件创建依赖关系链; ⑤ ⑤ 根据依赖关系和时间数据,确定哪些目标文件要重新生成;根据依赖关系和时间数据,确定哪些目标文件要重新生成; ⑥ ⑥ 执行相应的生成命令。执行相应的生成命令。

Page 30: Linux 常用开发工具

11 .. makefilemakefile 文件文件• makemake 被调用后会依次查找名为被调用后会依次查找名为 GNUmakefileGNUmakefile ,, makefilemakefile 和和 MakeMakefilefile 的描述文件 的描述文件 • 一个示例 一个示例 ::prog: x.o y.o z.o assmb.oprog: x.o y.o z.o assmb.o gcc x.o y.o z.o assmb.o -L/home/mqc/lib -lm -o proggcc x.o y.o z.o assmb.o -L/home/mqc/lib -lm -o progx.o:x.c defs.hx.o:x.c defs.h gcc -c x.cgcc -c x.cy.o: y.c defs.hy.o: y.c defs.h gcc -c y.cgcc -c y.cz.o:z.cz.o:z.c gcc -c z.cgcc -c z.cassmb.o:assmb.sassmb.o:assmb.s as -o assmb.o assmb.sas -o assmb.o assmb.sclean:clean: rm prog *.orm prog *.o

Page 31: Linux 常用开发工具

• MakefileMakefile 规则有以下通用形式:规则有以下通用形式:目标文件:目标文件: [[相依文件…相依文件… ]]<tab><tab> 命令命令 1[#1[#注释注释 ]]……<tab><tab> 命令命令 n[#n[# 注释注释 ]]• 在格式上应注意:在格式上应注意:• 依赖行从一行的开头开始书写依赖行从一行的开头开始书写• 各命令行单独占一行,每个命令行的第一个字符必须是制表符各命令行单独占一行,每个命令行的第一个字符必须是制表符 <tab><tab> ,,而不能使用而不能使用 88 个空格个空格

• ## 号后的内容为注释号后的内容为注释 • 在依赖行上,目标文件和相依文件之间要用一个或两个冒号分开在依赖行上,目标文件和相依文件之间要用一个或两个冒号分开

Page 32: Linux 常用开发工具

22 .依赖关系图.依赖关系图• 使用使用 makemake 的一个核心问题是确定好各文件之间的依赖关系。一般来的一个核心问题是确定好各文件之间的依赖关系。一般来说,生成一个目标文件可能有多个不同的途径,根据这些途径能够指说,生成一个目标文件可能有多个不同的途径,根据这些途径能够指

定不同的依赖关系。定不同的依赖关系。 • makemake 是依据“关系图深度优先搜索”的算法来核查目标文件及相依是依据“关系图深度优先搜索”的算法来核查目标文件及相依文件的修改时间,深度相等时,可由左到右依次进行。 文件的修改时间,深度相等时,可由左到右依次进行。 • 适当地引入中间结果,合理地构造依赖关系图,可以省去一部分编译适当地引入中间结果,合理地构造依赖关系图,可以省去一部分编译工作量。但并非层次越多越好,要考虑目标文件的生成过程及其所起工作量。但并非层次越多越好,要考虑目标文件的生成过程及其所起

的作用。的作用。

Page 33: Linux 常用开发工具

6.3.2 6.3.2 使用变量使用变量11 .变量定义和引用.变量定义和引用• makemake 的变量(又称做宏定义)一般均由大写字母和数字组成。的变量(又称做宏定义)一般均由大写字母和数字组成。• 定义变量的一般格式是:定义变量的一般格式是: << 变量名变量名 >=<>=< 字符串字符串 >> 例如,下面都是合法的变量定义:例如,下面都是合法的变量定义: OBJECT=x.o y.o z.oOBJECT=x.o y.o z.o LIBES=-lmLIBES=-lm• 引用引用 makemake 变量的方式与引用变量的方式与引用 shellshell 变量类似,即:把变量用圆括号变量类似,即:把变量用圆括号括起来,并在前面加上“括起来,并在前面加上“ $”$” 符号。例如:符号。例如: $(OBJECT)$(OBJECT) $(LIBES)$(LIBES)

Page 34: Linux 常用开发工具

22 .自动变量.自动变量• 除了用户定义的变量外,除了用户定义的变量外, makemake 也可以使用环境变量、自动变量和预也可以使用环境变量、自动变量和预

定义变量。定义变量。 • makemake 中定义了一些它们的值会因环境的不同而发生改变的变量,被中定义了一些它们的值会因环境的不同而发生改变的变量,被

称为自动变量。称为自动变量。 例如:例如:• $@ $@ 表示规则中的目标文件集合表示规则中的目标文件集合• $? $? 所有比目标文件还新的那些相依文件的集合,以空格分开所有比目标文件还新的那些相依文件的集合,以空格分开• $< $< 规则中的第一个相依文件名规则中的第一个相依文件名• $^ $^ 规则中所有相依文件的集合,以空格分开规则中所有相依文件的集合,以空格分开• $% $% 仅当目标文件是一个静态库成员时,表示规则中的目标成员 仅当目标文件是一个静态库成员时,表示规则中的目标成员 名,而此时名,而此时 $@$@ 表示相应库文件的名称表示相应库文件的名称• $* $* 如果目标文件的后缀是如果目标文件的后缀是 makemake 所识别的,则所识别的,则 $*$* 就是去掉后缀就是去掉后缀的目标文件名,但该引用只有用在隐含规则中才有意义的目标文件名,但该引用只有用在隐含规则中才有意义

Page 35: Linux 常用开发工具

33 .预定义变量.预定义变量• 归档库归档库 : AR ARFLAGS: AR ARFLAGS• 汇编命令: 汇编命令: AS ASFLAGSAS ASFLAGS• CC 编译命令: 编译命令: CC CPP CFLAGS CPPFLAGSCC CPP CFLAGS CPPFLAGS• C++C++ 编译命令: 编译命令: CXX CXXFLAGSCXX CXXFLAGS

Page 36: Linux 常用开发工具

6.3.3 6.3.3 隐式规则隐式规则• 在在 makefilemakefile 文件中显式地指定了一些规则,称为显式规则。文件中显式地指定了一些规则,称为显式规则。 • 隐式规则就是一种惯例,即预先约定好了,不需要在隐式规则就是一种惯例,即预先约定好了,不需要在 makefilemakefile 文件文件中写出来的规则。中写出来的规则。• 几个常用的隐式规则:几个常用的隐式规则:① ① 编译编译 CC 语言程序的隐式规则语言程序的隐式规则 ② ② 编译编译 C++C++ 程序的隐式规则 程序的隐式规则 ③ ③ 汇编和汇编预处理的隐式规则 汇编和汇编预处理的隐式规则

Page 37: Linux 常用开发工具

6.3.4 make6.3.4 make 命令常用选项命令常用选项• makemake 命令有丰富的命令行选项。命令有丰富的命令行选项。 例如:例如: -C -C dirdir 把目录改到把目录改到 dirdir -d -d 输出所有的调试信息输出所有的调试信息 -e -e 指明环境变量优先于指明环境变量优先于 makefilemakefile 文件中的变量文件中的变量 -f -f filefile 使用使用 filefile 文件作为文件作为 makefilemakefile 文件文件 -I -I 忽略在执行重新生成文件的命令的过程中出现的所有错误忽略在执行重新生成文件的命令的过程中出现的所有错误 -I -I dirdir 或 –或 – IIdirdir 指定一个包含指定一个包含 makefilemakefile 文件的搜索目录文件的搜索目录