开元周游
德国频道
查看: 1397|回复: 4
打印 上一主题 下一主题

第二讲:常用开发工具 zz

[复制链接]
1#
发表于 28.11.2002 12:59:28 | 只看该作者
即时机票
                       讲义下载:http://263.aka.org.cn/Lectures/001/Lecture-2/Lecture-2.zip<br>tgz:http://263.aka.org.cn/Lectures/001/Lecture-2/Lecture-2.tgz<br><br><br>第二讲:常用开发工具<br><br>4/7/2000, BluePoint Software, Eric Lee<br><br>主要内容<br><br>     diff / patch &amp;#0; 原代码维护基本命令<br><br>     RCS &amp;#0; 简单版本控制系统(Revision Control System)<br><br>     CVS &amp;#0; 并发版本管理系统(Concurrent Versions System)<br><br>     RPM包管理器<br><br>    <br><br> <br><br>AKA 自由软件系列讲座                       
2#
 楼主| 发表于 28.11.2002 12:59:51 | 只看该作者
                       diff<br><br>  diff是生成源码补丁的必备工具。其命令格式为:<br><br> diff [命令行选项] 原始文件 新文件<br><br>常用命令行选项如下:<br><br>   -r 递归处理目录     -u 输出统一格式(unified format)<br><br>   -N patch里包含新文件   -a patch里可以包含二进制文件<br><br>  它的输出在stdout上,所以你可能需要把它重定向到一个文件。<br>diff的输出有“传统格式”和“统一格式”之分,现在大都使用统一格式:<br><br>  传统格式示例:<br><br>   [hahalee@builder]$ diff a.txt b.txt<br><br>   1a2<br><br>   &gt; here we insert a new line<br><br>   3d3<br><br>   &lt; why not this third line?<br><br>  统一格式示例:<br><br>   [hahalee@builder]$ diff -u a.txt b.txt<br><br>   --- a.txt Thu Apr 6 15:58:34 2000<br><br>   +++ b.txt Thu Apr 6 15:57:53 2000<br><br>   @@ -1,3 +1,3 @@<br><br>   This is line one<br><br>   +here we insert a new line<br><br>   and this is line two<br><br>   -why not this third line?<br><br>  通过比较可以看出,传统格式的patch文件比较小,除了要删除/插入的行外没有冗余信息。<br>统一格式则保存了上下文(缺省是上下各三行,最少需要两行),这样,patch的时候可以允许<br>行号不精确匹配的情况出现。另外,在patch文件的开头明确地用---和+++标示出原始文件和当<br>前文件,也方便阅读。要选用统一格式,用 u 开关。<br><br>  通常,我们需要对整个软件包做修改,并生成一个patch文件,下面是典型的操作过程。<br>这里就要用到前面介绍的几个命令行开关了:<br><br>  tar xzvf software.tar.gz # 展开原始软件包,其目录为software<br><br>  cp _a software software-orig # 做个修改前的备份<br><br>  cd software<br><br>  [修改,测试……]<br><br>  cd ..<br><br>  diff _ruNa software-orig software &gt; software-my.patch<br><br>  现在我们就可以保存software-my.patch做为这次修改的结果,至于原始软件包,可以不必保存。<br>等到下次需要再修改的时候,可以用patch命令把这个补丁打进原始包,再继续工作。比如是在linux<br> kernel 上做的工作,就不必每次保存几十兆修改后的源码了。这是好处之一,好处之二是维护方便,<br>由于unified patch格式有一定的模糊匹配能力,能减少原软件包升级带来的维护工作量(见后)<br><br> <br><br>patch<br><br>  patch命令跟diff配合使用,把生成的补丁应用到现有代码上。常用命令行选项:<br><br>  patch [命令行选项] [待patch的文件[patch]]<br><br>  -pn patch level(n是数字) -b[后缀] 生成备份,缺省是.orig<br><br>为了说明什么是patch level,这里看一个patch文件的头标记。<br><br>  diff -ruNa xc.orig/config/cf/Imake.cf xc.bsd/config/cf/Imake.cf<br><br>  --- xc.orig/config/cf/Imake.cf Fri Jul 30 12:45:47 1999<br><br>  +++ xc.new/config/cf/Imake.cf Fri Jan 21 13:48:44 2000<br><br>  这个patch如果直接应用,它会去找xc.orig/config/cf目录下的Imake.cf文件,假如你的源码树<br>的根目录是缺省的xc而不是xc.orig,除了mv xc xc.orig之外,有无简单的方法应用此patch呢?<br>patch level就是为此而设:patch会把目标路径名砍去开头patch level个节(由/分开的部分)。<br>在本例中,可以用下述命令:cd xc; patch _p1 &lt; /pathname/xxx.patch 完成操作。<br>注意,由于没有指定patch文件,patch程序默认从stdin读入,所以用了输入重定向。<br><br>  如果patch成功,缺省是不建备份文件的(注:FreeBSD下的patch工具缺省是保存备份),如果你需要,<br>可以加上 b 开关。这样把修改前的文件以“原文件名.orig”的名字做备份。如果你喜欢其它后缀名,<br>也可以用“b 后缀”来指定。<br><br>  如果patch失败,patch会把成功的patch行给patch上,同时(无条件)生成备份文件和一个.rej文件。<br>.rej文件里是没有成功提交的patch行,需要手工patch上去。这种情况在原码升级的时候有可能会发生。<br><br>  关于二进制文件的说明:binary文件可以原始方式存入patch文件。diff可以生成(加-a选项),<br>patch也可以识别。如果觉得这样的patch文件太难看,解决方法之一是用uuencode处理该binary文件。                       
