一、目录及概述
Section 1.1. Introduction
Section 1.2. UNIX Architecture
Section 1.3. Logging In
Section 1.4. Files and Directories
Section 1.5. Input and Output
Section 1.6. Programs and Processes
Section 1.7. Error Handling
Section 1.8. User Identification
Section 1.9. Signals
Section 1.10. Time Values
Section 1.11. System Calls and Library Functions
Section 1.12. Summary
This chapter provides a whirlwind tour of the UNIX System from a programmer's perspective. We'll give some brief descriptions and examples of terms and concepts that appear throughout the text. We describe these features in much more detail in later chapters. This chapter also provides an introduction and overview of the services provided by the UNIX System, for programmers new to this environment.
本章是UNIX系统概览,几乎所有介绍UNIX系统的书都有此类内容。
学习本章有些内容可能不知其所以然,不过不用着急,后面所有章节会对不知其所以然的内容作详细的讲解。因此本章的几个小程序只要在自己学习的类UNIX系统上能够运行通过也就行了。至于用来学习的类UNIX系统的选择,随便一个应该都可以的。本人使用的是一款国产linux——中标普华linux服务器(neoshine Linux 2.6.9 kernel),运行在vmware 5.5之上。
二、运行第一个程序
第一个程序包括:
(1)/home/zhj/study/apue.2e/include/apue.h
(2)/home/zhj/study/apue.2e/lib/error.c
/home/zhj/study/apue.2e/lib/makefile
(3)/home/zhj/study/apue.2e/figures/fig1.3.c
/home/zhj/study/apue.2e/figures/makefile
头文件和程序暂不详细分析,以后章节会做这个工作;先分析两个makefile文件。
1、vi /home/zhj/study/apue.2e/lib/makefile
###############################################################
# #
# makefile #
# #
###############################################################
WKDIR=/home/zhj/study/apue.2e
CC=gcc
CFLAGS=-DLINUX -ansi -I$(WKDIR)/include -Wall -D_GNU_SOURCE
TEMPFILES=*.o *.out
AR = ar
LIBMISC = libapue.a
OBJS = error.o
RANLIB = ranlib
all: ${OBJS}
${AR} rv ${LIBMISC} $?
${RANLIB} ${LIBMISC}
clean:
rm -f $(LIBMISC) $(TEMPFILES)
(1)gcc
GCC(GNU C Compiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。
虽然我们称gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历以下四个相互关联的步骤∶
1.预处理(也称预编译,Preprocessing):生成.i的文件[预处理器cpp] ;
2.编译(Compilation):将预处理后的文件转换成汇编语言文件,生成文件.s[编译器ccl] ;
3.汇编(Assembly):将汇编语言文件变为目标代码(机器代码)生成.o的文件[汇编器as];
4.连接(Linking):连接目标代码,生成可执行程序[链接器ld] 。
命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(#include)、预编译语句(如宏定义#define等)进行分析。
当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是链接。在链接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的库中链接到合适的地方。
gcc参数选项非常多,有100多个,但常用的不多,详细内容可以到上下载gcc文档阅读。接下来介绍几个常用的选项,包括上面makefile中gcc用到的选项。
--help 显示gcc的命令行选项列表;与"-v"一起使用时还将显示gcc调用的各个进程所接受的选项。
-c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
-o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。
-Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。
-Ldirname,将dirname所指出的目录加入到程序函数档案库文件的目录列表中,是在连接过程中使用的参数。在预设状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的档案库文件,这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后到系统预设路径中寻找,如果函数库存放在多个目录下,就需要依次使用这个选项,给出相应的存放目录。
-lname,在连接时,装载名字为“libname.a”的函数库,该函数库位于系统预设的目录或者由-L选项确定的目录下。例如,-lm表示连接名为“libm.a”的函数库。
-ansi 按照ANSI标准编译程序,但并不限制与标准并不冲突的GNU扩展,这一选项将禁止 GNU C 的某些特色,例如 asm 或 typeof 关键词(一般不用该选项)。
-std= 指定C语言的标准(c89,c99,gnu89),该选项禁止了GNU C的扩展关键字asm,typeof,inline (一般不用该选项)。
-Wall 显示所有的警告消息。
-DMACRO 相当于C语言中的#define MACRO,以字符串“1”定义 MACRO 宏。
-UMACRO 取消对 MACRO 宏的定义。
(2)ar,ranlib
ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。
下面是ar命令的格式:
ar [仿真选项] [-]{dmpqrstx}[abcfilNoPsSuvV] [成员名] [计数] 归档文件 文件...
例如我们可以用ar rv libTest.a hello.o hello1.o来生成一个库,库名字是test,链接时可以用-ltest链接。该库中存放了两个模块hello.o和hello1.o。选项前可以有 ‘-’字符,也可以没有。下面我们来看看命令的操作选项和任选项。现在我们把{dmpqrstx}部分称为操作选项,而[abcfilNoPsSuvV]部分称为任选项。
{dmpqrstx}中的操作选项在命令中只能并且必须使用其中一个,它们的含义如下:
d:从库中删除模块。按模块原来的文件名指定要删除的模块。如果使用了任选项v则列出被删除的每个模块。
m:该操作是在一个库中移动成员。当库中如果有若干模块有相同的符号定义(如函数定义),则成员的位置顺序很重要。如果没有指定任选项,任何指定的成员将移到库的最后。也可以使用’a’,’b’,或’I’任选项移动到指定的位置。
p:显示库中指定的成员到标准输出。如果指定任选项v,则在输出成员的内容前,将显示成员的名字。如果没有指定成员的名字,所有库中的文件将显示出来。
q:快速追加。增加新模块到库的结尾处。并不检查是否需要替换。’a’,’b’,或’I’任选项对此操作没有影响,模块总是追加的库的结尾处。如果使用了任选项v则列出每个模块。这时,库的符号表没有更新,可以用“ars”或ranlib来更新库的符号表索引。
r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
t:显示库的模块表清单。一般只显示模块名。
x:从库中提取一个成员。如果不指定要提取的模块,则提取库中所有的模块。
[abcfilNoPsSuvV]是可与操作选项结合使用的任选项:
a:在库的一个已经存在的成员后面增加一个新的文件。如果使用任选项a,则应该为命令行中membername参数指定一个已经存在的成员名。
b:在库的一个已经存在的成员前面增加一个新的文件。如果使用任选项b,则应该为命令行中membername参数指定一个已经存在的成员名。
c:创建一个库。不管库是否存在,都将创建。
f:在库中截短指定的名字。缺省情况下,文件名的长度是不受限制的,可以使用此参数将文件名截短,以保证与其它系统的兼容。
i:在库的一个已经存在的成员前面增加一个新的文件。如果使用任选项i,则应该为命令行中membername参数指定一个已经存在的成员名(类似任选项b)。
l:暂未使用
N:与count参数一起使用,在库中有多个相同的文件名时指定提取或输出的个数。
o:当提取成员时,保留成员的原始数据。如果不指定该任选项,则提取出的模块的时间将标为提取出的时间。
P:进行文件名匹配时使用全路径名。ar在创建库时不能使用全路径名(这样的库文件不符合POSIX标准),但是有些工具可以。
s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。甚至对于没有任何变化的库也作该动作。对一个库做ar s等同于对该库做ranlib。
S:不创建目标文件索引,这在创建较大的库时能加快时间。
u:一般说来,命令arr…插入所有列出的文件到库中,如果你只想插入列出文件中那些比库中同名文件新的文件,就可以使用该任选项。该任选项只用于r操作选项。
v:该选项用来显示执行操作选项的附加信息。
V:显示ar的版本。
ar,ranlib的使用原理详见前数第四篇文章《makefile学习》中GNU MAKE3.8中文文档第十一章:使用make更新静态库文件。
2、/home/zhj/study/apue.2e/figures/makefile
(1)第一个简单易懂的makefile:
###############################################################
# #
# makefile #
# #
###############################################################
WKDIR=/home/zhj/study/apue.2e
INCDIR=$(WKDIR)/include
LIBDIR=$(WKDIR)/lib
LIB=apue
CC=gcc
CFLAGS=-I$(INCDIR) -Wall
OBJECTS=fig1.3
$(OBJECTS):$(OBJECTS).o
$(CC) -o $(OBJECTS) -L$(LIBDIR) $(OBJECTS).o -l$(LIB)
$(OBJECTS).o:$(OBJECTS).c
$(CC) $(CFLAGS) -o $(OBJECTS).o -c $(OBJECTS).c
clean:
rm -f *.o $(OBJECTS)
这个makefile足够简单,除了变量声明,就是两个gcc命令(我本来就是根据在命令行方式下gcc的命令改写的makefile文件)。只是在命令行执行gcc命令时,先执行.c到.o的编译,再执行.o到目标文件的链接。
(2)对以上makefile的简单改写:
###############################################################
# #
# makefile #
# #
###############################################################
WKDIR=/home/zhj/study/apue.2e
INCDIR=$(WKDIR)/include
LIBDIR=$(WKDIR)/lib
LIB=apue
CC=gcc
CFLAGS=-I$(INCDIR) -Wall
OBJECTS=fig1.10
$(OBJECTS):$(OBJECTS).o
$(CC) -o $@ -L$(LIBDIR) $? -l$(LIB)
$(OBJECTS).o:$(OBJECTS).c
$(CC) $(CFLAGS) -o $@ -c $?
clean:
rm -f *.o $(OBJECTS)
这个改写仅仅是使用了GNU MAKE的自动化变量。有关GUN MAKE的自动化变量,详见前数第四篇文章《makefile学习》中GNU MAKE3.8中文文档第10.5.3自动化变量一节。
在lib和figures下分别make,第一个程序就这样运行成功了!
阅读(1400) | 评论(0) | 转发(0) |