Linux系统分析入门基础.pptx_第1页
Linux系统分析入门基础.pptx_第2页
Linux系统分析入门基础.pptx_第3页
Linux系统分析入门基础.pptx_第4页
Linux系统分析入门基础.pptx_第5页
已阅读5页,还剩143页未读 继续免费阅读

下载本文档

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

文档简介

1、第1讲 Linux系统分析基础,南京大学计算机科学与技术系,了解Linux发展概况 了解Linux内核结构及编译方法 掌握Linux基本编程方法 掌握GNU编程工具 理解Linux程序执行机制,2,教学目标,3,主要内容,Linux简介 Linux内核环境 Linux编程环境 GNU make管理项目 Linux的程序执行机制,4,初识Linux,类Unix(Unix-like)操作系统 其他类UNIX系统包括Solaris、Mac OS等 基于GPL(GNU Public License)的自由操作系统 第一个版本发行于1991年 主要用C语言编写,部分代码用汇编语言编写 “Linux”在不

2、同语境下的内涵不同 Linux内核、Linux系统、Linux开发套件等 严格来说,Linux指由Linux Torvalds维护(及通过主要镜像网站发布)的内核,Linux简介,5,Linux发展史,1991年11月,芬兰赫尔辛基大学的 Linus Torvalds 编写了一个小程序(取名为Linux),发布在互联网上 希望借此实现一个操作系统“内核” 1993年 一批高水平网络黑客参与,诞生Linux 1.0 版 1994年 Linux 的第一个商业版 Slackware 问世 1996年 美国国家标准技术局计算机系统实验室确认 Linux 版本1.2.13符合 POSIX 标准 2001

3、年 Linux2.4版内核发布 2003年 Linux2.6版内核发布,Linux简介,6,Linux操作系统特征,符合POSIX标准规范的操作系统 Portable Operation System Interface of Unix:可移植的操作系统接口 由IEEE开发,ANSI和ISO标准化 具备现代操作系统的基本功能 抢占式多任务处理,支持多用户 图形用户接口 异构硬件支持 支持SMP 支持TCP/IP 多体系结构支持,支持32/64位CPU 拥有其他操作系统没有的特色 NFS、VFS、高效的EXT系列文件系统等,Linux简介,代表一种开源文化 免费软件,开放源代码 自由软件,可在原

4、有程序基础上开发自己的程序 GNU/Linux Linux仅指Linux内核 Linux系统的大部分应用都建立在GNU软件之上 核心结构 Linux内核 Linux Shell Linux文件系统 Linux应用系统 GNU Tools,7,Linux精髓,Linux简介,8,Linux的系统结构,用户应用程序,系统调用,硬件资源管理接口,Shell,库函数,内核实现,Linux简介,不区分的缺陷 用户直接修改操作系统的数据 用户直接调用操作系统的内部函数 用户直接操作外设 用户任意读/写物理内存 区分的意义 禁止用户程序和底层硬件直接打交道 如果用户程序往硬件控制寄存器写入不恰当的值,可能导

5、致硬件无法正常工作 禁止用户程序访问任意物理内存,否则可能会破坏其他程序的正常执行 如果对核心内核所在的地址空间写入数据,会导致系统崩溃,9,划分用户态/内核态的必要性,Linux简介,现代CPU都有几种不同指令执行级别 在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就对应着内核态 在相应低级别执行状态下,代码的掌控范围会受到限制,只能在对应级别允许的范围内活动 举例 intel x86 CPU有四种不同的执行级别0-3 Linux只使用0级和3级分别表示内核态和用户态,10,CPU对用户态/和心态划分的支持,Linux简介,cs寄存器最低两位表明当前代码的特权级