3#
 楼主| 发表于 28.11.2002 13:00:11 | 只看该作者
                         单个文件的版本控制/管理,适合对少量文件进行版本控制,不适合小组进行项目协作开发。优点:使用简便;<br>缺点:功能有限。RCS常用命令有ci/co/rcsdiff。<br><br>  rcs用一个后缀为“,v”的文件保存一文件的内容和所有修改的历史信息,你可以随时取出任意一个版本,<br>用rcs保存程序就不必为不同版本分别备份。下面是一个“,v”文件的例子:<br><br> (太长,忽略。请看演示或自己找一个样本)<br><br>  rcs文件里记载了每次更新的日期、作者、还有更新说明(Log)。文件的最新版本内容放在Log之后,<br>再后面是历次版本与其后一版本的差别,按check in的时间做倒序排列。这么做的原因是因为新版本的<br>check out机会大些,倒序排列可优化check out时间。<br><br>   ci _ check in,保存新版本<br><br>  此命令把指定文件添加到rcs历史文件中,同时把该文件删除。如果当前目录下有个RCS目录,ci会<br>把历史文件存在此处,否则放在当前目录下。<br><br>   [hahalee@builder]$ mkdir RCS<br><br>   [hahalee@builder]$ ci wood.txt<br><br>   RCS/wood.txt,v &lt;-- wood.txt<br><br>   enter description, terminated with single &#39;.&#39; or end of file:<br><br>   NOTE: This is NOT the log message&#33;<br><br>   &gt;&gt; initial checkin #NOTE: 这里是给本次checkin做的说明<br><br>   &gt;&gt; .<br><br>   initial revision: 1.1<br><br>   done<br><br>   [hahalee@builder]$ ls -l RCS/<br><br>   总共 4<br><br>   -r--r--r-- 1 hahalee hahalee 451 Apr 7 07:27 wood.txt,v<br><br>  ci也有丰富的命令行选项,比如,可以指定check in的版本号,甚至可以用字符串来做版本号,<br>请查阅ci的manpage。<br><br>   co _ check out,取出当前(或任意)版本<br><br>常用命令行选项:<br><br>  -r[rev] 指定版本的checkout -l[rev] 指定版本,加锁的checkout<br><br>  如不加可选的版本号,缺省是最近的版本。如果只需要一份只读的拷贝,用-r(特殊情况,如需要<br>一份只读的当前拷贝,可以不要任何选项)。如需要对checkout的文件进行修改,请用-l选项。常见<br>的操作流程是:<br><br>   ci xxx.c; co _l xxx.c; 编辑,测试; ci xxx.c …………<br><br>  在每次checkin的时候,版本号会自动在最低位上加1。为了在文件中反映版本控制信息,rcs提供<br>了几个特殊的关键字,这里介绍$Id$和$Log$,其它的请参考info cvs。<br><br>  $Id$代表文件的版本标识,由文件名/版本号/最后一次checkin时间/最后一次checkin的用户这几<br>项组成,比如:<br><br>$Id: wood.txt,v 1.3 2000/04/07 00:06:52 hahalee Exp $<br><br>如果需要更详细的信息,可以用$Log$,$Log$被扩展为该文件的所有修改日期和备注,例:<br><br>    /* $Log: wood.txt,v $<br><br>    * Revision 1.2 2000/04/07 00:29:12 hahalee<br><br>    * This is my second checkin<br><br>    *<br><br>    * Revision 1.1 2000/04/07 00:28:39 hahalee<br><br>    * Initial revision<br><br>    * /<br><br>  顺便介绍一下ident命令。它的功能比较简单,就是从文件中搜索出RCS标示符并打印出来。<br>可以用ident /usr/sbin/sendmail 来看看。不用说,如果想在最终的binary文件里找到$Id$串,<br>得要把它声明到一个字符串里去。很多程序里这么写:<br><br>    #ifndef lint //这里是为了避免lint报告“变量未使用”<br><br>    static const char rcsid[] =<br><br>   &quot;$Id: bin/sh.c,v 1.15 1999/08/27 23:13:43 wp Exp $&quot;; //这是从 $Id$ 扩展                                                                                                                                                <br>  //出来的<br><br>    #endif<br><br>   rcsdiff _ 比较revision之间的差异.运行diff命令,生成patch文件<br><br>命令行格式:rcsdiff [选项] [-r版本[-r版本]] [diff选项] 文件名<br><br>  说明:如果没给出版本号,把上次checkin的内容同当前工作文件比较;如给出了一个版本号,<br>就把那个版本的内容同当前工作文件比较;若给出了两个版本号,则用第一个来跟第二个比较。<br>由于rcsdiff调用diff命令,所有的diff选项都可用。它的输出也是加了额外信息的diff格式内容,<br>可以给patch使用。<br><br>  rcs里面还有rcs,rcsclean,rlog,merge,rcsmerge我们没有提到,有的特别简单有的特<br>别繁琐且用得少。其中rcs命令可以用来对rcs文件进行各种精细的维护,最为复杂。                       
