Linux 开发工具及编程工具

软件工具和操作系统之间是相互促进相互发展的,操作系统离不开软件工具的支持,软件工具也离不开操作系统这个平台。Linux操作系统下的开源方式,让大家拥有更多的资源,得到更多的信息,对软件工具的发展起到了更大的促进作用。在这其中开发工具起到了至关重要的作用,开发工具作为生产软件的软件,有如神兵利器一般为Linux的发展保驾护航。

从建模工具开始吧!在DC Server 5.0中带有两个建模工具,umbrello和ArgoUML。umbrello是一个轻型的UML建模工具,是KDE开发的小程序的集合Kdesdk中的一个小应用,它和其它Kdesdk中的小应用共同的特点就是功能简单使用方便。与之相反ArgoUML的功能要全面的多,ArgoUML是纯Java开发的软件,只要系统上安装有Java运行环境ArgoUML就可以正常运行,它支持 OCL,支持认知式开发,不再仅仅局限在画图建模,还可以对设计进行自动评价、自动更正…,而且它还可以将UML 直接转换成程序代码,可转换的代码有C++、C# 、PHP和Java,Argo同时它还支持反向工程。

对于那些已经习惯了使用Windows上Rose的朋友来说,也许会觉得它并没有什么突出的特点,在界面风格上不是很漂亮。但是作为一个开源软件,其在使用功能上它可以满足您的工作需要,在使用习惯上对那些未使用过其他建模工具朋友,在使用ArgoUML的时候也都不会感到一头雾水,因此还是值得推崇的。 

接下来要隆重推出DC Server 5.0中主要的IDE(集成开发环境)了。

Eclipse是linux平台时下备受注目的开源Java IDE。Eclipse主要以其开放性、极为高效的GUI、先进的代码编辑器等著称,其项目包括许多各种各样的子项目组,包括 Eclipse插件、功能部件等。而其开放式的平台则给了Eclipse在众多开发平台中前所未有的扩展性。任何人都能够轻易的将自己的软件做成Eclipse的插件,而且这些插件只需简单的复制到Eclipse的插件文件夹下 就可以被集成,通过插件,我们能够在Eclipse中 进行所见即所得的窗体设计,能够开发C/C++软件,能够进行Web项目开发及测试,还能够进行企业级软件的开发管理和性能测试。Eclipse采用了SWT界面库,支持多种的本机界面风格,其代码编辑器也十分先进,众多的编码辅助功能都相当实用。更为值得一提的是它率先集成的CASE工具让软件开发更科学高效。集成的CVS和新的版本控制程序SubVersion(SVN), 促进了协同开发的效率。JUnit则提供了在软件开发中使用TDD(Test Driven Develop)方法的一个便捷且低廉的实现方案。

唯一的遗憾就是其资源占用问题,资源占用太高,为了实时生成窗体而付出的时间代价十分巨大。但是作为一个高品质的开发平台,这些多于我们进行的应用开发来说是可以接受的。

有了Eclipse这个新贵,我们也不能忘了Kdevelop这个元老。它同Qt Designer出现,使得KDE在图形界面操作环境中的地位逐步提高。Kdevelop-Project诞生于1998年,其目的是为了给KDE提供一个易用的C/C++集成开发环境,此后,Kdevelop IDE采用发布, 支持多种程序设计语言(Ada、Bash、C/C++、Java、Perl、PHP、Python、Ruby等)。Kdevelop不仅提供了很多开发者需要的特性,同时它也集成了一些第三方的函数库,例如make和GNU C++ Compilers编译器,将他们作为开发过程中的一个可视化的集成部件,使得用户可以更加轻松的进行开发。并且根据linux系统的特点,所有的软件工具大部分都是以rpm包的形式来安装的,Kdevelop在3.0以后提供SPEC文件编写和RPM包制作的功能,使得从开发到应用变得更为简便。

软件开发势必要有大量的代码阅读工作,Kscope 便是Linux平台上用于进行代码阅读的工具之一。它是基于Cscope的KDE前端程序。Cscope是一种C语言程序代码的查询浏览工具,它通过解析一组代码,创建一个相互参照的数据库,来让用户进行查询。Kscope在Cscope的原有特性基础上加以扩展,增加用户界面、强化了编辑的集成、提高了项目的管理能力和复杂查询结果的显示。Kscope可以将查询的结果显示在一个查询窗口或一个函数树,这样有利于用户去理解整个代码的结构,即使是繁杂的核心源代码在Kscope中也会变得清晰起来。