6、 CPU每条指令的读取都是通过cs:eip这两个寄存器 cs:代码段选择寄存器 eip:偏移量寄存器 上述判断由硬件完成 在Linux中,地址空间是一个显著的标志 0 xc0000000以上地址空间:只能在内核态下访问 0 x00000000 0 xbfffffff的地址空间:两种状态下都可访问 注意,这里的地址空间是逻辑地址而不是物理地址,11,用户态/和心态的区分方法,Linux简介,Linux是单内核、多模块系统 Linux内核运行在单独的内核地址空间 所有操作系统功能作为一个模块实现在其内核中 模块均运行在内核态,直接调用函数,无需消息传递 具备模块化设计、抢占式内核(Linux 2.

7、6支持,Linux 2.4用户级抢占)、支持内核线程及动态装载内核模块的能力 与Unix主要区别 Linux汲取了微内核设计思想(基于模块定制内核) Unix也是单内核系统 Windows NT和Mach是微内核系统 只提供基础功能,其他功能通过服务实现 微内核功能被划分为多个独立过程,每个过程称为服务器,12,Linux的内核特点,Linux简介,13,Linux单内核结构,Linux简介,14,Linux的内核版本,Linux内核版本指由Linux开发小组(Linus Torvalds总协调)开发出系统内核的版本号 Linux内核采用双树系统 一棵是稳定树,主要用于发行 另一棵是非稳定树(

8、开发树),用于产品开发和改进 Linux内核版本号由3位数字组成,r.x.y,第1位数字r为主版本号,第2位数字x为说明版本类型的次版本号: 偶数表示产品化版本 奇数表示实验版本,第3位数字y为修改号,表示错误修补的次数,Linux简介,15,主流的Linux发行版本,Linux简介,16,Linux与Windows的区别,文件系统 Linux需要一个挂载根目录/的ext分区和一个作为虚拟内存的swap分区 Linux没有盘符,可通过设备名挂载,挂在信息在/dev/fstab,如 mount -t ntfs /dev/sda1 /mnt/win_c Linux将所有设备都映射成/dev目录下的

9、一个文件 用户管理 系统管理员是root,使用su命令切换,Linux简介,17,主要内容,Linux简介 Linux内核环境 Linux编程环境 Linux的系统初始化 Linux的程序执行机制,18,Linux内核核心组成,进程调度程序:负责控制进程访问CPU 内核管理程序:支持虚拟内存及多进程安全共享主存系统 虚拟文件系统:抽象异构硬件设备细节,提供公共文件接口 网络接口:提供对多种组网标准和网络硬件的访问 进程间通信:为进程之间的通信提供实现机制,Linux内核环境,19,Linux内核源码的获取,下载位置 以GNU zip和bzip2形式发布 安装位置

10、一般安装在/usr/src/linux,不要将该源码树用于开发 在编译自己编写的C库所用的内核版本要链接到该树 不要以root身份对内核进行修改,应先建立自己的主目录,仅以root身份安装新内核 安装新内核应该保持/usr/src/linux原封不动,Linux内核环境,20,Linux核心源码结构,Linux内核环境,21,Linux核心源码的组织,arch 目录 包含与体系结构相关的核心代码,相关.h文件则放在include/asm下 支持的每种CPU均有相应子目录,包含boot、kernel、lib和mm等子目录 /kernel目录 存放大多数内核函数 主要文件包括sched.c、tim

11、e.c、sys.c、itimer.c、fork.c、signal.c、softirq.c、resource.c、dma.c、printk.c等 /mm子目录 独立于体系结构的主存管理文件 包括实现虚拟主存管理的源代码,Linux内核环境,/fs目录 存放VFS和系统支持的各种文件系统源代码 每个子目录对应一个特定文件系统 /include目录 存放重要的内核.h头文件 为各种CPU专设一个子目录 通用子目录include/linux、include/net /ipc目录 存放处理进程间通信所需源代码,22,Linux核心源码的组织(续),Linux内核环境,/drivers目录 存放所有设备驱

12、动程序源代码 /net子目录 存放网络子系统,如各种网卡和网络规程驱动程序 /security目录 存放安全子系统代码 /sound目录 存放语音子系统代码,23,Linux核心源码的组织(续),Linux内核环境,/init目录 存放内核引导和初始化代码 许多重要文件,如main.c、version.c就位于该目录下 /lib目录 存放内核需要的通用工具性内核函数(如对出错信息的处理),它能够在引导时解压内核并装入主存 /scripts目录 存放编译内核所用脚本和用于系统配置的命令文件 /documentation目录 存放内核源代码文档,24,Linux核心源码的组织(续),Linux内核

