Linux 操作 系统 开发
周炯 上海艾基信 息技术有限 公司
Acegene IT Co. Ltd.
1
内容提 要 • 使用 gcc • 使用 Gnu’s make 管理项目 • 使用 autoconf 创建自配置软件 • 比较和归并源文件 • 使用 RCS 进行版本控制
Acegene IT Co. Ltd.
2
一、使 用 gcc • 1 gcc 特性 • 2 使用简介 • 3 常用命令行选项
Acegene IT Co. Ltd.
3
1 gcc 特性 • 编译过程 – 预处理、编译、链接
• 支持风格 – ANSI C 、 C++ 、 Objective C
• 调试信息 – 能够在生成调试信息同时进行优化
• 交叉编译 • 大量扩展(降低可移植性)
Acegene IT Co. Ltd.
4
2 使用简 介 • #include <stdio.h> int main(void) { fprintf(stdout,”Hello World!\n”); return 0; } • gcc hello.c –o hello • ./hello
Acegene IT Co. Ltd.
5
2 使用简 介 • 过程: – cpp 预处理所有的宏、展开头文件 – 编译为目标代码 – 使用 ld 链接成二进制文件
• gcc • gcc • gcc • gcc
-E hello.c -o hello.cpp -x cpp-output -c hello.cpp hello.o hello.o -o hello test2.c test.c -o test
Acegene IT Co. Ltd.
6
2 使用简 介 • 常用扩展名解释 • .c c 语言源代码 • .C,.cc c++ 源代码 • .i 预处理后的 c 源代码 • .ii 预处理后的 c++ 源代码 • .S,.s 汇编语言源代码 • .o 汇编后的目标代码 • .a,.so 库代码
Acegene IT Co. Ltd.
7
3 常用命 令行选项 • • • •
-o FILE 指定输出文件名,未指定 a.out -c 只编译,不链接 -DFOO=BAR 定义预处理宏 -IDIR 将 DIR 指定的目录添加到头文件搜索路 径中 • -LDIR 将 DIR 加入到库文件的搜索目录列表中 ,缺省情况下 gcc 只链接共享库 • -static 链接静态库 • -lFOO 链接名为 FOO 的函数库,如 -lmath
Acegene IT Co. Ltd.
8
3 常用命 令行选项 • -g 在可执行文件中包含调试信息 • -ggdb 在可执行程序中包含只有 GNU debugger 才能识别的大量调试信息 • -p 加入 prof 能够识别的统计信息 • -ON 编译时进行优化 (N 为优化级别 ) • -w 关闭所有警告 • -Wall 发出所有 gcc 能提供的警告 • -werror 将警告转化为错误,中止编译 • -v 显示每一步详细信息 Acegene IT Co. Ltd.
9
二、使 用 Gnu’s make 管理项 目 • 为何使用 make • 编写 makefile • 深入了解 makefile • 额外的 make 命令行选项 • 调试 make • 常见错误 • 常用的 makefile 目标
Acegene IT Co. Ltd.
10
1 为何使 用 make • 包含多个源文件的项目在编译时有长而复 杂的命令行,可以通过 makefile 保存这些 命令行来简化该工作 • make 可以减少重新编译所需要的时间, 因为 make 可以识别出哪些文件是新修改 的 • Make 维护了当前项目中各文件的相关关系 ,从而可以在编译前检查是否可以找到所 有的文件 Acegene IT Co. Ltd.
11
2 编写 makefile • makefile :一个文本形式的文件,其中包 含一些规则告诉 make 编译哪些文件以及 怎样编译这些文件,每条规则包含以下内 容: – 一个 target ,即最终创建的东西 – 一个和多个 dependencies 列表,通常是编译 目标文件所需要的其他文件 – 需要执行的一系列 commands ,用于从指定 的相关文件创建目标文件
Acegene IT Co. Ltd.
12
2 编写 makefile • make 执行时按顺序查找名为 GNUmakefile , makefile 或者 Makefile 文件,通常,大多数人常用 Makefile • Makefile 规则: • target: dependency dependency [..] command command [..] • 注意: command 前面必须是制表符
Acegene IT Co. Ltd.
13
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.
14
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.
15
例子 • • • • • • • • • •
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.
16
3 深入了 解 makefile • • • • • • •
环境变量: make 会自动读取环境变量并使用 自动变量: $@ 规则的目标对应的文件名 $< 规则中的第一个相关文件名 $^ 规则中的所有相关文件的列表 $? 规则中日期新于目标的所有相关文件的列表 $(@D) 目标文件的目录部分(如果目标在子目 录中) • $(@F) 目标文件的文件名部分 Acegene IT Co. Ltd.
17
3 深入了 解 makefile • 预定义变量: • AR 归档维护程序 ar • AS 汇编程序 as • CC C 编译程序 cc • CPP C 预处理程序 cpp • RM 文件删除程序 rm –f • ARFLAGS ASFLAGS CPPFLAGS LDFLAGS
Acegene IT Co. Ltd.
18
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.
19
3 深入了 解 makefile • 添加注释:行首加 # 符号 • 额外 make 命令行参数 • -f file 指定 makefile 的文件名 • -n 打印要执行的命令但不实际执行 • -r 禁止使用所有 make 的内置规则 • -d 打印调试信息 • -k 某个编译目标失败,继续编译其他目标
Acegene IT Co. Ltd.
20
4 调试 make • 使用 -d 参数 • 输出信息: – 重新编译时需要比较的文件 – 被比较文件以及比较结果 – 需要被重新生成的文件 – make 想要使用的隐含规则 – make 实际使用的隐含规则以及所执行的命令
Acegene IT Co. Ltd.
21
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.
22
6 有用的 makefile 目标 • install 目标安装 • dist 生成准备发布的软件包,删除编译工 作目录中的旧的二进制文件和目标文件并 创建一个归档文件 • distclean • uninstall • test 或者 check 诊断安装包 • installtest 或 installcheck
Acegene IT Co. Ltd.
23
三、使 用 autoconf 创建自 配置软件 • 开发在不同 UNIX 和类 UNIX 上都可以运 行的软件: – 代码需要可移植 – 开发者必须对不同系统的编译和运行环境,甚 至是硬件体系结构有足够的了解
• 使用 autoconf 可以生成一个自动配置源代 码包的 shell 脚本,以使程序能够在许多不 同品牌的 UNIX 和类 UNIX 上编译和运行。 这个脚本通常叫做 configure ,它检查在 当前系统中是否提供程序所需要的某些功 能,并在此基础上生成 makefile 。 Acegene IT Co. Ltd.
24
四、比 较和归并 源文件 • 1 比较文件 • 2 生成补丁
Acegene IT Co. Ltd.
25
1 比较文 件 • cmp 命令 • diff 命令 • diff3 命令 • sdiff 命令
Acegene IT Co. Ltd.
26
cmp 命令 • cmp [options] file1 file2 • 比较两个文件,给出差别字符的位置和行 号。同时可以设置选项使得 cmp 给出结果 时同时显示差别字符。 • -c 显示第一个差别字符 • -l 以十进制显示差别字符的位置,并以八 进制显示其数值
Acegene IT Co. Ltd.
27
diff 命令 • diff [options] file1 file2 • 普通输出格式: – 仅按序显示差别行
• 上下文输出格式: -C – 以一些行作为上下文(上下文 hunk )来显示 差别行,以便用户更清楚地知道所比较文件的 差别。
• 统一输出格式: -U – 修改了上下文格式,取消了重复的上下文并简 化了输出。 Acegene IT Co. Ltd.
28
diff3 命令 • 两个人同时修改了一个公用文件的情况下 ,使用 diff3 命令,可以比较两个文件对一 个源文件的修改,并把结果合并在一个输 出文件中,用以指出两个文件对源文件所 作的修改的冲突之处。 • diff3 [options] myfile oldfile yourfile
Acegene IT Co. Ltd.
29
sdiff 命令 • 使用交互方式来合并文件,并以逐字格式显示文 件。使用交互特性时,应在命令行使用 -o file 选 项指定输出文件,在执行时, sdiff 显示每一个 hunk ,并在其后输出提示符 % ,此时键入所需 要的命令,然后回车,可用的命令如下: – – – – –
l 把左边的列复制到输出文件 r 把右边的列复制到输出文件 el 先编辑左边的列,然后复制 er 先编辑右边的列,然后复制 e 放弃左右两列,输入新文本,然后把新文本复制到 输出文件 – eb 链接左右两列并进行修改,然后把结果复制到输出 文件 – q 退出 Acegene IT Co. Ltd.
30
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.
31
使用 RCS 进行版本控制 • 什么是版本控制 • 为什么需要版本控制 • RCS 和 CVS • 术语 • 基本用法 • RCS 关键字
Acegene IT Co. Ltd.
32
什么是 版本控制 • 跟踪和管理文件变化的自动过程 • RCS (Revision Control System) 修改控制系统 • 其他类似的 GNU 软件 – SCCS Source Code Control System – CVS Concurrent Version System
Acegene IT Co. Ltd.
33
为什么 需要版本 控制 • 1 也许有一天你对源代码做了关键改动, 删除了老的文件并且忘记了所作改动的确 切位置 • 2 同时跟踪关于当前版本,下一版本以及 修改过的错误的情况等信息是冗长并且容 易出错的事情 • 3 也许你的同事不经意间修改了你的代码 ,会使得你不得不在备份磁带上疯狂查找 以找回合适的版本
Acegene IT Co. Ltd.
34
RCS 和 CVS • CVS 建立在 RCS 的基础上,新增了两个特性: – 1 CVS 比 RCS 更适合于管理多目录的服务,因为它处 理层次目录结构时比 RCS 简单,同时它对于项目的概 念也更加完整,可以认为, RCS 是面向文件的,而 CVS 则面向项目 – 2 支持分布式项目的开发,多个开发者可以在不同的 地点或者 Internet 上共同开发一个项目,他们所存取 和操作的是一个单独的代码库。其成功例子: KDE 和 Debian 的 Linux 版本
Acegene IT Co. Ltd.
35
术语 • RCS Files: 在 RCS 目录下的文件,由 RCS 控制,并通过 RCS 命令存取。一个 RCS 文件包含某一特殊文件的所有版本。 通常, RCS 文件的扩展名是 ,v • Working file: 从 RCS 源代码库 ( 即 RCS 目录 ) 中检索到的一个或者多个文件,放置 在当前工作目录下,并能够被编辑
Acegene IT Co. Ltd.
36
术语 • Lock: 以编辑目的取回工作文件时别人就 不能同时编辑这个文件。此时,文件由第 一个编辑它的人锁定 • Revision: 源文件的一个特定版本,用数 字标识。 Revision 的编号从 1.1 开始,并 依次递增,除非强制指定修订版本号 • RCS 自动处理各版本的存储、检索、更改 日志、存取控制、发行管理、修订标识和 合并;并且,由于它只跟踪文件的变化, 所以只需要最小的空间。 Acegene IT Co. Ltd.
37
基本用 法 • • • •
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.
38
基本用 法 • 如果是单用户使用,可以使用 rcs -U howdy.c 来关闭锁机制,用 rcs -L howdy.c 来打开锁机制。 • 如果你想把文件变成 RCS 文件,但是又不 想工作文件被删除,使用: • ci -l f.c 或者 ci -u f.c • 前者执行之后用户仍拥有锁,而后者执行 后用户不再有锁 ( 也就是,不可写 ) 。
Acegene IT Co. Ltd.
39
基本用 法 • • • • • •
其他参数 -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.
40
基本用 法 • ident :可以在所有类型的文件中定位 RCS 关键字(形如 $KEYWORD:VALUE$ 的字符串,不一定非得是 RCS 关键字), 开发人员利用这个特性就能找出程序的特 定发行版本中所使用的各个模块的版本号 或者其他附加信息。 • 在模块中内嵌信息是一种有用的手段,因 为这样就可以把特定的问题定位到特定的 代码模块。
Acegene IT Co. Ltd.
41
基本用 法 • rcsdiff -rVer1 -rVer2 Filename • rlog Filename 打印日志消息和其他信息 • rlog –R 只显示文件名 -L 列出被加锁的 文件 -l 列出被某个指定用户加锁的文件 • rcsmerge 可以合并多个版本,生成一个 单独的工作文件 • rcsmerge -rAncestor -rDescendant Working_file -p > Merged_file
Acegene IT Co. Ltd.
42
基本用 法 • rcs 用于两种情形: • 如果以只读方式取出文件后做修改,并且想保存 结果,此时可以使用 rcs -l Filename ,取出该 文件,并加锁,同时不覆盖现有的同名文件。 • 如果需要打开其他人对文件的加锁,可以使用 rcs -u filename ,此时文件被解锁,并且原来 的加锁者将受到一条解释信息。 • 此外: rcs -mrev:msg 可以修改某个版本的描 述信息
Acegene IT Co. Ltd.
43
基本用 法 • rcsclean 清除 RCS 文件,基本用法为 rcsclean [options] file1 file2 … • 不加任何选项的 rcsclean 删除哪些在取出 后没有更改的工作文件 • -u 选项可以先解锁所有已经加锁的文件, 然后再删除没有更改的那些工作文件。使 用 -rM.N 可以删除指定的版本,例如: rcsclean –r2.3 howdy.c 将删除 howdy.c 的 2.3 版
Acegene IT Co. Ltd.
44
RCS 关键 字 • $Id$ • $Log$ 日志消息, RCS 是在先前的日志 消息上面插入新的消息,而不是用最新的 消息取代以前的消息 • $Author$ 存入该版本的用户登录名 • $Date$ 该版本存入的日期和时间,使用 UTC 格式 • $Header$ RCS 文件的全路径名,版本号 ,日期,时间,作者,状态,加锁者(在 文件被加锁的情形下) Acegene IT Co. Ltd.
45
RCS 关键 字 • $Locker$ 锁定该版本的使用者的登陆名 • $Name$ 用于取回该版本的符号名 • $RCSfile$ 不包含路径的 RCS 文件名 • $Revision$ 该版本的版本号 • $Source$ RCS 文件的全路径名 • $State$ 版本的状态: Exp( 试验版 本 ) 、 Stab( 稳定版本 ) 、 Rel( 发行版 本 ) ,缺省为 Exp
Acegene IT Co. Ltd.
46
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.
47
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.
48
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 Acegene IT Co. Ltd.
49
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 gcc3.2
• compatibility package ???
Acegene IT Co. Ltd.
50
Current Architectures • These are the CPUs that can run Linux today: – List all CPUs one would need to build for if wanted to send a product on all types of CPUs. – IBM s/390, IA32 – Building for i386 covers most bases w/o optimizations
Acegene IT Co. Ltd.
51
Debugging your code • Spinning process? Oracle shadow?
Attach to process using gdb debugger:
$ gdb -pid 8520 `which oracle` GDB is free software, covered by the GNU General Public Attaching to program: oracle, process 8520 Reading symbols from 9.2.0/lib/libodm9.so...done. (gdb) where #0 0x40550104 in semop () from /lib/i686/libc.so.6 #1 0x0981aae9 in sskgpwwait () Wait on Semaphore ……… #6 0x0822ed45 in kslwait () #7 0x084fbaf0 in kjudbm () Mount Instance (gdb) detach Acegene IT Co. Ltd.
52
Profiling your code • Is your code doing what you think it should? – To find out or learn more on 3rd party tools, use oprofile, a freeware runtime profiling tool • Works on UL but not on RHEL 2.1AS
– Intel compiler: vtune
Acegene IT Co. Ltd.
53
Q& A
QUESTIONS ANSWERS