Unix or Linux 软件开发工具速查

恩布开源企业IM 2011-11-11

Linux下的基本操作速查

涉及的内容:

1)连接服务器;

2)Shell常用命令与常用参数;

3)VIM的使用;

4)Linux更新软件;

5)GCC的常见参数;

6)GDB调试程序;

7)Makfefile的编写;

8)代码注释,文档管理:开源Doxygen;

9)版本控制:SVN常用命令;

连接到Linux服务器

用SecureCRT连接Linux服务器。安装完成后从File菜单选择QuickConnect即可。使用SSH1协议,在连接时注意。

为了方便起见,建议在安装完成后作如下设置:

Options->GlobalOptions->DefaultSession->EditDefaultSettings

Connection->ProtocolSSH1

Terminal->Emulation->TerminalXterm

Terminal->Emulation->ANSIColorOn

Terminal->Appearance->CurrentColorSchemaTraditional

建议在Windows上安装虚拟机学习;

如何使用Shell

刚登录到Linux时,会显示BashShell提示符如下。现在你可以使用Shell命令来指挥Linux。

l===常识===

linux用"/"而非"\"来分隔目录,/dir/.表示/dir这个目录,而/dir1/dir2/..表示/dir1这个目录。

shell总是有一个当前目录,文件的相对路径(不以"/"开头的路径)从当前目录开始计算

catsort等处理文件内容的命令,在没有文件名时处理标准输入(键盘输入)

*和?是文件名通配符,*代表示任意数量字符,?代表单个字符。通配符由shell而非命令自身解释,因此ren*.bak*.sav这样的dos操作是不可能的。

l===目录相关===

pwd显示当前目录,

cd/dir1/dir2修改当前目录为/dir1/dir2

mkdirnewdir在当前目录下建立新目录newdir

rmdirolddir在当前目录下删除旧目录olddir

ls-l列出当前目录下所有文件

ls-la列出包括以"."开头的隐含文件

l===解决乱码或者其他中文字符集问题===

exportLC_ALL=

exportLC_CTYPE=zh_CN.gbk

l===文件操作===

rmfoobaretc删除文件foobaretc

mvfoobar文件改名foo1改成bar

mvsrc1src2…dst把文件移动到dst目录

cpsrcdst把文件src拷贝为dst

cpsrc1src2…dst把文件拷贝到dst目录

scp…root@host:path把文件拷贝到主机host的目录path下

scproot@host:pathdst.把文件从主机host的目录path下拷贝到当前目录

ln-soldnew为文件old建一个符号连接new

l===文件内容操作===

catfoo显示文件foo的内容

head-n100foo查看文件foo的前100行

tail-n100foo查看文件foo的尾100行

diff-ufoobar对比文件foo和bar

sortfoo按字母排序文件foo

sort-nfoo按数字排序文件foo

sortfoo|uniq-c统计文件foo中每行出现了多少次

fgrepxxxfiles在文件中检索字符串xxx

l===查看帮助===

manbash查看bashshell的内部命令,按q退出

infocoreutils查看最常用的那些命令,按q退出

manls查看命令ls的帮助

man-aprintf查看printf的所有帮助,按q切换到下一个帮助。像printf这样同时出现在shell/c/perl等多个环境中的命令会有多个帮助。

man-Kprintf在所有的帮助文件中搜索printf

l===简单管理===

psaux列出当前所有的进程,注意PID和COMMAND两列

top实时显示当前系统负载和最活跃的进程。

按1显示多cpu详情,按shift-m显示内存最多的进程

kill1234杀死PID为1234的进程

kill-91234强行杀死PID为1234的进程(如果kill不行的话)

netstat--anp列出当前所有的tcp/udp连接以及相关的进程

l===打包===

一般用tar打包,包有.tar.gz(.tgz)以及.tar.bz2两种格式

tarcvzfa.tar.gzfoo把foo下的所有文件打包成a.tar.gz