13、环境,采用模块化的内核配置系统 内核模块(Loadable Kernel Module)的概念 模块实际上是一种目标对象文件,没有链接,不能独立运行 但是其代码可以在系统运行时链接到系统中作为内核的一部分运行,或从内核中取下,从而可以动态扩充内核的功能(不需要重新编译内核) 这种目标代码通常由一组函数和数据结构组成,25,Linux内核的配置组成,Linux内核环境,使得内核更加紧凑和灵活,可扩展 修改模块时,不必全部重新编译整个内核 系统如果需要使用新模块,只要编译相应的模块,然后将模块插入即可 模块可以不依赖于某个固定的硬件平台 模块的目标代码一旦被链接到内核,它的作用域和静态链接的内核目

14、标代码完全等价,26,内核模块的优点,Linux内核环境,并不是所有地方都使用内核模块 设备驱动程序 文件系统驱动程序 系统调用 大部分系统调用属于基础内核(Basic kernel),也可以以内核模块方式增加新的系统调用或者覆盖现有基于内核模块方式实现的系统调用,27,内核模块的使用,Linux内核环境,程序代码:helloworld.c 编译、安装方法 root# gcc -c helloworld.c root# insmod helloworld.o root# lsmod root# rmmod helloworld,28,模块示例,#define MODULE #include i

15、nt init_module(void) printk(“Hello World!n”); return 0; void cleanup_module(void) printk(“ Goodbye!n”); ,Linux内核环境,29,内核模块与应用程序的差别,C语言程序 模块 运行 用户空间 内核空间 入口 main() init_module() 出口 无 cleanup_module() 编译 gcc -c gcc -c -D_KERNEL_-DMODULE 连接 gcc insmod 运行 直接运行 insmod 调试 gdb kdbug, kdb, kgdb等,Linux内核环境,控

16、制需要编译到内核的二进制映象(启动时载入)和在需要时才装入的内核模块 配置选项命名形式:CONFIG_FEATURE 如CONFIG_SMP表示支持对称多处理器 配置项选择模式 二选一:yes或no 三选一:yes、no或module Yes选项表示把代码编译进主内核映象,而不作为模块 Module意味该配置项被选定,但编译时该功能的实现代码是以模块形式生成 驱动程序一般都用三选一形式 字符串或整数 不控制编译过程,只是指定内核源码可以访问的值,如定义静态变量 一般以预处理宏的形式表示,30,Linux内核编译时的模块选配参数,Linux内核环境,内核编译主要工具文件 内核编译后,会在/boo

17、t目录生产以下文件 vmlinuz文件 initrd.img文件 System.map文件,31,Linux内核编译的基本架构,Makefile 定义编译链接规则、位于linux源代码各目录 配置文件(config.in或kconfig) 提供内核的配置选择和设置 配置工具 文本命令行工具:make config 基于ncurse的图形工具:make menuconfig 基于X11的图形工具:make xconfig 基于gtk+的图形工具:make gconfig 创建默认配置:make defconfig 配置工具输出文件 .config文件:用#include包括到主Makefile中

18、 include/linux/autoconf.h:用#include包括到各个.c文件 每个.c文件都有代码项,32,Linux内核配置系统组成,Linux内核环境,采用GNU编译工具对.config中的源文件列表编译 完成内核文件的配置、依赖关系及模块的生成,随后调用Rules.make编译文件 Rules.make定义所有Makefile共用的编译规则 Makefile支持的make命令 make mrproper:检查.o文件及文件依赖关系的正确性 make config:配置内核并生成配置文件 make dep:根据配置文件创建相应的依赖关系树 make clean:清除旧版本的目标

19、文件 make zImage:编译并用gzip压缩成1MB以下的内核 未压缩的文件是vmlinuz make bzImage:编译并用gzip压缩成1MB以上的内核 make modules:编译模块 make modules_install :安装模块 depmod a:生成模块之间的依赖关系,33,主Makefile功能,Linux内核环境,准备阶段 下载源码: 将源码解压到/usr/src目录下 tar xvjf linux-x.y.z.tar.bz2 tar xvzf linux-x.y.z.tar.gz 解压位置:linux-x.y.z目录下 建立内核编译

20、环境 ln sf linux-x.y.z linux cd /usr/include rm -rf asm linux scsi ln -sf /usr/src/linux/include/asm-i386 asm ln -sf /usr/src/linux/include/linux linux ln -sf /usr/src/linux/include/scsi scsi,34,Linux内核的编译、安装过程,Linux内核环境,配置内核 检查文件依赖关系正确性:make mrproper 获取默认.config文件:cp /boot/config-uname -r .config 生成配

