第3章Linux系统C语言开发工具_第1页
第3章Linux系统C语言开发工具_第2页
第3章Linux系统C语言开发工具_第3页
第3章Linux系统C语言开发工具_第4页
第3章Linux系统C语言开发工具_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第3章章Linux系统C语言开发工具2 本章重点q Linux环境下C程序的编辑、编译、运行q gcc的编译过程q 编译参数-I、 -L的使用q 静态函数库与共享库q make工程文件q gdb调试工具的使用3 本章导读q C语言是Linux系统最常用的编程语言之一q Linux内核绝大部分用C语言编写q 开发人员通过函数库、系统调用实现系统服务q Linux系统拥有许多程序生成和分析的工具4 3.1 第一个Linux环境下的C语言程序q 例3.1 编写一个简单的C语言程序,在屏幕上打印5行“Hello, Linux World”gcc编译器编译C程序的常用格式:gcc 源文件 -o 可执行

2、文件gcc -o 可执行文件 源文件gcc 源文件 (可执行文件名默认为a.out)5 3.1 第一个Linux环境下的C语言程序q 例3.1 编写一个简单的C语言程序,在屏幕上打印5行“Hello, Linux World”(续)6 3.1 第一个Linux环境下的C语言程序q 例3.1 编写一个简单的C语言程序,在屏幕上打印5行“Hello, Linux World”(续)7 3.2 编译C语言程序3.2.1 gcc编译器q gcc编译器是Linux平台上应用最广泛的C编译器;g+编译器用于编译C+程序,但是g+内部还是调用了gccq 执行gcc命令时,它将完成“预处理预处理”、“编译编译

3、”、“汇编汇编”、“链链接接”4个步骤,并生成可执行代码。q gcc命令可以接受多种文件类型,并依据用户指定的命令行参数做出处理后缀名对应的语言后缀名对应的语言.cC原始程序.ii经过预处理的C+程序.CC+原始程序.s汇编语言程序汇编语言程序.ccC+原始程序.S汇编语言程序.cxxC+原始程序.h预处理文件(头文件).mObjective-C原始程序.o二进制文件(目标文件)二进制文件(目标文件).i经过预处理的经过预处理的C程序程序.a/.so编译后的库文件(无后缀)(无后缀) 一般指可执行文件一般指可执行文件83.2.1 gcc编译器q gcc编译流程如右图所示;各种参数有助于程序员灵

4、活地控制整个编译过程源代码(*.c文件)预处理(预处理(Pre-processing),选项),选项-E编译(编译(Compiling),选项),选项-S汇编(汇编(Assembling),选项),选项-c链接(链接(Linking),选项),选项-o生成预处理过的文件.i生成汇编语言文件.s生成二进制文件.o链接生成可执行文件 3.2 编译C语言程序9 3.2 编译C语言程序3.2.1 gcc编译器q gcc命令的使用格式:gcc options filename-listoptions常用选项有:-ansi 依据ANSI标准-c 不执行链接步骤,编译生成目标文件(.o)-g 创建用于gdb

5、(GNU DeBugger)的符号表和调试信息-l 库文件名 链接库文件-m 类型 根据给定的CPU类型优化代码-o 文件名 将生成的可执行程序保存为指定的文件-O 级别 根据指定的级别(0-3)进行优化;级别为0,则不做任何优化-pg 产生供GNU剖析工具gprof使用的信息-S 不执行汇编和链接阶段,并保留编译产生的汇编代码(.s文件)10 3.2 编译C语言程序3.2.1 gcc编译器q gcc命令的使用格式:options常用选项有:(续)-v 产生尽可能多的输出信息-w 忽略警告信息-W 产生比默认模式更多的警告信息q gcc的每个选项前需要有连字符 -q gcc不能在一个连字符后跟

6、一组选项例如gcc -p -g hello.c 与gcc -pg hello.c 含义不同11 3.2 编译C语言程序3.2.1 gcc编译器q 例:选项 -c 的用法附:在多文件C/C+程序中,全局变量只能在一个文件中被定义,在其它文件中应被声明为“外部变量”/对全局变量a进行了声明/对全局函数PrintA进行了声明/定义了全局变量a/定义了全局函数PrintA12 3.2 编译C语言程序3.2.1 gcc编译器q 例:选项 -c 的用法(续) 使用 -c 选项编译生成目标文件;然后链接目标文件,生成可执行文件 链接时,链接器在a.o中找到变量a和函数PrintA13 3.2 编译C语言程序