tarxvzfa.tar.gz把a.tar.gz解包到当前目录

tarxvjfa.tar.bz2把a.tar.bz2解包到当前目录

如何使用VIM编辑文件

首先,正确的设置vim环境会使用更加舒服,执行以下命令设置环境:

echo-e"setnocp\nsyntaxon\nsetts=4\nsetsw=4\nsetsi\n">>~/.vimrc

vimfoo启动vim,并编辑文件foo

vim和Windwos的编辑器不一样,它有2种模式:命令模式和编辑模式。刚启动vim时处于命令模式,此时可以移动光标和发布命令。常用命令:

ir<insert>进入编辑模式

<esc>离开编辑模式

:q:q!退出/强制退出

:w:w!存盘/强制存盘

:wq:wq!存盘退出/强制存盘退出

?/向前/向后查找文本

ggG移动到文件头/文件尾

dd删除当前行

vV开始选择文本/开始按行选择文本

y将v/V选中的文本放入剪贴板

p粘贴剪贴版的内容

J将下一行拼到当前行尾

:%s/old/new/g全文替换old为new

<ctrl-]>如果有maketags的话,查找当前标识符的定义

:make在当前目录执行make,并移动到第一个编译错误

Shell进阶

===egrep正则表达式检索===

egreppatternfiles在文件中检索pattern,显示匹配的行

pattern由若干atom组成,atom定义如下

.匹配任意字符

[abc]匹配abc三个字母任何一个

[^abc]匹配除abc三个字母以外的任何字符

[a-h]匹配abcdefgh中的任何一个

<atom>??前一个atom匹配0~1次

<atom>++前一个atom匹配至少1次

<atom>**前一个atom匹配任意次

<atom1>|<atom2>匹配两个atom中的任何一个

(<atom1><atom2>…)用"("和")"把多个atom编成一组

\转义符,例如"\."精确匹配".","\t"匹配tab字符

^表示一行的开始

$表示一行的结束

其他普通字符都是atom

例子:

([a-z]\.)[a-z]+匹配任何纯由小写字母组成的域名

egrep常用参数

-o显示匹配上pattern的串

-v显示没有匹配pattern的那些行

-n显示行号===输入输出重定向和管道===

一般情况下程序从键盘读取用户输入,输出到显示器。我们可以通过"<"">""|"操作符来改变这种行为。

ls>file把ls的结果存到文件file,file原有的内容被销毁i

ls>>file把ls的结果存到文件file原有内容的尾部

ls-xxx&>file把ls的错误信息和正常输出都存到文件file

foo<file用文件file作为命令foo的输入

ls|sort把ls的结果做为sort的输入

ls2>&1|sort把ls的结果和出错信息一起做为sort的输入

ls|teefile利用tee命令把ls的结果存到文件file并同时显示在荧幕上。===后台任务===

在程序运行的过程中,按ctrl-z可以把程序切换到后台挂起,此时程序暂停执行。

启动程序的时候,在命令行的最后加"&",可以让程序直接在后台执行

grepxxxfile>yyy&在后台执行grep命令

jobs显示当前后台有哪些程序

fg9把第9号后台程序切换到前台

bg9让第9号后台程序恢复执行(用于ctrl-z挂起的程序)

Windows和Linux互传文件

如果你使用SecureCRT,那么可以用rz命令传送文件到linux,用sz命令传送文件到Windows,但是这两个命令在处理大文件时往往有问题。

你可以安装winscp来传送文件

用yum或者apt-get补充安装rpm软件包

rpm是linux下常用的软件包封装格式。

rpm-ivhxxx.rpm安装xxx.rpm

rpm-qa显示系统上已经安装了哪些rpm

rpm-qlxxx显示xxx包括哪些文件,xxx需要已经安装

rpm-exxx删除xxx

rpm-qf/bin/ls查找/bin/ls属于哪个rpm包