21、置文件:make config 创建依赖关系树:make dep 清除旧版本目标文件:make clean 生成压缩形式内核文件:make bzImage或make zImage 编译后的文件在/usr/src/linux/arch/i386/boot目录下 编译、安装内核 编译内核:make 编译模块:make modules 安装模块:make modules_install 生成模块依赖关系:depmod a 安装内核:make install,35,Linux内核的编译、安装过程(续),Linux内核环境,配置启动文件 将内核映像拷贝到合适位置,并按启动要求启动 #cp /usr/sr

22、c/linux/arch/i386/boot/zImage /boot/zImage-x.y.z #cp /usr/src/linux/System.map /boot/System.map-x.y.z ln sf /boot/vmlinuz-x.y.z /boot/vmlinuz ln sf /boot/System.map-x.y.z /boot/system.map 系统正常启动时不会读这个符号表;主要是为了内核引导出错时便于调试 /sbin/mkinitrd /boot/initrd-x.y.z.img x.y.z 如果是LILO启动方式,编辑/etc/lilo.conf,36,Lin

23、ux内核的编译、安装过程(续),Linux内核环境,lilo.conf修改方法 image=/boot/vmlinux-2.4.7-10/ 旧内核 label=linux read-only root=/dev/hdal image=/boot/zImage-x.y.z / 新内核 label=newkernel read-only root=/dev/hdal 注意:必须运行lilo命令将激活新配置。如果是grub,则不需要。,37,Linux内核的编译、安装过程(续),38,Linux系统的文件系统结构,/:文件系统结构的起始点 /home:用户主目录 /bin:标准指令和工具程序 /us

24、r :系统使用文件和指令 /usr/bin:用户命令和工具程序 /usr/sbin:系统管理员命令 /usr/lib:编程语言库,/usr/doc:Linux文档 /usr/man:在线联机帮助手册 /usr/spool:假脱机文件 /sbin:管理员开启系统的命令 /var:时变文件,例如邮箱文件 /dev:设备文件接口 /etc:系统配置文件及其它系统文件,Linux内核环境,39,主要内容,Linux简介 Linux内核环境 Linux编程环境 GNU make管理项目 Linux的程序执行机制,40,Linux系统的用户视图,Linux编程环境,41,C程序员的系统视图,Linux编程

25、环境,42,系统调用与函数库,系统调用 Linux内核的对外接口 用户程序和内核之间唯一的接口 函数库 依赖于系统调用 标准函数库建立在系统调用的上层,提供的功能比系统调用强,使用也比较方便 静态库(.a文件) 动态库/共享库 (.so文件),Linux编程环境,43,Linux支持的编程语言,高级编程语言 C/C+, Java, Fortran ELF二进制格式 Executable and Linkable Format 工具接口标准委员会(TIS)选择ELF体系作为不同操作系统之间可移植的二进制文件格式 脚本 Shell: sh/bash, csh, ksh Perl, Python,

26、tcl/tk, sed, awk,Linux编程环境,44,文件名后缀,Linux编程环境,45,集成环境,集成开发环境IDE Emacs/xemacs Kdevelop Eclipse 命令行开发环境 编辑器 vi/vim/gvim, emacs/xemacs, pico 代码阅读器 source navigator,vi/emacs+ ctags/etags 配置工具 automake, autoconf, ,Linux编程环境,46,GNU开发工具,GCC GNU C编译器 Binutils 辅助GCC的主要软件 GDB GNU调试工具 gdb调试命令 二进制代码工具 as, ld, a

27、r, ldd Make CVS 版本控制,Linux编程环境,47,GCC,GCC不只是一个C编译器 GCC = GNU Compiler Collection GCC支持多种高级语言的编译 C、C+ ADA Object C JAVA Fortran PASCAL,Linux编程环境,48,GCC工具,cpp 预处理器 GNU C编译器在编译前自动使用cpp对程序进行预处理 gcc 符合ISO等标准的C编译器 g+ 基本符合ISO标准的C+编译器 gcj GCC的java前端 gnat GCC的GNU ADA 95前端,Linux编程环境,49,GNU工具gcc,是一个强大的工具集合,包含预