在代码调试方面,Linux下的调试工具有很多,kdbg是一个基于Gdb的KDE应用程序,是Linux平台上一个优秀的代码调试工具,其在程序界面上直观地提供变量检查、断点设置等功能,它弥补了Gdb是在文本状态下进行调试的不足,对于已经习惯了图形界面操作的用户接受起来更容易。Gdb就是一个GUN源码调试工具,用来进行C、C++、Java等语言的调试,如果大家有时间不妨试一下Gdb调试程序给您带来的乐趣。




Linux常用编程工具

引言

    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 等,具体内容请阅读它们的相关文档。

三.调试器gdb:

    gdb是一款优秀的调试器,对它熟悉了你就会发现它真的很好用。在使用gdb调试程序前,你应该确认编译时加上了-ggdb选项,那样才能产生更多的调试信息。

提示:虽然你可以同时使用-ggdb和-O选项,但是不建议你那么做,因为一些最优化功能会让调试变得复杂。

下面将通过一个程序展示gdb的使用方法。有错误的程序是test.c。
$ gcc test.c -ggdb -o test
$ gdb test
GNU gdb Red Hat Linux (6.1post-1.20040607.41rh)
Copyright 2004 Free Software Foundation, Inc.
...
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb)
好了,现在gdb已经准备好接收命令了。
(gdb) l
1 #include < stdio.h>
2 int main(void){
3     int i=0;
4     for(;i<=10;i++);
5         printf("Now the value of i is:%d\n",i);
6     return 0;
7     }
l/list 命令的功能是列出源代码。如果后面带上行号,则会列出指定行号附近的代码。如果有多个文件的话,你也可以通过指定文件名:行号来列出对应的代码。
(gdb) b main
Breakpoint 1 at 0x8048384: file test.c, line 3.
b/break 是插入断点,后面可以是函数名,也可以是行号。
(gdb) r
Starting program: /misc/myprogram/test

Breakpoint 1, main () at test.c:3
3 int i=0;
r/run 命令是运行程序,直到断点处或程序结束。
(gdb)watch i
Hardware watchpoint 2: i
watch 是用来观察变量的变化的,一旦指定变量发生变化就停止程序。
(gdb) n
4 for(;i<=10;i++);
(gdb) n
Hardware watchpoint 4: i

Old value = 7216256
New value = 1
0x08048396 in main () at test.c:4
4 for(;i<=10;i++);
n/next 是执行下一行程序。i的值发生了变化,程序停了下来。
(gdb) p i
$1 = 1
p/print 用来打印指定表达式的当前值。
...
(gdb) c
Continuing.
Now the value of i is:11

Program exited normally.
c/continue 的功能是继续执行程序直到下一个断点处或程序结束。
(gdb) q
$
q/quit 是退出gdb调试程序。 调试完毕,如果你想把调试信息从执行文件中去掉而又不重新编译,可以使用命令:strip  filename
使用gdb我们可以很快找出错误。gdb还有很多高级功能,比如进行汇编级别的调试,而且可以和emacs搭配使用,是非常优秀的调试工具。[8]中对它进行了更全面的介绍。

四.性能分析工具gprof:

    有一些程序设计工具,它可以告诉你程序执行的效率,整个程序的调用结构,函数调用关系等。这样的工具真的很有用。gprof就是这样的一个效率分析工具,它能产生一份详细的列表,列出程序执行的一些统计值,其中包括每个函数被调用的频率,被谁调用,所花费时间等。要使用gprof,在用gcc编译时要加上-pg参数。这个参数会在目的文件中加上gprof所需的信息,也会将执行文件连接上支持性能分析的函数库。
    你只要直接执行编译时加过 -pg 的程序即可,执行完毕后会在当前工作目录下产生一个gmon.out的文件,它记录了gprof所需的信息,我们可以用gprof来读取它。
$ gcc bintree.c -o bintree -pg
$ ./bintree
...
$ gprof bintree gmon.out
Flat profile:

Each sample counts as 0.01 seconds.
no time accumulated

  %   cumulative   self              self     total
 time   seconds   seconds    calls  Ts/call  Ts/call  name
  0.00      0.00     0.00       28     0.00     0.00  print
  0.00      0.00     0.00        7     0.00     0.00  btree_insert
...
gprof的输出信息相当冗长,上面省略了很多。由于上面的函数执行太快,而gprof的计时单位相当粗略,所以那些函数的执行时间都显示0.00秒。gprof能为我们提供不少有用的信息。
    另一个常用的计时工具是 time 命令,它可以精确地测量程序运行时间。使用它只需在其后面 加上要测量的命令即可。比如:
