540 likes | 713 Views
Linux 操作系统 开发. 周炯 上海艾基信息技术有限公司. 内容提要. 使用 gcc 使用 Gnu ’ s make 管理项目 使用 autoconf 创建自配置软件 比较和归并源文件 使用 RCS 进行版本控制. 一、使用 gcc. 1 gcc 特性 2 使用简介 3 常用命令行选项. 1 gcc 特性. 编译过程 预处理、编译、链接 支持风格 ANSI C 、 C++ 、 Objective C 调试信息 能够在生成调试信息同时进行优化 交叉编译 大量扩展(降低可移植性). 2 使用简介.
E N D
Linux操作系统开发 周炯 上海艾基信息技术有限公司 Acegene IT Co. Ltd.
内容提要 • 使用gcc • 使用Gnu’s make管理项目 • 使用autoconf创建自配置软件 • 比较和归并源文件 • 使用RCS进行版本控制 Acegene IT Co. Ltd.
一、使用gcc • 1 gcc特性 • 2 使用简介 • 3 常用命令行选项 Acegene IT Co. Ltd.
1 gcc特性 • 编译过程 • 预处理、编译、链接 • 支持风格 • ANSI C、C++、Objective C • 调试信息 • 能够在生成调试信息同时进行优化 • 交叉编译 • 大量扩展(降低可移植性) Acegene IT Co. Ltd.
2 使用简介 • #include <stdio.h>int main(void){ fprintf(stdout,”Hello World!\n”); return 0;} • gcc hello.c –o hello • ./hello Acegene IT Co. Ltd.
2 使用简介 • 过程: • cpp预处理所有的宏、展开头文件 • 编译为目标代码 • 使用ld链接成二进制文件 • gcc -E hello.c -o hello.cpp • gcc -x cpp-output -c hello.cpp hello.o • gcc hello.o -o hello • gcc test2.c test.c -o test Acegene IT Co. Ltd.
2 使用简介 • 常用扩展名解释 • .c c语言源代码 • .C,.cc c++源代码 • .i 预处理后的c源代码 • .ii 预处理后的c++源代码 • .S,.s 汇编语言源代码 • .o 汇编后的目标代码 • .a,.so 库代码 Acegene IT Co. Ltd.
3 常用命令行选项 • -o FILE 指定输出文件名,未指定a.out • -c 只编译,不链接 • -DFOO=BAR 定义预处理宏 • -IDIR 将DIR指定的目录添加到头文件搜索路径中 • -LDIR 将DIR加入到库文件的搜索目录列表中,缺省情况下gcc只链接共享库 • -static 链接静态库 • -lFOO 链接名为FOO的函数库,如-lmath Acegene IT Co. Ltd.
3 常用命令行选项 • -g 在可执行文件中包含调试信息 • -ggdb 在可执行程序中包含只有GNU debugger才能识别的大量调试信息 • -p 加入prof能够识别的统计信息 • -ON 编译时进行优化(N为优化级别) • -w 关闭所有警告 • -Wall 发出所有gcc能提供的警告 • -werror 将警告转化为错误,中止编译 • -v 显示每一步详细信息 Acegene IT Co. Ltd.
二、使用Gnu’s make管理项目 • 为何使用make • 编写makefile • 深入了解makefile • 额外的make命令行选项 • 调试make • 常见错误 • 常用的makefile目标 Acegene IT Co. Ltd.
1为何使用make • 包含多个源文件的项目在编译时有长而复杂的命令行,可以通过makefile保存这些命令行来简化该工作 • make可以减少重新编译所需要的时间,因为make可以识别出哪些文件是新修改的 • Make维护了当前项目中各文件的相关关系,从而可以在编译前检查是否可以找到所有的文件 Acegene IT Co. Ltd.
2 编写makefile • makefile:一个文本形式的文件,其中包含一些规则告诉make编译哪些文件以及怎样编译这些文件,每条规则包含以下内容: • 一个target,即最终创建的东西 • 一个和多个dependencies列表,通常是编译目标文件所需要的其他文件 • 需要执行的一系列commands,用于从指定的相关文件创建目标文件 Acegene IT Co. Ltd.
2 编写makefile • make执行时按顺序查找名为GNUmakefile,makefile或者Makefile文件,通常,大多数人常用Makefile • Makefile规则: • target: dependency dependency [..] command command [..] • 注意:command前面必须是制表符 Acegene IT Co. Ltd.
2 编写makefile • 例子: editor: editor.o screen.o keyboard.o gcc -o editor editor.o screen.o keyboard.o editor.o : editor.c editor.h keyboard.h screen.h gcc -c editor.c screen.o: screen.c screen.h gcc -c screen.c keyboard.o : keyboard.c keyboard.h gcc -c keyboard.c clean: rm editor *.o Acegene IT Co. Ltd.
3 深入了解makefile • 伪目标:如上例中的clean • 变量: • 声明 VARNAME=sometext [..] • 使用 $(VARNAME) • 递归展开变量,如TOPDIR=/home/young, SRCDIR=$(TOPDIR)/src,则SRCDIR=/home/young/src • make可以检测到错误的递归展开,如CC = gcc CC=$(CC) –o • 解决方案 CC:=gcc -o CC+= -O2 Acegene IT Co. Ltd.
例子 • OBJS = editor.o screen.o keyboard.o • HDRS = editor.h screen.h keyboard.h • editor: $(OBJS) • gcc -o editor $(OBJS) • editor.o : editor.c $(HDRS) • gcc -c editor.c • screen.o: screen.c screen.h • gcc -c screen.c • keyboard.o : keyboard.c keyboard.h • gcc -c keyboard.c • clean: • rm editor $(OBJS) Acegene IT Co. Ltd.
3 深入了解makefile • 环境变量:make会自动读取环境变量并使用 • 自动变量: • $@ 规则的目标对应的文件名 • $< 规则中的第一个相关文件名 • $^ 规则中的所有相关文件的列表 • $? 规则中日期新于目标的所有相关文件的列表 • $(@D) 目标文件的目录部分(如果目标在子目录中) • $(@F) 目标文件的文件名部分 Acegene IT Co. Ltd.
3 深入了解makefile • 预定义变量: • AR 归档维护程序 ar • AS 汇编程序 as • CC C编译程序 cc • CPP C预处理程序 cpp • RM 文件删除程序 rm –f • ARFLAGS ASFLAGS CPPFLAGS LDFLAGS Acegene IT Co. Ltd.
3 深入了解makefile • 隐式规则 OBJS = editor.o screen.o keyboard.o editor: $(OBJS) gcc -o editor $(OBJS) clean: rm editor $(OBJS) • 模式规则 %.o:%.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ Acegene IT Co. Ltd.
3 深入了解makefile • 添加注释:行首加#符号 • 额外make命令行参数 • -f file 指定makefile的文件名 • -n 打印要执行的命令但不实际执行 • -r 禁止使用所有make的内置规则 • -d 打印调试信息 • -k 某个编译目标失败,继续编译其他目标 Acegene IT Co. Ltd.
4 调试make • 使用-d参数 • 输出信息: • 重新编译时需要比较的文件 • 被比较文件以及比较结果 • 需要被重新生成的文件 • make想要使用的隐含规则 • make实际使用的隐含规则以及所执行的命令 Acegene IT Co. Ltd.
5 常见的make出错信息 • No rule to make target ‘target’. Stop • ‘target’ is up to date • Target ‘target’ not remake because of errors (-k参数) • command: Command not found • Illegal option - option Acegene IT Co. Ltd.
6 有用的makefile目标 • install 目标安装 • dist 生成准备发布的软件包,删除编译工作目录中的旧的二进制文件和目标文件并创建一个归档文件 • distclean • uninstall • test或者check 诊断安装包 • installtest或installcheck Acegene IT Co. Ltd.
三、使用autoconf创建自配置软件 • 开发在不同UNIX和类UNIX上都可以运行的软件: • 代码需要可移植 • 开发者必须对不同系统的编译和运行环境,甚至是硬件体系结构有足够的了解 • 使用autoconf可以生成一个自动配置源代码包的shell脚本,以使程序能够在许多不同品牌的UNIX和类UNIX上编译和运行。这个脚本通常叫做configure,它检查在当前系统中是否提供程序所需要的某些功能,并在此基础上生成makefile。 Acegene IT Co. Ltd.
四、比较和归并源文件 • 1 比较文件 • 2 生成补丁 Acegene IT Co. Ltd.
1 比较文件 • cmp命令 • diff 命令 • diff3 命令 • sdiff 命令 Acegene IT Co. Ltd.
cmp命令 • cmp [options] file1 file2 • 比较两个文件,给出差别字符的位置和行号。同时可以设置选项使得cmp给出结果时同时显示差别字符。 • -c 显示第一个差别字符 • -l 以十进制显示差别字符的位置,并以八进制显示其数值 Acegene IT Co. Ltd.
diff命令 • diff [options] file1 file2 • 普通输出格式: • 仅按序显示差别行 • 上下文输出格式:-C • 以一些行作为上下文(上下文hunk)来显示差别行,以便用户更清楚地知道所比较文件的差别。 • 统一输出格式:-U • 修改了上下文格式,取消了重复的上下文并简化了输出。 Acegene IT Co. Ltd.
diff3 命令 • 两个人同时修改了一个公用文件的情况下,使用diff3命令,可以比较两个文件对一个源文件的修改,并把结果合并在一个输出文件中,用以指出两个文件对源文件所作的修改的冲突之处。 • diff3 [options] myfile oldfile yourfile Acegene IT Co. Ltd.
sdiff 命令 • 使用交互方式来合并文件,并以逐字格式显示文件。使用交互特性时,应在命令行使用-o file选项指定输出文件,在执行时,sdiff显示每一个hunk,并在其后输出提示符%,此时键入所需要的命令,然后回车,可用的命令如下: • l 把左边的列复制到输出文件 • r 把右边的列复制到输出文件 • el 先编辑左边的列,然后复制 • er 先编辑右边的列,然后复制 • e 放弃左右两列,输入新文本,然后把新文本复制到输出文件 • eb 链接左右两列并进行修改,然后把结果复制到输出文件 • q 退出 Acegene IT Co. Ltd.
2 准备补丁 • 创建补丁: • diff -c sigrot.1 sigrot.2 > sigrot.patch • diff -u sigrot.1 sigrot.2 > sigrot.patch • 使用-r参数来遍历目录 • patch -p0 < sigrot.patch • p0 表示指定使用补丁前补丁中所包含的文件名中需要剥离的”/”的重数,-p则剥离了除最终文件名之外的所有部分。 • 恢复:patch -p0 -R < sigrot.patch Acegene IT Co. Ltd.
使用RCS进行版本控制 • 什么是版本控制 • 为什么需要版本控制 • RCS和CVS • 术语 • 基本用法 • RCS关键字 Acegene IT Co. Ltd.
什么是版本控制 • 跟踪和管理文件变化的自动过程 • RCS (Revision Control System)修改控制系统 • 其他类似的GNU软件 • SCCS Source Code Control System • CVS Concurrent Version System Acegene IT Co. Ltd.
为什么需要版本控制 • 1 也许有一天你对源代码做了关键改动,删除了老的文件并且忘记了所作改动的确切位置 • 2 同时跟踪关于当前版本,下一版本以及修改过的错误的情况等信息是冗长并且容易出错的事情 • 3 也许你的同事不经意间修改了你的代码,会使得你不得不在备份磁带上疯狂查找以找回合适的版本 Acegene IT Co. Ltd.
RCS和CVS • CVS建立在RCS的基础上,新增了两个特性: • 1 CVS比RCS更适合于管理多目录的服务,因为它处理层次目录结构时比RCS简单,同时它对于项目的概念也更加完整,可以认为,RCS是面向文件的,而CVS则面向项目 • 2 支持分布式项目的开发,多个开发者可以在不同的地点或者Internet上共同开发一个项目,他们所存取和操作的是一个单独的代码库。其成功例子:KDE和Debian的Linux版本 Acegene IT Co. Ltd.
术语 • RCS Files: 在RCS目录下的文件,由RCS控制,并通过RCS命令存取。一个RCS文件包含某一特殊文件的所有版本。通常,RCS文件的扩展名是,v • Working file: 从RCS源代码库(即RCS目录)中检索到的一个或者多个文件,放置在当前工作目录下,并能够被编辑 Acegene IT Co. Ltd.
术语 • Lock: 以编辑目的取回工作文件时别人就不能同时编辑这个文件。此时,文件由第一个编辑它的人锁定 • Revision: 源文件的一个特定版本,用数字标识。Revision的编号从1.1开始,并依次递增,除非强制指定修订版本号 • RCS自动处理各版本的存储、检索、更改日志、存取控制、发行管理、修订标识和合并;并且,由于它只跟踪文件的变化,所以只需要最小的空间。 Acegene IT Co. Ltd.
基本用法 • ci : Check In • co : Check Out • mkdir RCS • ci howdy.c 建立一个RCS文件,名为howdy.c,v,将版本号设置为1.1,并要求输入描述 • co howdy.c 将howdy.c文件从最新的版本中取出,存为工作文件,如果想修改文件,必须使用co -l howdy.c,将其锁定。 • 编辑完之后,如果想知道做了什么改动,有什么区别,可以使用rcsdiff howdy.c • 遇到无法锁定的情况,可以使用rcs -l howdy.c来获得锁。 Acegene IT Co. Ltd.
基本用法 • 如果是单用户使用,可以使用rcs -U howdy.c来关闭锁机制,用rcs -L howdy.c 来打开锁机制。 • 如果你想把文件变成RCS文件,但是又不想工作文件被删除,使用: • ci -l f.c 或者 ci -u f.c • 前者执行之后用户仍拥有锁,而后者执行后用户不再有锁(也就是,不可写)。 Acegene IT Co. Ltd.
基本用法 • 其他参数 • -r 指定需要获取的版本号 • -f 强制RCS覆盖当前的工作文件 • 如果你想把当前的版本号改变,使用 • ci -r2 howdy.c 或者 ci -r2.1 howdy.c • 将使用新的版本号。以后的版本将自动使用2.2, 2.3... • 如果不强调 -r,总是取出当前版本号最大的版本。 • 如果check in 时使用 ci -r1.3.1, 则新版本号会是 1.3.1.1 • 关于分支,使用 rcsfile Acegene IT Co. Ltd.
基本用法 • ident :可以在所有类型的文件中定位RCS关键字(形如$KEYWORD:VALUE$的字符串,不一定非得是RCS关键字),开发人员利用这个特性就能找出程序的特定发行版本中所使用的各个模块的版本号或者其他附加信息。 • 在模块中内嵌信息是一种有用的手段,因为这样就可以把特定的问题定位到特定的代码模块。 Acegene IT Co. Ltd.
基本用法 • rcsdiff -rVer1 -rVer2 Filename • rlog Filename 打印日志消息和其他信息 • rlog –R只显示文件名 -L 列出被加锁的文件 -l 列出被某个指定用户加锁的文件 • rcsmerge 可以合并多个版本,生成一个单独的工作文件 • rcsmerge -rAncestor -rDescendant Working_file -p > Merged_file Acegene IT Co. Ltd.
基本用法 • rcs 用于两种情形: • 如果以只读方式取出文件后做修改,并且想保存结果,此时可以使用rcs -l Filename,取出该文件,并加锁,同时不覆盖现有的同名文件。 • 如果需要打开其他人对文件的加锁,可以使用rcs -u filename,此时文件被解锁,并且原来的加锁者将受到一条解释信息。 • 此外:rcs -mrev:msg可以修改某个版本的描述信息 Acegene IT Co. Ltd.
基本用法 • rcsclean 清除RCS文件,基本用法为rcsclean [options] file1 file2 … • 不加任何选项的rcsclean删除哪些在取出后没有更改的工作文件 • -u 选项可以先解锁所有已经加锁的文件,然后再删除没有更改的那些工作文件。使用-rM.N可以删除指定的版本,例如:rcsclean –r2.3 howdy.c将删除howdy.c的2.3版 Acegene IT Co. Ltd.
RCS关键字 • $Id$ • $Log$ 日志消息,RCS是在先前的日志消息上面插入新的消息,而不是用最新的消息取代以前的消息 • $Author$ 存入该版本的用户登录名 • $Date$ 该版本存入的日期和时间,使用UTC格式 • $Header$ RCS文件的全路径名,版本号,日期,时间,作者,状态,加锁者(在文件被加锁的情形下) Acegene IT Co. Ltd.
RCS关键字 • $Locker$ 锁定该版本的使用者的登陆名 • $Name$ 用于取回该版本的符号名 • $RCSfile$ 不包含路径的RCS文件名 • $Revision$ 该版本的版本号 • $Source$ RCS文件的全路径名 • $State$ 版本的状态:Exp(试验版本)、Stab(稳定版本)、Rel(发行版本),缺省为Exp Acegene IT Co. Ltd.
ABI Compatibility • What is Application Binary Interface • Runtime compatibility mechanism • Allows for an upgrade option on components so long as the “binary” interface is maintained • If “binary” interface changed then ABI is said to have “changed” losing compatibility Acegene IT Co. Ltd.
ABI Illustration #define ARRAY_SIZE 8 struct my_struct { int array[ARRAY_SIZE]; }; init_struct( struct my_struct *p ) { memset( p, 0, sizeof(struct mystruct); } Acegene IT Co. Ltd.
Glibc Compatibility • Usually only affected by 2nd-digit change • e.g., glibc-2.1 glibc-2.2 • Symbols are versioned to provide executable binary compatibility • Does NOT provide link time compatibility • Must link against the same version of glibc that objects were compiled against • Since Oracle links at the customer site, we get around this by using glibc stubs for linking Acegene IT Co. Ltd.
Gcc C++ Compatibility • C++ ABI has changed between 2.96 and 3.2 • C++ on Linux now closer to ISO standard • C++ programs built with gcc-2.96 will not run with runtime libraries from gcc-3.2 • compatibility package ??? Acegene IT Co. Ltd.