rpm比自己下载源码要方便,但是去哪里下载rpm仍然是个问题。Linux发行版一般都附带了大量的rpm,但是并没有默认全部安装。Redhat提供了yum工具用于安装和管理系统附带的rpm软件包。使用软件和编译程序时如果发现缺少对应的工具或者库文件可以用yum补充安装。

yumsearchxxx搜索名字和描述中带有xxx的软件包。

yuminstallxxx安装xxx以及xxx依赖的rpm到最新版本。

例如,我们编译时发现找不到zlib相关的头文件。首先用”yumsearchzlib”发现有一个包叫做zlib-devel.i386,然后用”yuminstallzlib-devel”安装它即可。

某些系统用的是apt-get来管理rpm

apt-cachesearchxxx搜索xxx

apt-getinstallxxx安装xxx

参考

Bash新手指南

http://xiaowang.net/bgb-cn/

Shell设计入门

http://www.newsmth.net/bbscon.php?bid=392&id=320837

C/C++的开发GCC/GDB/Make

在Linux下,我们用gcc来编译C/C++程序,用GDB调试程序,并用make工具来把多个源文件组织成project。如果缺乏耐心的话,请直接跳到本章的最后快速指南[Makefile模板[14页]]学习如何快速开始一个项目。

gcc

gcc–theGNUCompilerCollection。能编译C,C++和一些其它语言编写的程序。

gcc特性

和其它编译器一样,gcc的编译过程可分为4个阶段:预处理,汇编,编译和链接。gcc的使用者可以在任何阶段停止整个编译过程,并得到该阶段的输出信息。

gcc也有优化代码和生成调试信息的功能,一般我们编译代码的时候,都会加入调试信息,这样代码出现问题的时候容易追查。但编译器优化过的代码往往不方便调试,因此,代码优化只有在正式上线的时候才会被使用。

此外gcc支持30多个警告和3个警告级别,支持交叉编译(生成非本机体系结构的二进制代码),还对标准C和C++进行了大量扩展,以提高执行效率和编程的方便性。但我们不建议使用这些扩展,因为这会影响代码的可移植性。

gcc使用

编译文件hello.c的基本方式是:

gcchello.c--ohello

其中hello.c是输入文件,-o选项的内容为输出文件。该命令编译并链接hello.c,生成文件为hello可执行文件。如果不加-o参数,则为gcc最简单的用法:

gcchello.c

此时gcc生成文件名为a.out的可执行文件。

编译多个源文件(如hello.c和world.c):

gcchello.cworld.c--ohelloworld

实际使用中,建议先把多个源文件编译成为目标文件,再进行链接生成可执行文件:

gcc--chello.c

gccworld.c-c

gcchello.oworld.o--ohelloworld

上例中的-c选项表示只对源文件做编译处理,生成目标文件,没有加-o参数,此时编译器生成与源文件同名的.o目标文件(为别为hello.o和world.o),第三个命令把各个.o文件链接成可执行文件。

注意各参数和输入文件在命令中顺序可任意。例如第三句可以写成(不推荐)

gcchello.o--ohelloworldworld.o

只对源文件进行预处理(包括头文件展开,宏展开等),可用-E参数。例如:

gcc--E--ohello.cpphello.c

先成的文件名为hello.cpp。在unix系统下,.cpp文件表示预处理过的C/C+文件。而对于C+源文件,一般使用.cc或.cxx的扩展名。

很多时候我们还需要观察gcc产生的汇编代码,可用-S参数:

gcc--Shello.c

此时gcc生成文件名为hello.s的汇编语言文件。

调试与优化

优化的目的是改进程序的执行效率,代价是延长编译时间,也可能会增加产生的二进制文件的大小,增大调试难度。

优化参数包括-O0,-O1(等同于-O),-O2和-O3,优化程度递增。如果不加优化参数,则相当于--O0,不优化。在O0下内联函数不会被展开。一般在编译Linux内核的时候使用参数-O2,因为O3参数会展开一些非内联函数,增加二进制代码量,这对Linux内核是不能接受的。对于一般的应用,使用O3优化也是安全的。