$time ./test>/dev/null
显示如下,分别是实际耗时,用户级别耗时和系统级别耗时:
real    0m0.056s
user    0m0.014s
sys     0m0.006s
它还能格式化输出,还能测量输入/输出,消息数目,非常方便。还有一个更简单的 calls 程序,它只显示源代码中函数调用的树状结构。而 strace 能够显示程序执行时用到的系统调用,具体请参阅相关手册。

五.链接器ld:

    ld是GNU的链接器,支持生成大量的可执行文件格式,它是一款复杂而快捷的工具。 ld有许多灵活的参数来控制其链接过程。这里只介绍主要几个参数。
    如果你希望用example.ld作为链接脚本,可以这样使用:

    ld -T example.ld

如果你想把一系列的.o文件链接到另外一个.o文件中,可以像这样用ld:

    ld -r foo.o bar.o -o example.o

如果你希望ld生成一个Linux上使用的共享库,可以用:

    ld -shared ...

如果你想去掉文件中的符号表等内容,加上-s选项。而-S选项则只去掉调试信息。

    ld -s ...

如果你想把 entry 作为程序入口,可以:

    ld -e entry ...

如果你想把.text段加载到0x0处,可以:

    ld -Ttext 0x0 ...

查看帮助信息可以用:

    ld --help

了解更多,请查看Steve Chamberlain的文章[6]。

六.Patch文件:

    如果你在维护包含很多源文件的一个大型项目,每次更新后都推出完整的源程序是不太可行的,所以最好就用patch程序来更新原来的程序。这样,当你的程序升级时,你只要推出源文件对应的patch文件,其他人就能通过执行patch来使用那个patch文件,以获得最新版本的程序。
    比如我们有一个程序foo,我们把它更新为bar,我们可以用diff程序这样产生patch文件:
$diff -u foo bar > foo.patch
-u 参数指定使用特殊的diff输出格式,否则得到的patch格式怪异,一般人都没法看懂。 foo.patch 就包含了描述foo和bar不同的信息,我们将用这个文件来更新。

提示:一定要注意diff命令后面的文件名顺序,一定是旧的文件在前,新的文件在后!

接下来,我们用patch来更新:
$patch foo < foo.patch
使用过某个patch文件后,若要再次使用该patch文件,patch程序会产生警告信息:询问是否以-R方式执行,-R将还原文件。这样很好,防止进行了误操作。当然,有时你想更新的是整个目录中的所有源文件,比如foo和bar两个目录,我们可以:
$diff -cr foo bar >foo.patch
$patch -p0 < foo.patch
diff的 -c 参数表示输出上下文格式, -r 参数表示递归的比较两个目录。  -p0 告诉patch程序被更新的文件的路径名并没改变。
    diffstat是一个很有用的工具,它可以列出patch 所引起的变更的统计(加入或移出的代码行)。输出关于patch的信息,执行:
$diffstat -p1 foo.patch
    更多选项请参阅patch和diff的使用手册。 和diff类似的工具还有比较三个文件的diff3,合并文件的sdiff,简单比较的cmp,分行比较的comm等,这里就不一一介绍了。

七.版本控制系统CVS:

    CVS是非常优秀的版本控制工具,比较适合大项目的版本控制。甚至可以说没有CVS就不会有今天GNU的流行。GNU绝大多数的项目都采用CVS来控制版本。熟悉CVS对Linux程序员来说是非常有必要的。
    CVS的使用很复杂,这里只做简单介绍。CVS管理着 repository ,里面存储着正式的源代码。每个在 repository 项目叫做 module 。开发者不能直接编辑 repository 中的文件,而是先要取出( check out ),编辑完后再把源代码传送回 repository commit )。
    首先,我们应该把环境变量 CVSROOT 设成我们想要存储 repository 的目录:
$mkdir /usr/local/CVSROOT
$export CVSROOT=/usr/local/CVSROOT
提示:不要把CVS的repository建在和你想要加入repository之中的项目相同的目录中。这会导致一个死循环。

储存目录建好后,我们就可以建立 repository 了:
$cvs init
然后要在 repository 中建立项目。在CVS中建立项目有很多方法,我们可以用下面的命令:

   cvs import dir manufacturer tag

其中 dir 是项目所属的目录, manufacturer 是作者名(设成别的也可以), tag 是版本编号,比如说是 initial start 。例如:
$cvs import example myname initial
一旦在CVS中建立了项目,开发者们就可以开始各自的工作了,他们互不影响。