7、3.2.2 gcc编译流程q gcc编译流程如下图所示:源代码(*.c文件)预处理(Pre-processing)编译(Compiling)汇编(Assembling)链接(Linking)可执行文件14 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 预处理预处理/预编译预编译:在真正开始对程序编译之前,先对源程序进行一番处理,形成临时的源程序文件。预处理的功能主要有: 符号常量的定义和宏定义符号常量的定义和宏定义例如#define MAX_NUM 1000#define UNIVERSITY_NAME “NWSUAF”15 3.2 编译C语言程序3.2.2 gcc编译流程(续)q

8、 预处理预处理/预编译预编译:(续) 文件包含文件包含例如#include /如果不包含该头文件,则printf语句出错 通过#include命令能够将被包含的文件(一般称为头文件)的全部内容插入到#include命令的位置,此即预处理阶段需要做的事情。 复杂程序常常由多个.c文件组成,这些文件可能都会使用某个函数,则1. 将该函数的定义编写在某个.c文件中;2. 将函数的声明编写在一个头文件中;3. 在用到该函数的.c文件中包含该头文件16 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 例/”表示首先到当前文件夹下找头文件,/再到编译器指定的文件夹下找头文件库函数文件主函数文件头

9、文件未出现17 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 预处理预处理/预编译预编译: 符号常量的定义和宏定义 文件包含 条件编译条件编译18 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 编译编译: 检查语法错误,若无语法错误,生成中间的目标文件(.o或.obj文件) 多个.c文件组成的程序,每个.c文件都会被编译生成一个.o文件 .o文件中存放的是所对应的.c文件中的全局变量、静态变量的名称、地址等,以及在.c文件中编写的全部函数的可执行机器指令 若a.c有语法错误,不会影响b.c被编译成b.o,例如19 3.2 编译C语言程序3.2.2 gcc编译流程(续)q

10、 编译编译: 若a.c有语法错误,不会影响b.c被编译成b.o,例如(续)修正b.c之后,20 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 链接链接: 头文件中一般只有库函数的声明,没有库函数的函数体。 库函数的源代码编译器厂家不一定会提供给用户,但是会提供库函数经过编译后的中间结果。 编译器的安装文件夹下往往都会有一个lib文件夹,里面放着后缀是”.lib”、”.obj”的文件,这些文件中包含很多库函数的机器指令(即实现方式)。 链接阶段,编译器会抽取库函数的机器指令,合并到可执行文件中去。 有些软件厂商专门出售函数库,如高效的图形处理函数库、科学计算函数库、视频编解码函数库等

11、;用户买到函数库后,在程序中包含声明库函数的头文件,且需要在链接选项中指定要链接哪些.lib文件或.obj文件 综上,链接就是把编译出来的多个.o文件拼在一起,并抽取一系列相关库函数的机器指令,合并形成可执行文件。21 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 例例3.3 输入两个整数,输出求和后的结果。使用-E、-S、-c、-o选项,控制gcc的编译流程。 步骤1:编写源代码22 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 例例3.3(续)(续) 步骤2:预处理阶段 在该步骤中,编译器将”stdio.h”文件包含进来,插入到#include 位置处。 使用 E

12、控制编译流程:当预处理完成后即停止编译流程。23 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 例例3.3(续)(续) 步骤2:预处理阶段(续) 预处理后的程序3-3.i的部分内容如下:/可参阅stdio.h的内容24 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 例例3.3(续)(续) 步骤3:编译阶段 首先检查代码的规范性、正确性;检查无误后,把代码翻译为汇编语言;使用参数”-S”控制编译流程,产生汇编代码。25 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 例例3.3(续)(续) 步骤4:汇编阶段 把编译阶段生成的”.s”文件转成”.o”文件(二进制代

13、码)。用参数”-c”控制编译流程:汇编结束后即停止编译流程。26 3.2 编译C语言程序3.2.2 gcc编译流程(续)q 例例3.3(续)(续) 步骤5:链接阶段 预处理阶段已将头文件stdio.h包含进来,其中有printf、scanf的声明; 链接阶段需要查找相应的库文件(例如/usr/lib下的libc.so.6库文件),将printf、scanf链接到库函数中,即找到printf、scanf的实现细节; 完成链接后,生成可执行程序注:gcc默认使用动态链接库(另见P118页“共享库”的描述),即在编译链接时并不把库文件的代码加入可执行文件,而是在程序执行时动态加载链接库,以节省系统开

