Unix or Linux 软件开发工具速查
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