原创 linuxC编程

2006-10-26 11:48 3302 5 5 分类: 软件与OS

下面几条是基于G N U开放源代码方面的要求:


1) 在任何情况下都不要引用有版权的源代码。


2) 善意接受别人给你的程序添加的代码,但请记住检查其合法性,即是否也是 GNU 的。


3) 编写日志文件( C h a n g e l o g ),这将使你的代码更容易维护


在V I M中,用户可以编辑自己的 . v i m r c文件,加上下面这些配置,就可
以在V I M中实现L i n u x核心编程风格。
set ts="8"
if !exists("autocommands_loaded")
let autocommands_loaded = 1
augroup C
autocmd BufRead *.c set cindent
augroup END
endif


我们也可以用下面这条命令将其转变为G N U编程风格:


indent -gnu test.c
如果要变成L i n u x核心风格,则输入如下命令:


indent -kr -i8 test.c


其中- g n u参数就是采用G N U风格,- k r参数是采用K & R风格,-kr -i8参数就是L i n u x内核编程的风格。
如何使用gcc开发应用程序


在L i n u x中使用最多的编程语言还是C和C + + ,而如何使用g c c和编写M a k e f i l e ,是每一个初学者最头疼的事情,下面我们就来看看如何使用g c c和编写M a k e f i l e


如何使用gcc


1. 使用g c c编译和连接


用g c c编译C程序生成可执行文件有时候看起来像是一步就完成了,但实际上它要经历如下的四个步骤:1) 预处理(P r e p r o c e s s i n g):这一步需要分析各种命令,如# d e f i n e、# i n c l u d e、# i f等。g c c调用c p p程序来进行预处理工作。


2) 编译(C o m p i l a t i o n):这一阶段根据输入文件产生汇编语言,由于通常是立即调用汇编程序,所以其输出一般不保存在文件中。g c c调用c c 1进行编译工作。


3) 汇编(A s s e m b l y):这一步将汇编语言用作输入,产生具有 . o扩展名的目标文件。g c c调用a s进行汇编工作。


4) 连接(L i n k i n g):这一阶段中,各目标文件. o被放在可执行文件的适当位置上,该程序引用的函数也放在可执行文件中(对使用共享库的程序稍有不同)。g c c调用连接程序l d来完成最终的任务。


下面是g c c如何处理不同类型的文件的列表:


file.c: C源文件,被gcc预处理和编译


file.C: C++源文件,被gcc预处理和编译


file.cc: C++源文件,被gcc预处理和编译


file.cxx:C++源文件,被gcc预处理和编译


file.m: Objective C源文件,被gcc预处理,编译和汇编


file.i: 预处理后的C源文件,被gcc编译


file.ii: 预处理后的C++源文件,被gcc编译


file.s: 汇编语言源文件,被as汇编


file.S: 汇编语言源文件,被as预处理和汇编


file.o: 编译后的目标文件,传送给ld


file.a: 目标文件库,传送给ld


g c c在命令行上经常使用的几个选项是:



-c 只预处理、编译和汇编源程序,不进行连接。编译器对每一个源程序产生一个目标文件。
-o file   确定输出文件为f i l e。如果没有用- o选项,缺省的可执行文件的输出是a . o u t,目标文件和汇编文件的输出对s o u r c e . s u ff i x分别是s o u r c e . o和s o u r c e . s,预处理的C源程序的输出是标准输出s t d o u t。


- D m a c r o或-Dmacro="defn"   其作用类似于源程序里的# d e f i n e。例如:% gcc -c -DHAVE_GDBM -DHELP_FILE=\"help\" cdict.c其中第一个- D选项定义宏H AV E _ G D B M,在程序里可以用# i f d e f去检查它是否被设置。第二个- D选项将宏H E L P _ F I L E定义为字符串“h e l p”(由于反斜线的作用,引号实际上已成为该宏定义的一部分),这对于控制程序打开哪个文件是很有用的。


-Umacro   某些宏是被编译程序自动定义的。这些宏通常可以指定在其中进行编译的计算机系统类型的符号,用户可以在编译某程序时加上 - v选项以查看g c c缺省定义了哪些宏。如果用户想取消其中某个宏定义,用- U m a c r o选项,这相当于把#undef macro放在要编译的源文件的开头。


-Idir   将d i r目录加到搜寻头文件的目录列表中去,并优先于在 g c c缺省的搜索目录。在有多个- I选项的情况下,按命令行上- I选项的前后顺序搜索。d i r可使用相对路径,如- I . . / i n c等。


-O   对程序编译进行优化,编译程序试图减少被编译程序的长度和执行时间,但其编译速度比不做优化慢,而且要求较多的内存。


-O2   允许比- O更好的优化,编译速度较慢,但结果程序的执行速度较快。


-g   产生一张用于调试和排错的扩展符号表。- g选项使程序可以用G N U的调试程序G D B进行调试。优化和调试通常不兼容,同时使用- g和- O(- O 2)选项经常会使程序产生奇怪的运行结果。所以不要同时使用- g和- O(- O 2)选项。


- f p i c或-fPIC   产生位置无关的目标代码,可用于构造共享函数库。以上是g c c的编译选项。


g c c的命令行上还可以使用连接选项。


事实上, g c c将所有不能识别的选项传递给连接程序l d。连接程序l d将几个目标文件和库程序组合成一个可执行文件,它要解决对外部变量、外部过程、库程序等的引用。但我们永远不必要显式地调用 l d。利用g c c命令去连接各个文件是很简单的,即使在命令行里没有列出库程序, g c c也能保证某些库程序以正确的次序出现。g c c的常用连接选项有下列几个:


-Ldir   将d i r目录加到搜寻- l选项指定的函数库文件的目录列表中去,并优先于 g c c缺省的搜索目录。在有多个- L选项的情况下,按命令行上 - L选项的前后顺序搜索。d i r可使用相对路径。如- L . . / l i b等。


-lname   在连接时使用函数库l i b n a m e . a,连接程序在- L d i r选项指定的目录下和/ l i b,/ u s r / l i b目录下寻找该库文件。在没有使用 - s t a t i c选项时,如果发现共享函数库 l i b n a m e . s o,则使用l i b n a m e . s o进行动态连接。


-static   禁止与共享函数库连接。


-shared   尽量与共享函数库连接。这是L i n u x上连接程序的缺省选项。


下面是一个使用g c c进行连接的例子:


% gcc -o prog main.o subr.o -L../lib -lany -lm


库可以有三种形式:静态、共享和动态。


静态库的代码在编译时就已连接到开发人员开发的应用程序中,而共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。


动态库则是共享库的另一种变化形式。动态库也是在程序运行时载入,但与共享库不同的是,使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入。动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其他程序使用。由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此,代码的规模比较小。
已经开发的大多数库都采取共享库的方式。E L F格式的可执行文件使得共享库能够比较容易地实现,当然使用旧的a . o u t模式也可以实现库的共享。L i n u x系统中目前可执行文件的标准格式为E L F格式。



系统中可用的库都存放在/ u s r / l i b和/ l i b目录中。库文件名由前缀l i b和库名以及后缀组成。根据库的类型不同,后缀名也不一样。共享库的后缀名由 . s o和版本号组成,静态库的后缀名为. a。采用旧的a . o u t格式的共享库的后缀名为. s a。一个标准库的名称如下: libname.so.major.minor libname.a这里的n a m e可以是任何字符串,用来唯一标识某个库。该字符串可以是一个单字、几个字符、甚至一个字母。数学共享库的库名为l i b m . s o . 6,这里的标识字符为m,版本号为6。l i b m . a则是静态数学库。X Wi n d o w s库名为l i b X 11 . s o . 6,这里使用X 11作为库的标识,版本号为6。使用g c c编译器就可以将库与自己开发的程序连接起来,例如: l i b c . s o . 6中包含了标准的输入输出函数,当连接程序进行目标代码连接时会自动搜索该程序并将其连接到生成的可执行文件中。标准的输入输出库中包含了许多基本的输入输出函数,如 p r i n t f函数等。也可以连接其他的一些系统函数库,如数学库等。但与l i b c . s o . 6不同,大部分其他的系统库需要在命令行中显式地指定所用的库名。


在/ u s r / l i b和/ l i b目录中可以找到绝大多数的共享库。连接时将首先搜索这两个目录。有一些库也可能存放在特定的目录中,在/ e t c / l d . c o n f配置文件中给出了这些目录的列表。连接程序也会对列出的这些目录进行搜索。在默认情况下,L i n u x将首先搜索指定库的共享版本,如果找不到,才会去搜索静态版本。在对共享库进行更新或安装新库后,必须运行l d c o n f i g命令更新/ e t c / l d . c o n f文件中相应的项(如果使用R P M进行安装,会自动进行更新)。


在g c c编译器中引用可搜索到的目录中的库文件时,需要使用 - l选项和库名。在g c c命令行上输入- l m可以在程序中连接标准算术库,- l将首先使用l i b n a m e . s o进行搜索,这里是l i b m . s o。下面的例子将使用算术库创建t e s t程序,请注意这里的- l m选项。$ gcc test.c -o test -lm在引用其他目录中的库时,需要使用 - L d i r选项指定该目录。该选项指定了搜索库函数时的其他路径。在下面的例子中,用户在连接时使用了m y d i r目录中的m y l i b . s o库文件。$ gcc test.c -o test -Lmydir -lmylib


有时候,用户会感到有必要创建自己的函数库。 a r命令可用于创建和更新函数库。


 创建一个新的函数库,可用如下命令:ar rs lib-name list-of-files


r选项表示a r命令应把在列表l i s t - o f - f i l e s中的目标文件增加到l i b - n a m e库中,如果l i b - n a m e库不存在,就创建一个。s选项表示为该档案库产生一个索引(从而不必要执行r a n l i b命令了)。


要更新一个库可用如下命令: ar rus lib-name list-of-files该命令将l i s t - o f - f i l e s列出的任何文件的日期与库中该文件的版本进行比较,如果 l i s t - o f - f i l e s中的文件比库中的版本更新,a r就用新版本替代旧版本。s选项可更新此函数库的索引。


从函数库中删除一个或多个文件,可使用如下命令: ar ds lib-name list-of-files   该命令可删除l i s t - o f - f i l e s列出的并在l i b - n a m e库中的所有文件。


从一个函数库中提取一个或多个文件,可用如下命令: ar x lib-name list-of-files


该命令并不修改函数库文件本身,而是从库中提取 l i s t - o f - f i l e s列出的所有文件。通常,把提取文件的时间标记成当前时间。但如果用x o选项代替x选项,则把提取文件的时间标记成它们进入档案库的时间。

文章评论0条评论)

登录后参与讨论
我要评论
0
5
关闭 站长推荐上一条 /2 下一条