14、销。27 3.2 编译C语言程序3.2.3 gcc编译器的主要参数q gcc有100多个可用参数,主要分为 总体参数 告警和出错参数 优化参数 28 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)1. 总体参数 参数含义参数含义-c只汇编不链接,生成二进制目标文件-v显示gcc的版本信息-S只编译不汇编,生成汇编代码-I dir在头文件的搜索路径中添加dir目录-E只进行预编译-L dir在库文件的搜索路径列表中添加dir目录-g在可执行程序中包含调试信息-static链接静态库-o file把文件输出至file中-llibrary链接名称为library的库文件29 3.2

15、编译C语言程序3.2.3 gcc编译器的主要参数(续) 例3.4 设计一个程序(3-4.c),把从键盘输入的字符串按照原样输出到屏幕上,把标准输入输出库文件放在自定义的头文件(my.h)中,且该头文件位于当前目录下。/自定义头文件,包含标准输入输出库/gcc在默认的目录”usr/include”中找不/到”my.h”文件,因此需要用”-I dir”选项/表示在默认路径/usr/include”中搜索头文件30 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续) 例3.4 (续)/”表示首先在当前目录中搜索头文件,然后再到/编译器指定的文件夹下搜索头文件。/无需加入”-I dir”选

16、项31 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)2. 警告和出错参数 参数含义-ansi仅支持符合 ANSI 的 C 程序-pedantic允许发出 ANSI C 标准所列的全部警告信息-pedantic-error允许发出 ANSI C 标准所列的全部错误信息-w关闭所有警告-Wall允许发出gcc提供的所有有用的警告信息-werror把所有的警告信息转化为错误信息,并在警告发生时终止编译32 3.2 编译C语言程序补充:ANSI C和ISO C的历史 C 的第一个标准是由ANSI(美国国家标准协会)发布的。这份文档后来被国际标准化组织(ISO)采纳并且修订。名称ANS

17、I C被广泛使用,也有人使用ISO C 或 Standard C。C89 1983年,为了创立 C 语言的标准,美国国家标准协会(ANSI)组成了委员会(X3J11),经过漫长而艰苦的过程,该标准于1989年完成,一般简称为C89标准,也被称作ANSI C。C90 1990年,ANSI C89标准被国际标准化组织(ISO)和国际电工委员会(IEC)采纳为国际标准,简称C90标准。C89和C90通常指同一个标准,C89这种说法更常用。C99 2000年3月,国际标准化组织(ISO)和国际电工委员会(IEC)采纳了第二个C语言标准,简称C99标准。 C11 2011年12月,国际标准化组织(ISO

18、)和国际电工委员会(IEC)采纳了第三个C语言标准,简称C11标准,它是C程序语言的最新标准。 33 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)p 例3.6 设计一个程序,使它包含一些非标准语法。熟悉gcc的警告和出错参数的用法。 编辑源代码 关闭所有警告34 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)p 例3.6 设计一个程序,使它包含一些非标准语法。熟悉gcc的警告和出错参数的用法。(续) 显示不符合ANSI C语法标准的警告信息。 允许发出ANSI C标准所列的全部警告信息35 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)p 例3

19、.6 设计一个程序,使它包含一些非标准语法。熟悉gcc的警告和出错参数的用法。(续) 允许发出gcc提供的所有有用的警告信息36 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)3. 优化参数 代码优化指的是编译器通过分析源代码,找出其中尚未达到性能最优的部分,继而对其进行重新组合,目的在于改善程序的执行性能。37 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)3. 优化参数(续) 38 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)3. 优化参数(续) 39 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)3. 优化参数(续) 注:

20、也可以通过-S选项,分别生成优化前后的汇编代码,比较其异同。40 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)3. 优化参数(续) gcc提供的代码优化功能非常强大,通过参数”-On”来优化代码,其中n代表优化级别,如0、1、2、3、s-O0:关闭所有的优化选项,通常不建议这样做-O1:最基本的优化等级,不花费太多编译时间,试图生成更快、更小的代码-O2:不增大体积、不占用太多编译时间,试图提高代码性能;-O2在效率与安全性方面取得了较好的平衡,推荐使用。-O3:最危险的优化等级。增大体积、更耗内存、延长编译时间,增加编译失败的可能。-Os:对于磁盘空间紧张或CPU缓存较小的

21、机器非常有用,但可能存在问题,不推荐。综上,优化等级越高,程序的运行速度越快,但是编译时间、代码体积可能越长,-O2在这些因素之间取得了较好的平衡。41 3.2 编译C语言程序3.2.3 gcc编译器的主要参数(续)3. 优化参数(续) 程序员要力求手工编写高质量的代码,减少编译器的优化工作,甚至根本无需优化。 程序开发过程中不建议使用优化参数,只有当软件发行或开发结束时,对最终生成的代码进行优化。 资源受限时(例如在一些实时嵌入式设备中内存资源非常紧张),不建议对代码进行优化 跟踪调试时,优化可能使代码被删除、改写或重组等,从而使跟踪和调试变得异常困难,不建议使用。42 3.2 编译C语言程