优化参数只需在编译的时候指定,链接时不需要,例如:

gcchello.c--c--O2

gcc--ohellohello

编译优化在理论上不会影响程序的逻辑,如果出现优化后代码运行异常,则很可能是源程序本身有bug。

gcc可通过-g参数在生成的代码里加入调试信息,以方便调试时的会话过程。和优化参数一样,-g也只需在编译的时候指定:

gcc--g--chello.c

gcc--ohellohello.o

Unix下常用的调试工具gdb(GNUDebugger)将在下一部分介绍。用户还可通过-ggdb参数来加入更多的只能被gdb识别的调试信息。

注意,尽量避免-g和-Ox一起使用。编译优化会改变代码执行顺序被打乱以加快运行速度,但调试会变得很困难。

其它常用参数

-I::指定一个头文件路径。可用多个-I参数指定多个头文件路径。只在编译时有效。

-L::指定一个库文件路径。和-I一样可指定多个。只在链接时有效,经常和-l一起使用。

-l:指定一个库文件名。Linux下库文件的文件都是libXXX.so或libXXX.a的形式,分别是动态链接库和静态链接库。例如数学函数库文件为libm.so和libm.a,SSL的函文件为libssl.so和libssl.a。gcc在链接时-l参数只需指定库文件名的中缀部分。例如hello.c中调用了数学库的cos()函数,则:

gcc--g--chello.c

gcc--ohellohello.o--lm

-Wall:实际上是-W参数加”all”。可让gcc打开所有的警告。在调试代码时建议使用。

-static:所有引用的库都静态链接。将会增加可执行文件的大小。

gdb

gdb介绍

gdb–theGNUDebugger。Linux下用得最多的命令行调试器。使用gdb对程序进行调试的前提是可执行文件有调试符号,在编译时需使用-g或-ggdb参数(见上一节),同时不打开编译优化。

gdb基础

启动gdb有三种常用的方法(直接启动,调试core文件和调试运行中的进程)。直接启动gdb的方法如下。

gdbtest

此时会启动对程序test的调试,进入gdb交互界面。

在gdb中输入run(或r)命令表示运行程序,如果程序需要参数(main的参数),在run之后加入参数即可,例如:

(gdb)runarg1arg2

run命令将运行到程序正常退出,或遇到断点,或被用户Ctrl-C,或出现异常,例如段错误(内存访问超出进程的地址空间),除0,总线错误,以及其它一些使程序无法运行下错误。当程序中断时(断点或Ctrl-C或异常),gdb会显示中断的代码位置。可用list(或l)命令来查看中断位置前后(共10行)代码。list命令每运行一次,查看10行代码,同时查看点也向后推进10行。list命令也可指定要查看的源文件名和位置,例如:

(gdb)listtest.c:100

或当前文件就是test.c的话,等价于:

(gdb)list100

此时gdb显示test.c的第95行到104行的代码。如果再敲入一次list,则显示从105行到114行。

程序中断是可用print(或p)命令来查看各变量的值。print命令支持所有C语言的语法。例如查看结构体指针a的域x:

(gdb)printa->x

通过where(或bt)命令可查看程序的中断位置,此会gdb会显示当前的函数调用层次。通过up命令可退回到上一级函数,以查看上一级函数中的变量情况。与up相对应的命令是down。

断点的使用

调试出问题的代码的时候,在某一点停止执行往往很管用。gdb支持几种不同的设置断点的方式,包括行号和函数名。还允许设置条件断点,即只有满足一定条件,代码才会在断点处停止执行。设置断点的命令为break(或b),例如:

(gdb)breaktest.c:100

(gdb)break100

(gdb)breakfunc1

(gdb)break100if(a->x==5)

其中,条件断点语句的条件部分支持C语言的所有语法。当程序在某个断点中断时,则可用上面说到的print命令来查看各变量的值,up,down命令来查看程序各级函数中的状态。注意up,down命令只会影响查看点,并不会改变程序当前执行到的位置。