28、处理器、编译器、汇编器、链接器等组件 由输入文件类型和传递的参数决定gcc具体调用的组件 为开发者提供足够多的参数,可让开发者全面控制代码的生成 gcc下的C程序编译过程 预处理 编译成汇编代码 汇编成目标代码 链接,Linux编程环境,50,gcc使用举例,源程序,Linux编程环境,51,gcc使用举例,编译和运行 参数-o:指定目标名称(缺省gcc编译出来的文件是a.out) 参数-ansi:关闭GNU C中与ANSI C不兼容特性,激活ANSI C专有特性 包括禁止一些asminlinetypeof关键字,以及UNIX,vax等预处理宏,编译,运行,Linux编程环境,52,gcc的工

29、作过程,使用-v选项,可看到许多被隐藏的信息,Linux编程环境,53,预处理,使用-E参数激活预处理,输出文件的后缀为“.cpp” gcc E o gcctest.cpp gcctest.c 使用wc命令比较预处理后的文件与源文件,可以看到两个文件的差异,Linux编程环境,54,行数 单词数 字节数,预编译,wc命令示例,Linux编程环境,55,编译成汇编代码,预处理文件汇编代码 使用-x参数说明根据指定的步骤进行工作 cpp-output指明从预处理得到的文件开始编译 使用-S说明生成汇编代码后停止工作 gcc x cpp-output S o gcctest.s gcctest.cp

30、p 也可以直接编译到汇编代码 gcc S gcctest.c,Linux编程环境,56,编译成汇编代码,直接编译到汇编代码,Linux编程环境,预处理文件汇编代码,57,编译成目标代码,汇编代码目标代码 gcc x assembler c gcctest.s -c:只编译不链接,汇编代码目标代码,Linux编程环境,58,编译成目标代码,直接编译成目标代码 gcc c gcctest.c 使用汇编器生成目标代码 as o gcctest.o gcctest.s,直接编译成目标代码,使用汇编器,Linux编程环境,59,编译成执行代码,目标代码执行代码 gcc o gcctest gcctest

31、.o 直接生成执行代码 gcc o gcctest gcctest.c,Linux编程环境,60,gcc的高级选项,-Wall:打开所有的警告信息,Linux编程环境,61,根据警告信息检查源程序,main函数的返回值为int,在函数的末尾应当返回一个值,Linux编程环境,62,修改源程序,Linux编程环境,63,gcc优化编译,优化编译选项 -O0:缺省情况,不优化 -O1:第一级优化 优化取决于目标处理器 通常包括线程跳转(减少跳转次数)、延迟退栈(在嵌套函数调用时推迟退栈时间,直到递归结束) -O2: 包括O1级优化 调整处理器指令执行时序,优化处理器在等待其他指令结果或数据延迟时可

32、执行其他不相关指令 -O3 包括O2级优化 使内嵌函数、循环展开 执行与特定处理器特性相关的优化,Linux编程环境,64,gcc优化编译举例,不同的优化 编译选项,Linux编程环境,65,gcc优化编译举例(续),使用time命令统计程序的运行,Linux编程环境,66,67,GNU binutils简介,是一组二进制工具程序集 addr2line 将程序地址转换为文件名和行号 在命令行中给出地址和可执行文件名,使用可执行文件的调试信息指出对应源文件以及行号 ar 建立、修改、提取归档文件 归档文件结构保证可恢复原始文件内容 as GNU汇编器,主要用来编译gcc输出的汇编文件 将汇编代码

33、转换成目标代码,并放到一个文件 该目标文件将由连接器ld连接 ld 连接器,将目标和归档文件结合起来形成可执行文件 通常,建立一个新编译程序的最后一步就是调用ld,Linux编程环境,68,GNU binutils简介(续),nm 列出目标文件中的符号 objcopy 将一种类型目标文件转换成另一种类型的目标文件 objdump 显示一个或更多目标文件的信息 使用选项来控制其显示的信息 ranlib 产生归档文件索引,并将其保存到这个归档文件中 索引列出归档文件各成员所定义的可重分配目标文件 readelf 显示elf格式可执行文件的信息 size 列出目标文件每一段的大小以及总体的大小,Li