22、序3.2.4 函数库 函数库是一组预先编译好的函数的集合,通常以静态库、共享库两种格式存在。 标准系统库文件一般存放在/lib 和 /usr/lib 目录中;对于自定义的库文件,需要指明其所在目录和文件名称 库文件总是以lib开头,之后的内容指明该库是什么库:c代表C语言库m代表数学库 . 后的内容指明库文件的类型:.a 代表传统的静态函数库,例如libm.a为静态数学函数库.so 代表共享的函数库3.2.4 函数库指明编译器所要搜索的库文件的两种方式: 给出完整的路径名给出完整的路径名例如:gcc o hello hello.c /usr/lib/x86_64-linux-gnu/libm.

23、a表明除了搜索标准的C函数库之外,还需搜索数学库 使用使用 -l 、-L 选项选项例如:gcc -o hello hello.c -lm 表明搜索标准库目录中的libm.a(静态库)或libm.so(动态库)或 gcc -o hello hello.c -L /usr/lib -lm 其中,/usr/lib 可以被省略,因为它是标准库目录,是系统默认的搜索路径。43 3.2 编译C语言程序3.2.4 函数库 使用使用 -l 、-L 选项(续)选项(续)44 3.2 编译C语言程序45 3.2 编译C语言程序3.2.4 函数库1.静态库函数库的最简单的形式是一组处于“待用”状态的目标文件。当程序