让程序在断点中断之后继续运行,包括几个常用的命令。

continue(或c)命令让程序继续运行,直到遇到下一个断点;

next(或n)命令让程序执行下一条语句,如果下一条语句是函数,不进入函数内部;s

tep(或s)命令执行一下条语句,遇到函数则进入函数内部。

finish(或fin,maybe)可让程序继续运行,直到当前函数返回;

return(或ret?)命令让函数立即返回,返回后程序仍处于中断状态。return命令可加返回值,例如:

(gdb)return20

即让当前函数立即返回,返回值为20。注意的时让函数从一个非正常的点返回,后果可能很严重,但在调试中有时也很有用。在程序中断时还可以通过call命令来调用函数,例如:

(gdb)calla=func(20)

此时gdb调用了func函数并把返回值赋予变量a。如果func函数中也有断点,程序也会在断点处被中断。

如果要删除某个断点,首先找到要删除断点的id号,方法是:

(gdb)infobreak

此时gdb会显示当然的所有断点位置和对应的id。用delete(或del?)命令加id号删除对应的断点;delete不加参数则删除所有的断点。另外,用disable和enable命令可让断点临时关闭和重新打开。

调试core和调试进程

对于运行中的进程,如果出现一些异常无法继续运行,会在程序的运行目录下留下一个core文件,就是我们常说的“程序core了”。core的原因是程序/进程收到了某些会让程序core的信号(准确的说是让程序流产的信号),常见的有SIGSEGV(程序出现段错误,越界访问,最常见),SIGABRT(如程序调用了abort()函数,abort本身就是流产的意思),SIGFPE(浮点异常)。当程序core了之后,会在运行目录留下一个core文件,文件名为core.XXXX,XXXX为进程号pid。如果发现怎么程序异常退出却没有core文件,系统设置的问题。用以下命令允许产生无限大的core文件:

ulimit--cunlimited

假设我们的程序名为test,产生了文件名为core.1234的core文件,通过以下命令启动gdb来调试core:

gdbtestcore.1234

进入gdb之后,会显示出程序异常的位置。再通过上面介绍的gdb命令查看异常时程序的状态,就可以比较方便的找到程序bug所在。注意程序core了之后已经不在运行状态,因此和运行相关的命令,如run,continue,next,step,finish,return,call,在调度core的时候无法使用。break也是没有意义的。

gdb还可以调试一个正在运行中的进程,方法是:

gdb--p<进程号>

进入gdb之后进程被gdb中断,gdb显示中断位置。此时调试的方法与普通启动gdb方式几乎无异,也可以使用运行相关命令来控制进程的推进。唯一的区别是,使用exit(或Ctrl-D)命令退出后,被调试的进程会继续运行,而不是结束。

其它常用命令

kill–杀死当前的调试进程,对于core调试无效,因为core已经是死掉的进程。

infothread–显示所有线程和id号。

thread<id>–切换到某个线程。

setvariable<variablename>=<expression>–改变变量的值,对core调试无效,支持C语法。例如:

(gdb)setvariablei=x+5

ptype<variable>–显示变量的数据类型。

shell[cmd]–执行一个shell命令。如果[cmd]为空,则进入shell。在shell中exit或Ctrl-D返回gdb。

help–当你需要其它帮助。

Makefile

Makefile的原始形式

Make是linux最基本的工程描述工具。编写Makefile以后,简单的键入makeall就能方便的编译整个项目而不用一次次手工调用gcc。先来看一下一个最基本的Makefile,它描述了如何从s1.cpps2.cpp编译产生程序test:

objects=s1.os2.o##变量定义

all:test##一般用all表示生成所有目标

test:$(objects)##普通依赖关系

g++$+-o$@##从s1.os2.o如何生成test

%.o:%.cpp##从.cpp文件编译.o的依赖模板

