Linux在很多人眼中是非常好的操作系统,不仅因为它的内核和函数库的完整源代码都是公开的,而且因为它拥有许多好用的程序开发工具。下面就介绍几种常用的编程工具,熟悉这些工具对于开发Linux应用程序是很有必要的。当然了,像其它Linux程序一样,更详细的内容你能在man手册或info页中找到。
一.gcc编译器:gcc是GNU提供的优秀的软件之一,其性能不亚于任何商业编译器。它具有惊人的可移植性,而它也号称其最优化功能非常强大。gcc功能实在太多(不信的话你试一下man gcc),这里无法一一列举,只能介绍一些常用的参数。
-o filename
:这可能是你最常用的一个选项了。它用来产生以指定名字的可执行输出文件。如果不指定文件名,gcc产生默认的a.out。键入./filename就可执行程序,查看结果。
$ gcc hello.c -o hello
$ ./hello
hello world!
提示:在使用gcc命令的时候不要用Tab键来补齐文件名,因为那可能会覆盖源文件。
-c
: 只编译不链接,产生以.o结尾的目标文件。当然它也可以同时编译多个文件。
$ gcc -c hello.c
$ls -l hello.o
-rw-r--r-- 1 wangcong wangcong 888 6月 11 23:20 hello.o
-g/-ggdb
: -g参数可以让gcc将一些调试信息加入目标文件中,而-ggdb专为gdb调试器产生足够的调试信息。如需用gdb调试程序应加上此项。注意:这会使目标文件大小增加,我们最好只在测试时使用这个参数,最后发行版中将其去除。
例如:
$ gcc hash.c -o hash -ggdb
-Idir
: 要求gcc在搜寻头文件时除了默认的目录/usr/include,也要到指定的目录dir中去找。
比如,编译test.c时要用到/home/myname/test.h,我们可以:
$gcc -I/home/myname test.c -o test
-llibname
: 尝试链接指定名为liblibname.a的函数库。注意-l选项的顺序是有意义的。
比如,test.c中用到了数学函数库,我们要链接libm.a,可以:
$ gcc test.c -lm -o p
-Ldir
: 让gcc也要在指定的目录dir中去寻找-l指定的函数库。
例如我们要链接/home/myname/libtest.a,我们这样做:
$gcc -I/home/myname -L/home/myname -ltest test.c -o test
-On
: 最优化选项。后面的n越大最优化程度越大。一般最常用的是-O2。-O0是不优化,这也是默认的。
$gcc -O2 -o foo foo.c
-Wall/-w
: -Wall将打开所有警告,而-w将关闭所有警告。在编译C程序时,强烈建议你加上-Wall选项,因为gcc给出的很多警告都是相当有用的。当然还有折中的选择,具体请参阅man手册。
-lefence
: 将libefence.a函数库链接上,给程序加上电子篱笆,可以用来检查内存泄漏。挺有用的选项。
-S
:用来产生相应的汇编源文件,默认的文件名是filename.s
-ansi/-std=standard
:standard可以是以下内容:c89,c9x,c99,gnu89,gnu9x,gnu99等。其中-std=c89就相当于-ansi。而gnuxx相当于cxx加上gnu扩展。 当然了,它也可以用来调试C++,Fortran等其它程序。另外,即使你编译时使用了-Wall选项,也建议你使用lint检查一下你的C程序,它能给出很多有用的信息。Linux常用的lint工具是splint。[12]对GCC做了全面的介绍,绝对是首先参考。
二.管理工具make:
make是一个通用的工程管理工具,它可以“自动化编译”,极大地提高了软件开发的效率,无怪乎它被誉为“Unix发展的一个中流砥柱”。make的使用是根据预先设定的规则来运行的,这些设定的规则记录在一个文件中,即makefile。
make命令的格式是:
make [ -f makefile ] [ option ] ... target ...
-c dir
:将指定目录设为make开始运行后的工作目录。
-f filename
:将指定的文件作为makefile
-k
:使make尽可能地编译,即使命令调用返回一个错误,make也不会停止运行。这个功能很有用,例如,当需要移植的时候;你可以创建尽可能多的目标文件,然后可以在不用等待中间文件创建的同时,移植到不能创建的文件处。
下面简单地介绍一下makefile的基本书写规则。makefile基本书写规则如下:
target ... : prerequisites ...
command
...
target是目标文件,也就是你要产生的文件或一个标签;prerequisites是产生目标文件所需的文件列表;command是make需要执行的命令。第一个命令可以加“;”跟在倚赖文件列表后,也可以另起一行书写。注意:当命令另起一行书写时一定要加tab键,否则make不认识。一行放不下时可以用“\”来续行,在一行开头用“#”开始注释。
例如,有下面一个简单的工程,其倚赖关系如下:
上图中,工程example倚赖于test.o 和main.o,而test.o倚赖test.h和test.c,main.o倚赖main.c和main.h。我们将这样写makefile:
example:test.o main.o
gcc -o example test.o main.o
main.o:main.c main.h
gcc -c main.c
test.o:test.c test.h
gcc -c test.c
但是,你会发现,我们编译完成后,test.o和main.o没用了,我们应该删除它们。 那么应该怎么做呢?我们可以加一个动作名字clean,让这个动作完成删除作用。
clean:
rm -f test.o main.o
要执行删除只要运行
$make clean
就可以了。但是这还不够, 因为我们也有可能想产生一个目标文件叫做clean,这就会造成冲突。为了避免如此, 我们增加一行:
.PHONY: clean
.PHONY是一个伪指令,向make说明clean不是一个文件。当计算clean依赖关系时,make都会忽略任何名为clean的文件。 make除此之外还有大量的高级功能,比如:宏变量,流程控制等。 如果你想了解更多关于make的知识,请看[5]。
其实,makefile并不好写,尤其是对于大型工程项目。我们可以使用imake,它是一个makefile的生成程序,利用了C的预处理程 序,你只要写一个imakefile文件,就能使用imake来产生一个makefile。当然,还有其它的makefile生成器,像
ICmake,automake等,具体内容请阅读它们的相关文档。