24、需要使用函数库中的某个函数时,程序需要包含(#include)一个声明该函数的头文件编译器、链接器负责将程序代码和函数库结合在一起组成一个可执行文件除了标准的C语言库,如果还需要使用其它库,则必须用-l 和 L选项指明若要创建和维护自己的静态库,则需使用ar程序和gcc -c命令对所使用的函数分别进行编译46 3.2 编译C语言程序3.2.4 函数库1. 静态库静态库q 例3.8 创建一个小型函数库,包括以下步骤:(1)建立两个文件pro1.c、pro2.c,它们各自包含一个函数, 分别是void pro1(int), void pro2(char *)(2)应用gcc及参数-c,分别产生目标

25、文件pro1.o, pro2.o(3)建立名为lib.h的头文件,该文件包含两个函数pro1、pro2的函数原型/声明(4)应用归档命令ar 建立静态链接库文件libfoo.a,命令形式为: ar crv libfoo.a pro1.o pro2.o(5)最后设计主程序3-8.c,其中包含头文件lib.h(6)使用gcc对3-8.c进行编译,并加入参数-lfoo,即可调用pro1和pro2函数47 3.2 编译C语言程序3.2.4 函数库1. 静态库静态库q 例3.8 (续)步骤1:为两个函数分别创建各自的源文件48 3.2 编译C语言程序3.2.4 函数库1. 静态库静态库q 例3.8 (续

26、)步骤2:分别编译这两个函数,产生需要包含在库文件中的.o文件步骤3:为库文件创建一个头文件lib.h,该头文件声明了库文件中的函数;该头文件将被所有希望使用库文件的应用程序所包含49 3.2 编译C语言程序3.2.4 函数库1. 静态库静态库q 例3.8 (续)步骤4:使用ar程序创建一个归档文件,即库文件(libfoo.a),并将.o文件添加进去步骤5:创建主程序3-8.c,它包含库的头文件,且调用库中的一个函数50 3.2 编译C语言程序3.2.4 函数库1. 静态库静态库q 例3.8 (续)步骤6:编译并测试3-8.c注: “-L dir”的作用是在库文件的搜索路径列表中添加dir目录

27、 上述”-L .”指示编译器在当前目录下查找函数库; Linux下的库文件命名时须以”lib”开头 指定链接库文件需要使用”-llibxxx”参数,其中”lib”可以被省略,即”-lxxx”即可 因此上述”-lfoo”指示编译器使用名为libfoo.a的静态函数库,或名为libfoo.so的共享函数库(如果它存在)51 3.2 编译C语言程序3.2.4 函数库1. 静态库静态库q 例3.8 (续)可以使用nm命令查看.o文件、函数库(.a或.so)或可执行文件中包含的函数,例如注:创建可执行程序3-8时,程序只包含函数库中它实际需要的函数;虽然程序的头文件包含了函数库中所有函数的声明,但并不会

28、将整个函数库包含在最终的程序中。52 3.2 编译C语言程序3.2.4 函数库2. 共享库静态库缺点:当使用同一个函数库函数的多个程序同时运行时,内存中有同一函数的多个拷贝,从而消耗宝贵的内存资源以及磁盘空间。共享库能够克服这一缺点,实现函数的动态链接;当编译好的程序被装载到内存中执行时,函数引用被解析并产生对共享库的调用,如果有必要,共享库才被加载到内存中。通过共享库,系统只保留一份共享库的拷贝并供多个应用程序同时使用,该拷贝在磁盘上也仅保存一份。53 3.2 编译C语言程序3.2.4 函数库2. 共享库(续)共享库的另一个优势在于,共享库的更新不影响依赖它的应用程序的运行。例如/usr/l

29、ib/libm.o作为库文件的修订版本/usr/lib/libm.so.N 的符号链接,当Linux启动应用程序时,会考虑应用程序所需要的函数库版本,以防止新版本函数库在旧的应用程序上不能被使用。共享库在很多方面类似于Windows中使用的动态链接库,.so库对应于.DLL文件。在程序运行时加载;而.a库类似于.LIB文件,包含在可执行程序中。54 3.2 编译C语言程序3.2.4 函数库2. 共享库(续)55 3.2 编译C语言程序3.2.4 函数库2. 共享库(续)p 虽然程序已包含数学函数库,但是未指定库文件的路径、名称p 因此需要查找函数所在的库文件的路径、名称56 3.2 编译C语言

30、程序3.2.4 函数库2.共享库(续)思考题:57 3.3 make工程文件3.3.1 make命令 C语言的大型软件中常包含多个源文件、头文件,文件之间通常彼此依赖、关系复杂。 如果修改了其中的一个文件,则必须重新编译所有依赖它的文件。 make工程管理器是一个“自动编译管理器”,能够根据文件的时间戳自动发现被更新过的文件,从而减少编译的工作量。 make工程管理器通过读入makefile或Makefile文件来执行大量的编译工作,大大提高了工作效率。 makefile或Makefile的文件描述了系统中各个模块之间的依赖关系;当部分文件改变时,make工具决定需要重新编译的文件的最小集合。

31、58 3.3 make工程文件3.3.1 make命令 使用格式:make 选项 make工程文件-d 显示调试信息-f 文件 将指定文件(而不是默认的makefile或Makefile)作为依赖 关系文件-n 仅显示但不执行makefile或Makefile文件中的编译命令-s 执行但不显示任何信息59 3.3 make工程文件3.3.2 make规则 默认的程序依赖关系文件名可以是GNUmakefile、makefile、Makefile makefile所包含的规则主要描述目标文件(target文件,勿与.o文件混淆)由哪些依赖文件(dependency)产生,以及用什么命令来执行tar

32、get目标文件dependency依赖文件生成target目标文件所需的编译命令Tab键空格隔开目标文件可以是要执行的工作60 3.3 make工程文件3.3.2 make规则 当make命令检查发现,目标文件的生成或被改动的时间(文件的时间戳)至少比它的一个依赖文件还早的话,则make执行相应的命令,更新目标文件 目标文件(target)不一定是最后的可执行文件,可以是任何一个中间文件或依赖文件 makefile文件通常包括:l 需要由make工具创建的目标(target),通常是目标文件或可执行文件l 创建目标所依赖的文件l 创建每个目标时需要运行的命令l 其它要执行的动作(如clean)

33、61 3.3 make工程文件3.3.3 编写makefile文件例3.10 计算学生的总成绩、平均成绩(由自定义的函数fun_sum、fun_avg分别完成),并使用make工程管理器进行编译。文件名逻辑关系3-10-main.c3-10-fun_sum.c3-10-fun_avg.cChengji.h (包含fun_avg和fun_sum的函数声明)62 3.3 make工程文件3.3.3 编写makefile文件例3.10(续) makefile文件注:当3-10-main.c中使用#include “chengji.h”,且chengji.h在当前目录下时,可直接使用如下命令生成3-10-main.ogcc 3-10-main.c c否则,需要使用gcc 3-10-main.c c I dir (dir为chengji.h所在的目录) 63 3.3 make工程文件3.3.3 编写makefile文件例3.10 (续) 3-10-main.c 源代码64 3.3 make工程文件3.3.3 编写makefile文件例3.10 (续) 3-10-fun_sum.c、3-10-fun_avg.c、chengji.h 源代码65 3.3 make工程文件指定makefile3-10作为依赖关系文件,而不是默认的makefile或Makefile3.3.3 编写m

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论