4#
 楼主| 发表于 28.11.2002 13:00:36 | 只看该作者
                       <br><br> <br><br>  CVS,顾名思义,是个可以用在小组协作环境下的源码版本管理系统。同类的软件有AT&amp;T的SCCS(Source Code Control System),还有PVCS等。在OpenSource项目里CVS用得最为广泛, Linux kernel不使用CVS来维护,下面我们将会参考FreeBSD的源码管理来做示例。CVS是个相当复杂的系统,FreeBSD甚至设有专门的“CVS管理员”(CVS “Maester”)来全面负责项目的CVS repository维护。<br><br>  下面介绍与CVS相关的若干概念和术语:<br><br>    Repository:   “源码仓库”,CVS存放的项目源码历史档案<br><br>    CVSROOT:     该环境变量指明CVS Repository存放的目录<br><br>    Module:      模块。就是CVSROOT下的顶级目录名<br><br>    Vendor Branch:  分支。在一套Repository里可以存放多个代码分支的历史<br><br>    Release Tag:   发行标记。对于每一个版本,可以用符号来做标记<br><br>  下面是一个CVS repository的版本衍生图,大致描绘了FreeBSD的版本发行情况。图中的RELENG_3和RELENG_4表示“Release Engine”,也就是Vendor Branch,每个Branch分头发展,等某个Branch的开发到了一定的质量水准,就做个Release Tag。比如最近的4.0-RELEASE的Release Tag是REL_4_0。<br><br>  这些不同的Branch都存放在同一个Repository Tree里。<br><br> <br><br> <br><br> <br><br>  CVS是个很复杂的系统,可以参考下面两个URL获得进一步的信息:<br><br><a href='http://www.cyclic.com' target='_blank'>http://www.cyclic.com</a><br><br><a href='http://www.loria.fr/~molli/cvs-index.html' target='_blank'>http://www.loria.fr/~molli/cvs-index.html</a><br><br>(在cvs软件包里含有详细的文档,应当查阅info版本。几个ps文件都太老了)<br><br>下面介绍CVS的基本用法。<br><br>① Import 导入/创建CVS Repository Tree<br><br>  首先建一个目录作为你的CVSROOT,然后用cvs init命令对其初始化(建立一系列log,config文件)。然后到工作目录下使用cvs import命令:<br><br>   [hahalee@builder]$ mkdir /home/hahalee/CVS<br><br>   [hahalee@builder]$ export CVSROOT=/home/hahalee/CVS<br><br>   [hahalee@builder]$ cvs init<br><br>   [hahalee@builder]$ cvs import _b 0.5.0 hftpd RELENG_0 REL_0<br><br>   N hftpd/tar.h<br><br>   N hftpd/auth.h<br><br>   [blah...blah...blah...]<br><br>   N hftpd/docs/rfcs/rfc0959.txt<br><br>   N hftpd/docs/rfcs/rfc2428.txt<br><br>   No conflicts created by this import <br><br>  上述操作在$CVSROOT下生成hftpd目录,可以看到里面都是后缀为“,v”的文件,这就是import进来的Repository。RELENG_0是vendor-tag,REL_0是release-tag。vendor-tag就是vendor branch tag,可以理解为”code name”。<br><br>② Checkout 创建私有工作目录/Export<br><br>  换一个空目录,运行 cvs checkout modules_name 即可:<br><br>   [hahalee@builder]$ cvs checkout hftpd# hftpd是我们的module name<br><br>   cvs checkout: Updating hftpd<br><br>   U hftpd/AUTHORS<br><br>   U hftpd/COPYING<br><br>   [blah blah blah] # 省略许多<br><br>   [hahalee@builder t]$ ls -l<br><br>   总共 0<br><br>   drwxrwxr-x 5 hahalee hahalee 1253 Apr 7 20:08 hftpd<br><br>   [hahalee@builder t]$ find ./ -type d<br><br>  从最后一条命令的输出可看到,checkout的工作目录里多了CVS目录。里面记载了CVS相关的信息,可以方便后续的cvs操作。如果纯粹是为了拷贝出最新的source tree,可以用export,此时不会建立CVS目录。<br><br>③ Update 更新<br><br>  当你完成某一部分代码的时候,先不忙提交,可以把别人可能做了的其他修改update过来然后统一编译调试无误后再提交,这是team work的准则。在checkout出来的工作目录下(不管什么子目录),直接cvsup update 就可以了,当然你要先把CVSROOT环境变量设置好。<br><br>④ Commit 提交<br><br>  很简单,cvs commit。但你必须要在checkout出来的工作目录里提交才行:<br><br>   [hahalee@builder]$ cvs commit<br><br>   cvs commit: Examining .<br><br>   cvs commit: Examining docs<br><br>   cvs commit: Examining docs/man<br><br>   cvs commit: Examining docs/rfcs<br><br>   cvs commit: Examining tools<br><br>   Checking in AUTHORS;<br><br>   /home/hahalee/CVS/hftpd/AUTHORS,v &lt;-- AUTHORS<br><br>   new revision: 0.6; previous revision: 0.5<br><br>   done<br><br>  关于并发提交冲突:任何用户可以随意checkout他们自己的工作拷贝,commit也是不受限制的。这样,当用户a和b分别checkout了1.2版的c.c,然后各自对c.c做了修改,a提交了他的修改,然后,当b提交的时候,冲突就产生了。<br><br>  这时候,cvs会做以下动作:<br><br>告诉用户b,对c.c的提交发生冲突 <br>对用户b当前的c.c做备份文件.#c.c.1.2 <br>试图合并a和b的修改,生成新的c.c<br>然后,用户b应当修改c.c,去掉/合并冲突的行,并以版本1.4提交。<br><br>⑤ Diff<br><br>  可以用类似rcsdiff的方法用cvs生成patch,命令行语法也类似<br><br>   [hahalee@builder]$ cvs diff -u -r0.5 AUTHORS<br><br>   Index: AUTHORS<br><br>   ===================================================================<br><br>   RCS file: /home/hahalee/CVS/hftpd/AUTHORS,v<br><br>   retrieving revision 0.5<br><br>   retrieving revision 0.6<br><br>   diff -u -r0.5 -r0.6<br><br>   --- AUTHORS 2000/04/07 10:46:02 0.5<br><br>   +++ AUTHORS 2000/04/07 14:05:57 0.6<br><br>   @@ -1,3 +1,4 @@<br><br>   +ah&#33; let me in&#33;<br><br>   So then, who can&#39;t spell<br><br>   Develloppopotamus?<br><br>   Quite a lot of us.<br><br>  还有一个rdiff,用来生成两个不同的release 之间的patch。<br><br>⑥ 其他操作<br><br>   cvs 的其他操作还包括有:<br><br>   admin 管理功能<br><br>   tag 对某一版本做符号标记<br><br>   release 取消checkout,删除工作目录(release在这里是“释放”的意思)<br><br>   add,remove 往repository里添加/删除文件<br><br>   history 查看repository操作历史记录<br><br>⑦ CVS 的多平台特性以及C/S扩展<br><br>  cvs是多平台的,开发可以在多种平台比如,可以把linux上的CVS Repository通过samba export出来在Windows平台上做开发。现在很多软件包里包含有*NIX/Windows/MacOS等多平台支持代码,cvs的跨平台特性可提供最好的多平台开发支持。<br><br>  不过,cvs的操作是直接基于文件系统的,在需要大量远程协作的场合问题很多,远程的NFS mount效率太差,也会有安全问题。新版本的cvs自身内建了Client/Server支持,也可以利用Unix上传统的远程交互手段来通讯。<br><br>  1,通过rsh(也可用ssh替换)<br><br>  2,使用cvs自带的C/S用户认证:pserver(缺省端口2401)<br><br>  3,使用kerberos的gserver、kserver<br><br> <br><br>  <br>                       
5#
 楼主| 发表于 28.11.2002 13:04:24 | 只看该作者
                       <br><br> <br><br>(概要,sorry for short of time)<br><br>一,RPM的基本用法<br><br>1,安装(-i),卸载(-e),查询(-q),检查(-V,--checksig)<br><br>2,生成rpm包<br><br>二,SPEC文件的格式,及build的步骤<br><br>三,讨论:好的包管理器的若干要点<br><br>1,基本功能<br><br>2,多种介质支持<br><br>3,要有sub package管理<br><br>4,UI接口/支持<br><br> <br><br><br>                       
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点信息

站点统计| 举报| Archiver| 手机版| 小黑屋

Powered by Discuz! X3.2 © 2001-2014 Comsenz Inc.

GMT+1, 16.11.2024 04:31

关于我们|Apps

() 开元网

快速回复 返回顶部 返回列表