34、nux编程环境,69,ar,用于建立、修改、提取归档文件(archive) 一个归档文件可包含多个文件(也可认为归档文件是一个库文件) 归档文件保存被包含原始文件的内容、权限、时间戳、所有者等属性,在提取后可被还原,Linux编程环境,70,使用ar建立库文件,源程序add.c和minus.c,Linux编程环境,71,使用ar建立库文件(续),编译成目标文件,将库文件拷贝到/usr/lib目录下,ar的rv参数的说明: r:将多个文件组成一个文件 v:输出信息,Linux编程环境,72,调用ar建立的库文件,代码中使用Add和Minus函数,Linux编程环境,73,调用ar建立的库文件(续

35、),在编译时指定库文件,指明将libtest.a链接进来,运行结果,Linux编程环境,74,nm,列出目标文件中的符号 程序员可定位和分析执行程序/目标文件中的符号信息及其属性 显示的符号类型 A:符号的值是绝对值,不会被将来的链接所改变 B:符号位于未初始化数据部分(BSS段) C:符号是公共的 公共符号是未初始化的数据 在链接时,多个公共符号可能以相同的名字出现 如果符号在其他地方被定义,则该文件中的这个符号会被当作引用来处理 D:符号位于已初始化的数据部分(data段) T:符号位于代码部分(text段) U:符号未被定义 ?:符号类型未知或目标文件格式特殊,Linux编程环境,75,

36、nm使用举例,Linux编程环境,76,objcopy,将一种格式文件生成另一种格式文件,使用file命令查看文件类型,生成srec格式的目标文件,使用file命令查看新文件的类型,Linux编程环境,77,Linux的可执行文件格式,a.out格式(assembler and link editor output) 早期UNIX系统使用的可执行文件格式 文件头部结构定义(include/asm-x86/a.out.h) 现在基本被ELF文件格式代替 COFF格式(Common Object File Format) 包括文件头、可选头部及一些节(section) .text, .data和.

37、bss区段各有一个小节,还可包含其他区段 一个可选头部,对不同操作系统作特定定义 文件定义位置:include/linux/coff.h ELF格式(Executable and Linking Format) 代码、链接和注释都以段存在,节点表(Section Header Table)有一个表项与每个小节对应 文件类型:.o目标文件、.so动态库文件、可执行文件 ELF格式可以比COFF格式包含更多的调试信息 SREC MOTOROLA S-Recoder格式(S记录格式文件),Linux编程环境,78,objdump,显示一个或多个目标文件的信息 由相应选项控制显示哪些信息 可通过该工具

38、查看执行文件或库文件的信息 objdump对编写编译工具、分析代码执行机制非常有用,Linux编程环境,79,objdump使用举例,-f选项:显示文件头内容,Linux编程环境,80,objdump使用举例(续),-d选项进行反汇编,Linux编程环境,81,readelf,显示一个或多个ELF格式的目标文件信息,Linux编程环境,82,GNU gdb,gdb = GNU debuger 设置断点 监视、修改变量 单步执行 显示/修改寄存器的值 查看堆栈 远程调试,Linux编程环境,83,gdb常用命令,Linux编程环境,84,gdb使用举例,源代码如下,编译: gcc o bug b

39、ug.c,Linux编程环境,85,gdb使用举例,编译并运行,?,编译,Linux编程环境,86,使用gdb调试bug,运行bug,输入字符串hello,显示出错位置,能不能看到源代码呢?,Linux编程环境,87,使用gcc的-g参数,gcc g o bug bug.c -g:在可执行程序中包含标准调试信息 重新调试,列出源代码,Linux编程环境,88,使用gcc的-g参数,?怎么修改前面的源代码呢?,设置断点,Linux编程环境,89,主要内容,Linux简介 Linux内核环境 Linux编程环境 GNU make管理项目 Linux的程序执行机制,90,GNU make,代码维护工

40、具,使用GNU编译开发大型应用时常需要使用make管理项目 避免重复使用多个复杂命令行维护项目和生成目标代码 make通过将命令行保存到Makefile中简化编译工作 make根据Makefile中定义的规则和步骤及各个模块的更新情况,自动完成整个软件项目的维护和代码生成工作 make可识别Makefile中的被修改文件,并在再次编译的时候只编译这些文件,从而提高编译的效率 make会检查文件的修改和生成时间戳 如果目标文件的修改或者生成时间戳比它的任意一个依赖文件旧,则make就执行makefile文件中描述的相应命令,以便更新目的文件,Linux make管理项目,91,GNU make特