提示:避免直接编辑CVS repository中的文件,这不符合CVS设计者的本意。CVS控制的文件被设置为只读来避免这种情况的发生。

比如有一个程序有一个名为 example 的模块,可以这样“取出”它的本地目录:
$cvs checkout example
CVS会把 example 所有的文件和目录取出,这样你就可以编辑这些文件了。在编辑完成后,你可以这样将改变的文件写回 repository 中:
$cvs commit -m “description of your changes”
你也可以只写入某个文件:
$cvs commit example.c
当然,在你修改时,很可能你的同事已经将他编辑的文件写入 repository 中去了。这时,CVS不会让你写入,而是要求你先更新再写入。可以这样来更新:
$cvs update
有时候,你想在项目中加入或删除某个文件,你可以这样做:
$cvs add extra.c
这就把extra.c加入进去。删除文件有点麻烦,你必须先在你的工作目录中把你想删除的文件删除,然后在使用下面的命令:
$cvs remove
这样虽有点麻烦,但可以防止你误删,有必要时还可以进行恢复。
当然,开源项目几乎都是放在网上的。所以CVS也可以允许你远程使用:
$export CVSROOT=:cvsserver:guest@cvs.com:/cvs
$cvs login
...
CVS password:
...
$cvs checkout example.c
...
很多大的开源项目都是使用CVS进行版本控制的,要参与开源项目,非常有必要熟悉它。关于CVS更详细的介绍见[7]第13章。另外,RCS,Subversion也是同样出色的版本控制工具,[7]中对它们也作了介绍。 gCVS是CVS的图形化前端,使用非常简单。

八.双节棍──objdump&objcopy:

    objdump是一个不错的工具,它有很多功能,反汇编,显示调试信息,显示目标文件中的符号表或段信息等等。 而objcopy可以根据你的需要复制,翻译目标文件。

九.三叉戟──autoconf+automake+libtool:

十.瑞士军刀──valgrind

参见《瑞士军刀──valgrind》一文

十一.ctags+cxref+cflow+indent

ctags

cxref

    cxref可以分析C源程序,为它输出一个交叉引用的列表文件,这个输出文件可以是普通文本格式, 也可以是HTML,Latex等格式,对阅读代码非常方便。cxref命令格式如下:

cxref filename [ ... filename] -options
不同版本的cxref选项不太相同,以我使用的1.5版为例,讲一下它的用法。其它版本请参考它自带的手册。

-Nbasename:指定输出文件的前一部分的名字,默认的是cxref。

-Rdirname:当要分析的C源程序分布在多个目录中时,用此来指定源代码树的根目录。

-Odirname:输出交叉引用文件到指定的目录。

-htmlxx:xx可以是20或者32,使用HTML2.0或3.2格式输出。

cflow

indent


结论

    除了上面这些之外,Linux还有很多其它优秀的工具, 像著名的 vi  [4]和 emacs  [3]文本编辑器,词法分析工具 flex , 编译器的编译器 yacc ,排版工具 tex groff 等。 有的发行版还带了图形化的IDE,像 Qt KDevelop 等。 Linux自带了不少相关文档,而且篇幅有限,这里不再全面介绍。Linux真的是一个不错的开发平台。



进一步阅读:

[1] Programming with GNU Software , Mike Loukides and Andy Oram, O'Reilly
[2] Sed & Awk, Second Edition , Dale Dougherty and Arnold Robbins, 1997, ISBN 1-56592-225-5, O'Reilly.
[3] Learning GNU Emacs, Third Edition , Debra Cameron, James Elliott and Marc Loy, ISBN 0-596-00648-9, O'Reilly
[4] Learning the vi Editor, Fifth Edition , L.Lamb, 1990, O'Reilly
[5] Managing Projects with GNU make, Third Edition , Robert Mecklenburg, 2004, ISBN 0-596-00610-1, O'Reilly.
[6] Using LD, the GNU linker , Steve Chamberlain.
[7] Linux in a Nutshell, 5th Edition , Ellen Siever, Stephen Figgins and Aaron Weber, 2003, ISBN 0-596-00482-6, O'Reilly & Associates.
[8] 《用GDB调试程序》,CSDN文档中心
[9] GNU Automake , David MacKenzie and Tom Tromey, For version 1.3, 3 April 1998.
[10] Sed - An Introduction , Bruce Barnett and General Electric Company, 2005.
[11] Getting started with awk , HMC Computer Science Department.
[12] GCC: The Complete Reference , Arthur Griffith, McGraw-Hill

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值