g++-g-O2-c$<##具体如何编译

clean:##一般用clean表示清除所有目标和中间文件

rm-ftest*.o##

[kirbyzhou@sohu]$make##编译test

g++-g-O2-cs1.cpp

g++-g-O2-cs2.cpp

g++s1.os2.o-otest

[kirbyzhou@sohu]$make##再次编译,因为文件没有变化,所以什么都没发生

make:Nothingtobedonefor`all'.

[kirbyzhou@sohu]$makeclean##清理

rm-ftest*.o

Makefile的文件名必须是严格的”Makefile”,make会在当前目录下查找Makefile文件。Makefile主要由3部分组成:1.变量定义;2普通依赖关系(explicitrule);3.模板依赖关系(implicitrule)。格式分别如下:

TARGET:PREREQUISITES##TARGETS直接依赖于PREREQUISITES

<TAB>COMMAND##从PREREQUISITES如何产生TARGET

%.DST:%.SRC##.dst文件依赖于.src文件,例如.o和.cpp的关系

<TAB>COMMAND##从PREREQUISITES如何产生TARGET

在COMMAND中可以用$+表示PREREQUISITES,用$@表示TARGET,用$<表示第一个PREREQUISIT。例子参见上文。

用Automake/Autoconf自动生成makefile

涉及的文件增多以后,Makefile变得很难维护。首先是依赖关系的复杂性:s1.o不仅仅是依赖于s1.cpp,它可能还依赖于s1.hs2.hs3.h等等;其次如何生成库、动态库等等都比较复杂;各人的Makefile风格迥异很难修改;最后是缺乏统一的子目录管理机制。总之靠人工来维护Makefile是非常辛苦的。为此人们发明了一系列工具用于简化Makefile的编写,并统一Makefile的风格。

automake/autoconf是一套比较成熟的工具,它主要涉及到1个configure.ac和若干个Makefile.am

lMakefile.am一般每个子目录一个,一个最简单的Makefile.am如下,已经可以满足绝大部分的需求:

bin_PROGRAMS=demo1demo2##我要编译demo1demo2这两个程序

lib_LTLIBRARIES=libdemo3.la##我要编译libdemo3.la这个库

demo1_SOURCES=demo1.cppfunc.cppf.h##demo1的源码

demo2_SOURCES=demo2.cppfunc.cppf.h##demo2的源码

libdemo3_la_SOURCES=demo3.cppdemo3.h##libdemo3.la的源码

SUBDIRS=sub1sub2##如果有子目录要build的话,列在这里

Makefile.am首先定义需要build哪些target,语法如下:

[bin|lib|libexec|…|noinst]_[SCRIPTS/PROGRAMS|LIBRARIES|LTLIBRARIES]=target1target2…

其中””前说明target会被安装到$(prefix)下的哪个目录,noinst表示不安装;””后是target的类型------脚本/可执行程序/静态库/动态库。注意静态库和动态库分别要满足lib*.alib*.la的命名。

然后是每个target相关的源码,automake会自己处理源码间的关系:

<target>_SOURCES=src1.csrc2.cppheader1.hheader2.hpp

这里如果target是X.Y这样的形式,要写成X_Y_SOURCES=…的形式

l在项目的topdir里还需要一个configure.ac,描述一些全项目的信息

AC_PREREQ(2.57)##样板戏,不用管它,下同

AC_INIT(demopkg,0.5.1)##整套程序的名字、版本号

AM_INIT_AUTOMAKE([foreign])##样板戏,让autoconf按最糙的要求审核我们的程序

AC_PROG_CC##样板戏,检查C编译器

AC_PROG_CXX##样板戏,检查C++编译器

AC_PROG_LIBTOOL##样板戏,检查用于生成动态库的libtool工具

AC_CONFIG_FILES([

Makefiledemo/Makefile##在[]里列出需要自动生成的Makefile

])

AC_OUTPUT##最后一行样板戏

l最后执行autoreconf--is&&./configure就可以开始make了。

l常用的make目标有all(缺省target,build项目),clean(清理),install(安装),uninstall(反安装),check(测试),dist(源码打包),distcheck(检查打包后的源码能否正常工作)。

快速指南:

===编写Makefile===

编写Makefile参见[Makefile模板[14页]]

make用makefile编译整个工程

makeclean清除make的结果和中间文件

===GCC===

gcca.c编译纯C程序a.c为可执行程序a.out

g++-gs1.ccs2.cpp-odest把源文件s1.ccs2.cpp编译成可执行程序dest

g++-g-O0src.cpp-odest禁止优化的编译,这样方便调试

g++-I/opt/include…附加的include目录

g++-L/opt/lib-lACE…附加的lib目录,并链接库libACE.so

====GDB===

gdbtest调试程序test

gdbtest12345调试进程PID为12345的程序test

gdbtestcore.123调试程序test崩溃后留下的现场core.123

ulimit--cunlimited使程序崩溃后有机会留下现场

====GDB命令===

rarg1arg2…运行程序,arg1arg2…是传给程序的参数

l列出代码

la.cpp:100列出a.cpp第一百行附近的代码

b100在第100行设置断点

<ctrl-c>中断程序

px打印变量x的值

setvariablex=y+2改变变量的值

n/s/c单步/深入单步/继续

bt察看函数调用层次

up/down转到上一级/下一级函数

kill杀死当前的调试进程

infothread显示所有线程和id号

thread3切换到线程3

参考

GCC常见编译选项

http://dev.csdn.net/author/ganxingming/d4fabf69cc48471fbcbc7b9be2a908dc.html

GDB手册http://www.newsmth.net/bbs0an.php?path=%2Fgroups%2Fcomp.faq%2FLinuxDev%2Fdevelop%2Fgdb_linuxdev

GNUmake指南

http://www.newsmth.net/bbs0an.php?path=%2Fgroups%2Fcomp.faq%2FLinuxDev%2Fdevelop%2Fmakefile

使用automake和autoconf管理项目的上手指南

http://blog.donews.com/idlecat511/archive/2006/01/17/698470.aspx

http://cvs.so.sohu.com:2080/svn/arch/trunk/Projects/MakefileDemo/

文档工具

Doxygen

Doxygen是开源(GPL)的文档工具,可以自动根据类之间的调用关系生成UML图,也支持类似javadoc的从注释中提取文档的功能。

Doxygen可以直接生成html,LaTeX,rtf等格式的文档。

Doxygen的项目主页在http://www.doxygen.org/。生成图片需要Graphviz(http://www.graphviz.org/)程序的支持。

程序中的注释块

Doxygen支持的注释格式如下:

l/*或者/!开头:

/**

*@briefputresultbacktooutputmodule

*

*@paramseqtheseqoftherequest

*@paramresulttheresult

*

*@return0onsuccessful,otherwiseanerrornumber

*/

virtualintput_result(constseq_t&seq,constresult_t&result)=0;

l///或者//!开头:

///thesuperclassforoutputmodule

classBase_Output{

l还可以用增加一个<来为注释前面的代码写文档(默认为注释后面的),这种情况在定义enum的时候很有用:

/**

*@briefenumerateforsupportedproducts

*/

关于更多的程序中的注释块的说明可以参考官方文档

常用命令

命令以@或者\开头,用来指定后面文字的形势,比如@brief,\return等。

常用命令如下:

lbrief:简短说明

ldetails:详细说明

lparam:参数说明,后面跟的第一个单词为参数名

lreturn:返回值说明

lclass:类名,可以省略

lfile:文件名,可以省略

lauthor:作者

完整的命令列表请见官方文档(http://www.stack.nl/~dimitri/doxygen/commands.html)

配置文件

与make类似,doxygen的默认配置文件为当前目录下的Doxyfile文件,http://www.sohu-rd.com/images/f/fe/Doxyfile.doc是一个example,注意要去掉.doc扩展名

在这个例子里面,一般来说你需要更改的东西有:

lPROJECT_NAME:项目的名字

lPROJECT_NUMBER:项目的版本号

lTAB_SIZE:制表符的宽度

lINPUT:源代码的路径

lHTML_OUTPUT:输出的html文档的路径

lLATEX_OUTPUT:输出的LaTeX文档的路径

lRTF_OUTPUT:输出的rtf文档的路径

准备好配置文件后,在配置文件(Doxyfile)所在目录执行doxygen就可以生成文档。按照这个例子,doxygen会对Code子目录下面的所有代码生成文档,其中html文档生成到html子目录下,LaTeX文档生成到latex子目录下,rtf文档生成到rtf子目录下。

其它

l如果使用vim作为编辑器,可以安装DoxygenToolkit这个插件,这个可以对你已经写好的函数头、类头等自动生成doxygen注释框架。

l一个doxygen注释的源代码的例子在http://www.sohu-rd.com/images/7/7e/Core_Manager.h.doc,注意要去掉.doc扩展名

版本管理工具

SVN

SVN是CVS的进化版本,最主要的区别是SVN为整个Repository维护一个统一的版本号以避免混乱。建议在Windows下用TortotiseSVN。

svn中的trunk目录对应CVS的HEAD/MAIN分支,SVN中没有传统CVS的branch/tag,而是通过在branches/tags目录下建立原始文件的拷贝来模拟:

cvstagbranch_name:svncopy.branch_path

cvsup-rtag_name:svnswitchtag_path

WorkCopy的概念和CVS类似,注意,一般不checkout整个respository,而是checkouttrunk或某个分支

svn命令行简明参考手册

lPrestart

l创建仓库(Repository)

svnadmincreate/path/to/repository

svnadmin是有用的subversion系统管理命令,使用svnadminhelp查看在线帮助

信息。subversion的手册推荐在项目在repository下分别建立branches/tags/trunk/三个目录,分别存放分支/标签/主分支

l检出(checkout)项目

svncheckoutfile:///.../trunk/project

svncheckouthttp://host/.../trunk/project

l列出仓库中的项目(list)

svnlist-verbosefile:///.../tags/

svnlist-verbosehttp://.../trunk/

l状态查询(status)

svnstatus

给出新文件,已经改变的文件和被删除的文件列表

l添加文件或目录(add)

svnadd

l删除文件或目录(delete)

svndelete

svndeletehttp://host/svn_dir/repository/project_dir这条命令可以用来删除错误的import的某些项目!!

l回滚workcopy的修改

svnrevertfile1file2

svnrevert-R.

l提交(commit)

svncommithttp://host/svn_dir/repository/project_dir

l更新(update)

svnupdate

更新仓库中的文件到本地。

l删除重命名和移动(update)

svndelete(del,remove,rm)

svnmove(mv,rename,ren)

l使用COPY命令管理Tag和Branch

svncopyhttp://host/repos/project/trunkhttp://host/repos/project/tags/1.0.0

用于创建某个特定版本的快照(snapshot);

svnlisthttp://host/repos/project/tags/1.0.0

查看某个版本的内容

svnswitchbranch_url

把workcopy切换到某个分支

l版本合并

svnmerge-rN:Mbranch.

把branch上版本N和M之间的修改合并到当前目录

branch可以是url或者本地目录

svnmergetagbranch.

把tag和branch之间的修改合并到当前目录

svnlog-qv--stop-on-copyhttp://svnhost/svn/repo/branches/br1

查看某个branch的修改日志从而决定从哪个版本开始merge

l快速查看当前workcopy的版本号(svnversion)

svnversion

给出新文件,已经改变的文件和被删除的文件列表;

参考

CVS中文手册

http://man.chinaunix.net/develop/cvsdoc_zh/

使用Subversion进行版本控制

http://svnbook.red-bean.com/index.zh.html

相关推荐