41、点,适合于支持多文件构成的大中型软件项目的编译、链接、清除中间文件等管理工作 提供和识别多种默认规则,方便对大型软件项目的管理 支持对多目录的软件项目进行递归管理 对软件项目具有很好的可维护性和扩展性,Linux make管理项目,92,Makefile,Makefile被make读取 Makefile主要工作 定义依赖关系 生成目标文件所依赖的文件列表 需要用什么命令来产生目标文件的最新版本 定义编译、链接等相关参数,Linux make管理项目,93,Makefile的规则,规则内容 要创建的目标(文件) 创建目标(文件)所依赖的文件列表 通过依赖文件创建目标文件的命令组 规则一般形式 t

42、arget . : prerequisites . command . .,规则,依赖性,操作命令,gcc c main.c,main.o: main.c sum.h,tab,目标,Linux make管理项目,94,简单Makefile示例,edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o main.o : main.c defs.h cc

43、-c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h co

44、mmand.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o,Linux make管理项目,95,make的工作过程,缺省情况下从Makefile中的第一个目标开始执行 执行过程类似一次深度优先遍历,sum: main.o sum.o gcc o sum main.o sum.o main.o: main.c sum.h gcc c main.c sum.o: sum.c

45、 sum.h gcc c sum.c,Linux make管理项目,96,默认依赖规则说明,.o依赖于相应的.c文件,sum: main.o sum.o gcc o sum main.o sum.o main.o: main.c sum.h gcc c main.c sum.o: sum.c sum.h gcc c sum.c,sum: main.o sum.o gcc o sum main.o sum.o main.o: sum.h gcc c main.c sum.o: sum.h gcc c sum.c,Linux make管理项目,97,Makefile中的变量,变量功能 降低错误风险

46、,简化Makefile 贮存一个文件名列表 贮存可执行文件名 贮存编译器标志参数 变量使用示例:objects变量($(objects)) objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o edit: $(objects) cc -o edit $(objects),Linux make管理项目,98,预定义变量,make可直接使用许多预定义的变量 AR:归档维护程序的名称,默认值为 ar ARFLAGS:归档维护程序的选项 AS:汇编程序的名称,默认值为 as ASFLAGS:汇编程序的选

47、项 CC:C 编译器的名称,默认值为 cc CFLAGS:C 编译器的选项 CXX:C+ 编译器的名称,默认值为 g+ CPPFLAGS:C 预编译的选项 系统环境变量的处理 make 过程中被解释成make变量,Linux make管理项目,99,简化后Makefile文件,objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : defs.h kbd.o : defs.h command.h com

48、mand.o : defs.h command.h display.o : defs.h buffer.h insert.o : defs.h buffer.h search.o : defs.h buffer.h files.o : defs.h buffer.h command.h utils.o : defs.h .PHONY : clean clean : rm edit $(objects),Linux make管理项目,100,内部变量,$:目标文件的完整名称 $*:不包含扩展名的目标文件名称 $:依赖列表中的第一个依赖文件 $+:所有的依赖文件 以空格分开,并以出现的先后为序,可

49、能包含重复的依赖文件 $:整个依赖列表(除去所有重复的文件名) $? :所有的依赖文件 以空格分开,这些依赖文件的修改日期比目标的创建日期晚 $%:若目标是归档成员,则该变量表示目标的归档成员名 例如,如果目标名称为 mytarget.so(image.o) $ 为 mytarget.so $% 为 image.o 举例 CC = gccCFLAGS = -Wall -O -g foo.o : foo.c foo.h bar.h$(CC) $(CFLAGS) -c $ -o $,Linux make管理项目,101,隐式规则 (Implicit Rules),也称预定义规则 告诉make在没有

50、给出某些命令的时候如何处理 举例 objects = main.o kbd.o command.o utils.o edit: $(objects) cc -o edit $(objects) 问题:没有定义如何编译生成这些目标的规则 对名为somefile.o的目标文件,make首先找与之对应的源代码somefile.c,并用gcc c somefile.c o somefile.o编译生成目标代码 注意 若在工作目录下有对应的somefile.p文件,make会激活pascal编译器工作 可使用预定义变量改变隐含规则的工作方式,如 $(CC) $(CFLAGS) $(CPPFLAGS) $

51、(TARGET_ARCH) -c $ -o $,Linux make管理项目,102,扩展make隐式规则的方法 类似于普通规则,但目标必定含有符号% 该符号可与任何非空字符串匹配 为与目标中的”%”匹配,该规则关联的相关文件部分也必须使用”%” 举例 %.o : %.c make从somefile.c文件为所有形为somefile.o的文件somefile.o目标 make定义的模式规则 %.o : %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $ -o $,103,模式规则,Linux make管理项目,104,伪目标PHONY,不对应

52、于实际的文件,目标体规定make执行的命令 clean: $rm *.o exec_file 由于目标体clean没有依赖体,make认为其是最新的而不执行任何操作,因此它将永远不会被执行 若需执行,需显式执行命令 make clean 解决方法:. PHONY PHONY的依赖体文件的含义与通常一样 make不检查是否存在有文件名与依赖体中的一个名字相匹配的文件,而直接执行与之相应的命令 .PHONY: clean clean: $rm *.o exec_file,Linux make管理项目,PHONY目标也可以有依赖关系 当一个目录中有多个程序,将其放在一个makefile 中会更方便

53、因为缺省目标是makefile 中的第一个目标,通常将这个phony 目标叫做all,其依赖文件为各个程序 all : prog1 prog2 prog3.PHONY: allprog1 : prog1.o utils.occ -o prog1 prog1.o utils.oprog2 : prog2.occ -o prog2 prog2.oprog3 : prog3.o sort.o utils.occ -o prog3 prog3.o sort.o utils.o,105,伪目标PHONY(续),Linux make管理项目,106,Makefile中的函数,计算待操作的文件、目标或待执行

54、的命令 使用方法 $(function arguments) 典型函数 $(subst from, to, text) :替换字符串 $(subst ee, EE, feet on the street) 相当于fEEt on the strEEt $(patsubst pattern, replacement, text) $(patsubst %.c,%.o, x.c.c bar.c) 相当于x.c.o bar.o $(wildcard pattern) :列出当前目录下所有符合模式pattern格式的文件名 $(wildcard *.c) objects := $(wildcard *.

55、o),Linux make管理项目,107,Makefile中的条件语句,四种条件语句 ifeq.else.endif ifneqelseendif ifdefelseendif ifndef.elseendif,conditional-directive text-if-true endif 或 conditional-directive text-if-true else text-if-false endif,Linux make管理项目,108,带条件的makefile举例,sum: main.o sum.o gcc o sum main.o sum.o main.o: main.c

56、sum.h gcc c main.c #deciding which file to compile to create sum.o ifeq ($(USE_SUM), 1) sum.o: sum1.c sum.h gcc c sum1.c o $ else sum.o: sum2.c sum.h gcc c sum2.c o $ endif,Linux make管理项目,109,可移植GNU 包的典型安装方法,下载源代码包foo-1.0.tar.gz tar xvzf foo-1.0.tar.gz cd foo-1.0 ./configure make (su) make install,问

57、题1:配置脚configure是如何生成的?,问题2:configure脚本怎么知道该如何生成Makefile?,幕后英雄:GNU Auto 工具 autoconf, automake, libtool, autoscan, autoheader,Linux make管理项目,110,autoconf框架图,autoscan,configure.scan,configure.in,Makefile.am,Makefile.in,Makefile,automake,edit,aclocal.m4,aclocal,configure,autoconf,Src code,autoscan,./con

58、figure,Linux make管理项目,autoheader,为软件包创建configure. scan文件 从源文件中抽取与函数调用和头文件相关的信息,并为相应包创建一个 configure.scan文件(configure.in前身) autoscan在以命令行参数中指定的目录为根(如果未给定参数,则以当前目录为根)的目录树中检查源文件 基于perl语言实现,111,autoconf流程 autoscan,./configure,Linux make管理项目,autoheader,configure.scan示例,112,autoconf流程 autoscan(续),AC_PREREQ

59、(2.64) /表明文件所需要的autoscan版本#AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_INIT(hello, 1.0, ) #侦测所指定源代码文件是否存在,来确定源代码目录的有效性 AC_CONFIG_SRCDIR(helloworld.c) #用来生成config.h文件,以便autoheader使用 AC_CONFIG_HEADERS(config.h) #指定编译器,如果不指定,选用默认gcc AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT(Makefile ),Linux

温馨提示

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

评论

0/150

提交评论