??xml version="1.0" encoding="utf-8" standalone="yes"?>青草影院天堂男人久久,久久久久亚洲av无码专区,久久丫精品国产亚洲av不卡http://www.shnenglu.com/jjbird/category/948.html奇奇的空?/description>zh-cnTue, 20 May 2008 08:00:53 GMTTue, 20 May 2008 08:00:53 GMT60Linux下Y件安装详?/title><link>http://www.shnenglu.com/jjbird/articles/5770.html</link><dc:creator>奇奇</dc:creator><author>奇奇</author><pubDate>Mon, 17 Apr 2006 09:04:00 GMT</pubDate><guid>http://www.shnenglu.com/jjbird/articles/5770.html</guid><wfw:comment>http://www.shnenglu.com/jjbird/comments/5770.html</wfw:comment><comments>http://www.shnenglu.com/jjbird/articles/5770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jjbird/comments/commentRss/5770.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jjbird/services/trackbacks/5770.html</trackback:ping><description><![CDATA[ <table cellspacing="0" cellpadding="10" align="left" border="0"> <tbody> <tr> <td> <br /> </td> </tr> </tbody> </table> <font size="2">在Windows下安装Y件时Q只需用鼠标双击Y件的安装E序Q或者用Zip{解压羃软g解压~即可安装。在Linux下安装Y件对初学者来_隑ֺ高于Windows下Y件安装。下面我pl讲解Linux下如何安装Y件?<br /><br />先来看看Linux软g扩展名。Y件后~?rpm最初是Red Hat Linux提供的一U包装格式Q现在许多Linux发行版本都用;后缀?deb是Debain Linux提供的一U包装格式Q后~?tar.gz、tar.Z、tar.bz2?tgz是用Unixpȝ打包工具tar打包的;后缀?bin 的一般是一些商业Y件。通过扩展名可以了解Y件格式,q而了解Y件安装?<br /><br /><b>RPM格式软g包的安装</b><br /><br />1.?br />几乎所有的Linux发行版本都用某UŞ式的软g包管理安装、更新和卸蝲软g。与直接从源代码安装相比QY件包理易于安装和卸载;易于更新已安装的软g包;易于保护配置文gQ易于跟t已安装文g?<br /><br />RPM全称是Red Hat Package ManagerQRed Hat包管理器Q。RPM本质上就是一个包Q包含可以立卛_特定机器体系l构上安装和q行的Linux软g。RPMC意图见??<br /><br /></font> <center> <font size="2"> </font> </center> <br /> <br />大多数Linux RPM软g包的命名有一定的规律Q它遵@名称-版本-修正?cdQMYsoftware-1.2 -1.i386.rpm ?<br /><br />2.安装RPM包Y?<br />Q rpm -ivh MYsoftware-1.2 -1.i386.rpm <br /><br />RPM命o主要参数Q?<br /><br /><ccid></ccid><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid>-i 安装软g?br />-t 试安装Q不是真的安装?<br />-p 昄安装q度?br />-f 忽略M错误?br />-U 升安装?br />-v 套件是否正安装?/ccid></pre></td></tr></tbody></table><br /><br />q些参数可以同时采用。更多的内容可以参考RPM的命令帮助?<br /><br />3.卸蝲软g <br />Q rpm -e 软g?<br /><br />需要说明的是,上面代码中用的是Y件名Q而不是Y件包名。例如,要卸载software-1.2.-1.i386.rpmq个包时Q应执行Q?br />Qrpm -e software <br /><br />4.卸蝲RPM?br />有时除去一个RPM是不行的Q尤其是pȝ上有别的E序依赖于它的时候。如果执行命令会昄如下错误信息Q?<br /><br /><ccid></ccid><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid>Q? rpm -e xsnow<br />error: removing these packages would break dependencies:<br /> /usr/X11R6/bin/xsnow is needed by x-amusements-1.0-1</ccid></pre></td></tr></tbody></table><br /><br />在这U情况下Q可以用--force选项重新安装xsnowQ?<br /><br /><ccid></ccid><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid>Q? rpm -ivh --force xsnow-1.41-1.i386.rpm<br />xsnow</ccid></pre></td></tr></tbody></table><br /><br />q里推荐使用工具软gKleandiskQ用它可以安全彻底清理掉不再使用的RPM包。详l情况请查看2003q《开攄l世界》第12期?<br /><br />5.安装.src.rpmcd的文?br />目前RPM有两U模式,一U是已经q编码的Qi386.rpmQ,一U是未经~码的(src.rpmQ?br />rpm --rebuild Filename.src.rpm <br /><br />q时pȝ会徏立一个文件Filenamr.rpmQ在/usr/src/redflag/RPMS/子目录下Q一般是i386Q具体情况和Linux发行版本有关。然后执行下面代码即可:<br />rpm -ivh /usr/src/regflag/RPMS/i386/Filename.rpm <br /><br /><b>使用deb打包的Y件安?</b><br /><br />deb 是Debian Linux提供的一个包理器,它与RPM十分cM。但׃RPM出现得早Qƈ且应用广泛,所以在各种版本的Linux中都常见刎ͼ而Debian的包理器dpkg只出现在Debina Linux中。它的优Ҏ不用被严格的依赖性检查所困扰Q缺Ҏ只在Debian Linux发行版中才能见到q个包管理工兗?<br /><br />1. 安装<br />Q dpkg -i MYsoftware-1.2.-1.deb <br /><br />2. 卸蝲<br />Q dpkg -e MYsoftware <br /><br /><b>使用源代码进行Y件安?/b><br /><br />和RPM安装方式相比Q用源代码q行软g安装会复杂一些,但是用源代码安装软g是Linux下进行Y件安装的重要手段Q也是运行Linux的最主要的优势之一。用源代码安装软gQ能按照用户的需要选择定制的安装方式进行安装,而不是仅仅依靠那些在安装包中的预配置的参数选择安装。另外,仍然有一些Y件程序只能从源代码处q行安装?<br /><br />现在有很多地斚w提供源代码包Q到底在什么地方获得取决于软g的特D需要。对于那些用比较普遍的软gQ如SendmailQ可以从商业|站处下载源代码软g包(如http://www.sendmail.org Q。一般的软g包,可从开发者的Web站点下蝲。下面介l一下安装步骤: <br /><br />1.解压数据?br />源代码Y仉常?tar.gz做ؓ扩展?也有tar.Z、tar.bz2?tgz为扩展名的。不同扩展名解压~命令也不相同,见表1?<br /><br /><center><img src="http://www.pc-file.com/UploadFiles/200522185247580.jpg" /></center><br /><br />2.~译软g<br />成功解压~源代码文g后,q入解包的目录。在安装前阅读Readme文g和Install文g。尽许多源代码文g包都使用基本相同的命令,但是有时在阅读这些文件时能发C些重要的区别。例如,有些软g包含一个可以安装的安装脚本E序Q?shQ。在安装前阅读这些说明文Ӟ有助于安装成功和节约旉?<br /><br />在安装Y件以前要成ؓroot用户。实现这一炚w常有两U方式:在另一台终端以root用户dQ或者输入“su”,此时pȝ会提C入root用户的密码。输入密码以后,将一直拥有root用户的权限。如果已l是root用户Q那可以进行下一步?<br /><br />通常的安装方法是从安装包的目录执行以下命令: <br /><br /><ccid></ccid><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid>gunzip soft1.tar.gz<br />cd soft1<br />Q? /configure Q配|#<br />make Q调用makeQ?br />make install Q安装源代码Q?/ccid></pre></td></tr></tbody></table><br /><br />删除安装时生的临时文gQ?br />Qmake clean <br /><br />卸蝲软gQ?br />Qmake uninstall <br /><br />有些软g包的源代码编译安装后可以用make uninstall命o卸蝲。如果不提供此功能,则Y件的卸蝲必须手动删除。由于Y件可能将文g分散地安装在pȝ的多个目录中Q往往很难把它删除q净Q应该在~译前进行配|?<br /><br /><b>.bin文g安装</b><br /><br />扩展名ؓ.bin文g是二q制的,它也是源E序l编译后得到的机器语a。有一些Y件可以发布ؓ?bin为后~的安装包Q例如,媒体播攑֙ RealONE。如果安装过RealONE的Windows版的话,那么安装RealONE for Linux版本(文g名:r1p1_linux22_libc6_i386_a1.bin)非常简单了Q?br />Qchmod +x r1p1_linux22_libc6_i386_a1.bin<br />./ r1p1_linux22_libc6_i386_a1.bin <br /><br />接下来选择安装方式Q有普通安装和高安装两种。如果不x动安装目录,可选择普通安装,整个安装q程几乎和在Windwos下一栗?<br /><br />.bin文g的卸载,以RealONE for LinuxZQ如果采用普通安装方式的话,在用户主目录下会有Real和Realplayer9两个文g夹,把它们删除即可?<br /><br /><b>Linuxl色软g</b><br /><br />Linux 也有一些绿色YӞ不过不是很多。Linuxpȝ提供一U机Ӟ自动响应软gq行q程的要?为它讑֮好可以马上运行的环境。这U机制可以是一U接口,或者是中间件。程序员~写的程序可以直接拷贝分发,不用安装Q只要点ȝ序的图标Q访问操作系l提供的接口Q设定好可以工作。若要删除YӞ直接删除可?不用链接文g。这是最单的软g安装、卸载方式?<br /><br />上面介绍了Linux软g安装的方法,对于Linux初学者来_RPM安装是一个不错的选择。如果想真正掌握LinuxpȝQ源代码安装仍然是Linux下Y件安装的重要手段<img src ="http://www.shnenglu.com/jjbird/aggbug/5770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jjbird/" target="_blank">奇奇</a> 2006-04-17 17:04 <a href="http://www.shnenglu.com/jjbird/articles/5770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Makefile文g的格式与用法http://www.shnenglu.com/jjbird/articles/3380.html奇奇奇奇Tue, 21 Feb 2006 08:53:00 GMThttp://www.shnenglu.com/jjbird/articles/3380.htmlhttp://www.shnenglu.com/jjbird/comments/3380.htmlhttp://www.shnenglu.com/jjbird/articles/3380.html#Feedback0http://www.shnenglu.com/jjbird/comments/commentRss/3380.htmlhttp://www.shnenglu.com/jjbird/services/trackbacks/3380.html    ~~~~~~~~~~~~~~~~
    
    2.1 基本 makefile l构
    
    GNU Make 的主要工作是读进一个文本文Ӟ makefile 。这个文 仉主要是有兛_些文Ӟ‘target’目的文Ӟ是从哪些别的 文gQ‘dependencies’依靠文Ӟ中生的Q用什么命令来q行 q个产生q程。有了这些信息, make 会检查磁上的文Ӟ如果 目的文g的时间戳Q该文g生成或被改动时的旉Q比臛_它的一 个依靠文件旧的话Q?make 执行相应的命oQ以便更新目的文件?Q目的文件不一定是最后的可执行档Q它可以是Q何一个文件。)
    makefile 一般被叫做“makefile”或“Makefile”。当然你可以 ?make 的命令行指定别的文g名。如果你不特别指定,它会?䏀makefile”或“Makefile”,因此使用q两个名字是最?的?
    一?makefile 主要含有一pd的规则,如下Q?
    
    : ...
    (tab)
    (tab)
    .
    .
    .
    
    例如Q考虑以下?makefile Q?
    
    === makefile 开?===
    myprog : foo.o bar.o
     gcc foo.o bar.o -o myprog
    
    foo.o : foo.c foo.h bar.h
     gcc -c foo.c -o foo.o
    
    bar.o : bar.c bar.h
     gcc -c bar.c -o bar.o
    === makefile l束 ===
    
    q是一个非常基本的 makefile —?make 从最上面开始,把上 面第一个目的,‘myprog’,做ؓ它的主要目标Q一个它需要保 证其L最新的最l目标)。给出的规则说明只要文g‘myprog?比文件‘foo.o’或‘bar.o’中的Q何一个旧Q下一行的命o?会被执行?
    但是Q在查文?foo.o ?bar.o 的时间戳之前Q它会往下查 N些把 foo.o ?bar.o 做ؓ目标文g的规则。它扑ֈ的关?foo.o 的规则,该文件的依靠文g?foo.c, foo.h ?bar.h ?它从下面再找不到生成q些依靠文g的规则,它就开始检查磁?上这些依靠文件的旉戟뀂如果这些文件中M一个的旉x foo.o 的新Q命?'gcc -o foo.o foo.c' 会执行Q从而更?文g foo.o ?
    接下来对文g bar.o 做类似的查,依靠文g在这里是文g bar.c ?bar.h ?
    现在Q?make 回到‘myprog’的规则。如果刚才两个规则中的Q 何一个被执行Qmyprog 需要重建(因ؓ其中一?.o 档就会比 ‘myprog’新Q,因此q接命o被执行?
    希望到此Q你可以看出使用 make 工具来徏立程序的好处——前 一章中所有繁琐的查步骤都?make 替你做了Q检查时间戳?你的源码文g里一个简单改变都会造成那个文g被重新编译(??.o 文g依靠 .c 文gQ,q而可执行文g被重新连接(因ؓ .o 文g被改变了Q。其实真正的得益是在当你改变一?header 档的时候——你不再需要记住那个源码文件依靠它Q因为所有的 资料都在 makefile 里?make 会很L的替你重新编译所有那 些因依靠q个 header 文g而改变了的源码文Ӟ如有需要,?q行重新q接?
    当然Q你要确定你?makefile 中所写的规则是正无误的Q只 列出那些在源码文件中?#include ?header 档…?
    
    2.2 ~写 make 规则 (Rules)
    
    最明显的(也是最单的Q编写规则的Ҏ是一个一个的?看源码文Ӟ把它们的目标文g做ؓ目的Q而E源码文g和被?#include ?header 档做Z靠文件。但是你也要把其它被q些 header ?#include ?header 档也列ؓ依靠文gQ还有那些被 包括的文件所包括的文件……然后你会发现要对越来越多的文g q行理Q然后你的头发开始脱落,你的脾气开始变坏,你的?色变成菜Ԍ你走在\上开始跟늺杆子撞Q终于你捣毁你的 电脑昄器,停止~程。到低有没有些容易点儿的Ҏ呢?
    当然有!向编译器要!在编译每一个源码文件的时候,它实在应 该知道应该包括什么样?header 档。?gcc 的时候,?-M 开养I它会为每一个你l它的E文g输出一个规则,把目标文?做ؓ目的Q而这个E文g和所有应该被 #include ?header ?件将做ؓ依靠文g。注意这个规则会加入所?header 文gQ包 括被角括?`<', `>')和双引号(`"')所包围的文件。其实我们可?相当肯定pȝ header 档(比如 stdio.h, stdlib.h {等Q不?被我们更改,如果你用 -MM 来代?-M 传递给 gccQ那些用角括 号包围的 header 档将不会被包括。(q会节省一些编译时_
    ?gcc 输出的规则不会含有命令部分;你可以自己写入你的命?或者什么也不写Q而让 make 使用它的隐含的规则(参考下面的 2.4 节)?
    
    2.3 Makefile 变量
    
    上面提到 makefiles 里主要包含一些规则。它们包含的其它的东 西是变量定义?
    makefile 里的变量像一个环境变?environment variable)?事实上,环境变量?make q程中被解释?make 的变量。这?变量是大写敏感的,一般用大写字母。它们可以从几乎M 地方被引用,也可以被用来做很多事情,比如Q?
    
    i) 贮存一个文件名列表。在上面的例子里Q生成可执行文g?规则包含一些目标文件名做ؓ依靠。在q个规则的命令行 里同L那些文g被输送给 gcc 做ؓ命o参数。如果在q?里用一个变数来贮存所有的目标文g名,加入新的目标 文g会变的简单而且较不易出错?
    ii) 贮存可执行文件名。如果你的项目被用在一个非 gcc 的系 l里Q或者如果你想用一个不同的~译器,你必d所 有用编译器的地Ҏ成用新的~译器名。但是如果用一 个变量来代替~译器名Q那么你只需要改变一个地方,?它所有地方的命o名就都改变了?
    iii) 贮存~译器旗标。假设你想给你所有的~译命o传递一l?相同的选项Q例?-Wall -O -gQ;如果你把q组选项?入一个变量,那么你可以把q个变量攑֜所有呼叫编译器 的地斏V而当你要改变选项的时候,你只需在一个地Ҏ 变这个变量的内容?
    要设定一个变量,你只要在一行的开始写下这个变量的名字Q后 面跟一?= P后面跟你要设定的q个变量的倹{以后你要引?q个变量Q写一?$ W号Q后面是围在括号里的变量名。比如在 下面Q我们把前面?makefile 利用变量重写一遍:
    
    === makefile 开?===
    OBJS = foo.o bar.o
    CC = gcc
    CFLAGS = -Wall -O -g
    
    myprog : $(OBJS)
     $(CC) $(OBJS) -o myprog
    
    foo.o : foo.c foo.h bar.h
     $(CC) $(CFLAGS) -c foo.c -o foo.o
    
    bar.o : bar.c bar.h
     $(CC) $(CFLAGS) -c bar.c -o bar.o
    === makefile l束 ===
    
    q有一些设定好的内部变量,它们Ҏ每一个规则内容定义。三?比较有用的变量是 $@, $<?$^ Q这些变量不需要括h住)?$@ 扩展成当前规则的目的文g名, $< 扩展成依靠列表中的第 一个依靠文Ӟ?$^ 扩展成整个依靠的列表Q除掉了里面所有重 复的文g名)。利用这些变量,我们可以把上面的 makefile 写成Q?
    
    === makefile 开?===
    OBJS = foo.o bar.o
    CC = gcc
    CFLAGS = -Wall -O -g
    
    myprog : $(OBJS)
     $(CC) $^ -o $@
    
    foo.o : foo.c foo.h bar.h
     $(CC) $(CFLAGS) -c $<-o $@
    
    bar.o : bar.c bar.h
     $(CC) $(CFLAGS) -c $<-o $@
    === makefile l束 ===
    
    你可以用变量做许多其它的事情Q特别是当你把它们和函数混合 使用的时候。如果需要更q一步的了解Q请参?GNU Make 手册?('man make', 'man makefile')
    
    2.4 隐含规则 (Implicit Rules)
    
    h意,在上面的例子里,几个产生 .o 文g的命令都是一L?都是?.c 文g和相x仉产生 .o 文gQ这是一个标准的?骤。其?make 已经知道怎么做——它有一些叫做隐含规则的?|的规则Q这些规则告诉它当你没有l出某些命o的时候,应该 怎么办?
    如果你把生成 foo.o ?bar.o 的命令从它们的规则中删除Q?make 会查找它的隐含规则Q然后会扑ֈ一个适当的命令。它的命令会 使用一些变量,因此你可以按照你的想法来讑֮它:它用变?CC 做ؓ~译器(象我们在前面的例子)Qƈ且传递变?CFLAGS Q给 C ~译器,C++ ~译器用 CXXFLAGS Q,CPPFLAGS Q?C ?处理器旗标)Q?TARGET_ARCH Q现在不用考虑q个Q,然后它加 入旗?'-c' Q后面跟变量 $<Q第一个依靠名Q,然后是旗 ?'-o' 跟变?$@ Q目的文件名Q。一个E~译的具体命令将 会是Q?
    $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $<-o $@
    当然你可以按照你自己的需要来定义q些变量。这是Z么用 gcc ?-M ?-MM 开兌出的码可以直接用在一?makefile 里?
    
    2.5 假象目的 (Phony Targets)
    
    假设你的一个项目最后需要生两个可执行文g。你的主要目?是生两个可执行文gQ但q两个文件是怺独立的——如果一 个文仉要重建,q不影响另一个。你可以使用“假象目的”来 辑ֈq种效果。一个假象目的跟一个正常的目的几乎是一LQ?只是q个目的文g是不存在的。因此, make L会假讑֮需?被生成,当把它的依赖文g更新后,׃执行它的规则里的命o 行?
    如果在我们的 makefile 开始处输入Q?
    
    all : exec1 exec2
    
    其中 exec1 ?exec2 是我们做为目的的两个可执行文件?make 把这?'all' 做ؓ它的主要目的Q每ơ执行时都会试?'all' 更新。但既然q行规则里没有哪个命令来作用在一个叫 'all' ?实际文gQ事实上 all q不会在碟上实际生)Q所以这个规 则ƈ不真的改?'all' 的状态。可既然q个文gq不存在Q所?make 会尝试更?all 规则Q因此就查它的依?exec1, exec2 是否需要更斎ͼ如果需要,把它们更新Q从而达到我们的目的?
    假象目的也可以用来描qCl非预设的动作。例如,你想把所有由 make 产生的文件删除,你可以在 makefile 里设立这样一个规则:
    
    veryclean :
     rm *.o
     rm myprog
    
    前提是没有其它的规则依靠q个 'veryclean' 目的Q它永q?不会被执行。但是,如果你明的使用命o 'make veryclean' Q?make 会把q个目的做ؓ它的主要目标Q执行那?rm 命o?
    如果你的碟上存在一个叫 veryclean 文gQ会发生什么事Q这 时因为在q个规则里没有Q何依靠文Ӟ所以这个目的文件一定是 最新的了(所有的依靠文g都已l是最新的了)Q所以既使用h 命?make 重新产生它,也不会有M事情发生。解x法是?明所有的假象目的Q用 .PHONYQ,q就告诉 make 不用查它?是否存在于磁上Q也不用查找M隐含规则Q直接假设指定的?的需要被更新。在 makefile 里加入下面这行包含上面规则的规则Q?
    
    .PHONY : veryclean
    
    可以了。注意,q是一个特D的 make 规则Qmake 知道 .PHONY 是一个特D目的,当然你可以在它的依靠里加入你想用的Q何假?目的Q?make 知道它们都是假象目的?
    
    2.6 函数 (Functions)
    
    makefile 里的函数跟它的变量很怼——用的时候,你用一?$ W号跟开括号Q函数名Q空格后跟一列由逗号分隔的参敎ͼ最?用关括号l束。例如,?GNU Make 里有一个叫 'wildcard' 的函 敎ͼ它有一个参敎ͼ功能是展开成一列所有符合由其参数描q的?件名Q文仉以空格间隔。你可以像下面所CZ用这个命令:
    
    SOURCES = $(wildcard *.c)
    
    q行会生一个所有以 '.c' l尾的文件的列表Q然后存入变?SOURCES 里。当然你不需要一定要把结果存入一个变量?
    另一个有用的函数?patsubst Q?patten substitude, 匚w?换的~写Q函数。它需要3个参数——第一个是一个需要匹配的式样Q第二个表示用什么来替换它,W三个是一个需要被处理?q格分隔的字列。例如,处理那个l过上面定义后的变量Q?
    
    OBJS = $(patsubst %.c,%.o,$(SOURCES))
    
    q行处理所有在 SOURCES 字列中的字(一列文件名Q,如果它的 l尾?'.c' Q就?'.o' ?'.c' 取代。注意这里的 % W号匹 配一个或多个字符Q而它每次所匚w的字串叫做一个‘柄?stem) ?在第二个参数里, % 被解L用第一参数所匚w的那个柄?
    
    2.7 一个比较有效的 makefile
    
    利用我们现在所学的Q我们可以徏立一个相当有效的 makefile ?q个 makefile 可以完成大部分我们需要的依靠查,不用做太?的改变就可直接用在大多数的项目里?
    首先我们需要一个基本的 makefile 来徏我们的程序。我们可以让 它搜索当前目录,扑ֈ源码文gQƈ且假讑֮们都是属于我们的?目的Q放q一个叫 SOURCES 的变量。这里如果也包含所有的 *.cc 文gQ也怼更保险,因ؓ源码文g可能?C++ 码的?
    
    SOURCES = $(wildcard *.c *.cc)
    
    利用 patsubst Q我们可以由源码文g名生目标文件名Q我们需 要编译出q些目标文g。如果我们的源码文g既有 .c 文gQ也?.cc 文gQ我们需要用相嵌的 patsubst 函数呼叫Q?
    
    OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))
    
    最里面一?patsubst 的呼叫会?.cc 文gq行后缀替代Q生的l?果被外层?patsubst 呼叫处理Q进行对 .c 文g后缀的替代?
    现在我们可以讄一个规则来建可执行文gQ?
    
    myprog : $(OBJS)
     gcc -o myprog $(OBJS)
    
    q一步的规则不一定需要, gcc 已经知道怎么ȝ成目标文?(object files) 。下面我们可以设定生依靠信息的规则Q?
    
    depends : $(SOURCES)
     gcc -M $(SOURCES) > depends
    
    在这里如果一个叫 'depends' 的文件不存在Q或M一个源码文?比一个已存在?depends 文g斎ͼ那么一?depends 文g会被?成。depends 文g会含有?gcc 产生的关于源码文件的规则Q注 ?-M 开养I。现在我们要?make 把这些规则当?makefile ?的一部分。这里用的技巧很?C 语言中的 #include pȝ——我 们要?make 把这个文?include ?makefile 里,如下Q?
    
    include depends
    
    GNU Make 看到q个Q检?'depends' 目的是否更新了,如果没有Q?它用我们l它的命令重C?depends 档。然后它会把q组Q新Q?规则包含q来Ql处理最l目?'myprog' 。当看到有关 myprog 的规则,它会查所有的目标文g是否更新——利?depends 文g 里的规则Q当然这些规则现在已l是更新q的了?
    q个pȝ其实效率很低Q因为每当一个源码文件被改动Q所有的源码 文g都要被预处理以生一个新?'depends' 文g。而且它也不是 100% 的安全,q是因ؓ当一?header 档被改动Q依靠信息ƈ不会 被更新。但基本工作来_它也相当有用的了?
    
    2.8 一个更好的 makefile
    
    q是一个我为我大多数项目设计的 makefile 。它应该可以不需要修 改的用在大部分项目里。我主要把它用在 djgpp 上,那是一?DOS 版的 gcc ~译器。因此你可以看到执行的命令名?'alleg' E序包??RM -F 变量都反映了q一炏V?
    
    === makefile 开?===
    
    ######################################
    #
    # Generic makefile
    #
    # by George Foot
    # email: george.foot@merton.ox.ac.uk
    #
    # Copyright (c) 1997 George Foot
    # All rights reserved.
    # 保留所有版?
    #
    # No warranty, no liability;
    # you use this at your own risk.
    # 没保险,不负?
    # 你要用这个,你自己担风险
    #
    # You are free to modify and
    # distribute this without giving
    # credit to the original author.
    # 你可以随便更改和散发q个文g
    # 而不需要给原作者什么荣誉?
    # Q你好意思?Q?
    #
    ######################################
    
    ### Customising
    # 用户讑֮
    #
    # Adjust the following if necessary; EXECUTABLE is the target
    # executable's filename, and LIBS is a list of libraries to link in
    # (e.g. alleg, stdcx, iostr, etc). You can override these on make's
    # command line of course, if you prefer to do it that way.
    #
    # 如果需要,调整下面的东ѝ?EXECUTABLE 是目标的可执行文件名Q?LIBS
    # 是一个需要连接的E序包列表(例如 alleg, stdcx, iostr {等Q。当然你
    # 可以?make 的命令行覆盖它们Q你愿意没问题?
    #
    
    EXECUTABLE := mushroom.exe
    LIBS := alleg
    
    # Now alter any implicit rules' variables if you like, e.g.:
    #
    # 现在来改变Q何你x动的隐含规则中的变量Q例?
    
    CFLAGS := -g -Wall -O3 -m486
    CXXFLAGS := $(CFLAGS)
    
    # The next bit checks to see whether rm is in your djgpp bin
    # directory; if not it uses del instead, but this can cause (harmless)
    # `File not found' error messages. If you are not using DOS at all,
    # set the variable to something which will unquestioningly remove
    # files.
    #
    # 下面先检查你?djgpp 命o目录下有没有 rm 命oQ如果没有,我们使用
    # del 命o来代替,但有可能l我?'File not found' q个错误信息Q这?
    # 什么大。如果你不是?DOS Q把它设定成一个删文g而不废话的命令?
    # Q其实这一步在 UNIX cȝpȝ上是多余的,只是方便 DOS 用户?UNIX
    # 用户可以删除q5行命令。)
    
    ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)
    RM-F := rm -f
    else
    RM-F := del
    endif
    
    # You shouldn't need to change anything below this point.
    #
    # 从这里开始,你应该不需要改动Q何东ѝ(我是不太怿Q太Q了!Q?
    
    SOURCE := $(wildcard *.c) $(wildcard *.cc)
    OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE)))
    DEPS := $(patsubst %.o,%.d,$(OBJS))
    MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
    MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS)) \
    $(patsubst %.d,%.cc,$(MISSING_DEPS)))
    CPPFLAGS += -MD
    
    .PHONY : everything deps objs clean veryclean rebuild
    
    everything : $(EXECUTABLE)
    
    deps : $(DEPS)
    
    objs : $(OBJS)
    
    clean :
     @$(RM-F) *.o
     @$(RM-F) *.d
    
    veryclean: clean
     @$(RM-F) $(EXECUTABLE)
    
    rebuild: veryclean everything
    
    ifneq ($(MISSING_DEPS),)
    $(MISSING_DEPS) :
     @$(RM-F) $(patsubst %.d,%.o,$@)
    endif
    
    -include $(DEPS)
    
    $(EXECUTABLE) : $(OBJS)
     gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))
    
    === makefile l束 ===
    
    有几个地方值得解释一下的。首先,我在定义大部分变量的时候 用的?:= 而不?= W号。它的作用是立即把定义中参考到的函 数和变量都展开了。如果?= 的话Q函数和变量参考会留在?儿,是说改变一个变量的gD其它变量的g被改变。例 如:
    
    A = foo
    B = $(A)
    # 现在 B ?$(A) Q?$(A) ?'foo' ?
    A = bar
    # 现在 B 仍然?$(A) Q但它的值已随着变成 'bar' 了?
    B := $(A)
    # 现在 B 的值是 'bar' ?
    A = foo
    # B 的g然是 'bar' ?
    
    make 会忽略在 # W号后面直到那一行结束的所有文字?
    
    ifneg...else...endif pȝ?makefile 里让某一部分码有条g?失效Q有效的工具?ifeq 使用两个参数Q如果它们相同,它把??else Q或?endif Q如果没?else 的话Q的一D늠加进 makefile 里;如果不同Q把 else ?endif 间的一D늠加入 makefile Q如果有 else Q?ifneq 的用法刚好相反?
    'filter-out' 函数使用两个用空格分开的列表,它把W二列表中所 有的存在于第一列表中的目删除。我用它来处?DEPS 列表Q把所 有已l存在的目都删除,而只保留~少的那些?
    我前面说q, CPPFLAGS 存有用于隐含规则中传l预处理器的一?旗标。?-MD 开关类?-M 开养I但是从源码文?.c ?.cc ?形成的文件名是用后~ .d 的(q就解释了我形成 DEPS 变量?步骤Q。DEPS 里提到的文g后来?'-include' 加进?makefile 里,它隐藏了所有因文g不存在而生的错误信息?
    如果M依靠文g不存在, makefile 会把相应?.o 文g从磁?上删除,从而?make 重徏它。因?CPPFLAGS 指定?-MD Q?它的 .d 文g也被重新产生?
    最后, 'addprefix' 函数把第二个参数列表的每一前~上第一 个参数倹{?
    q个 makefile 的那些目的是Q这些目的可以传l?make 的命令行 来直接选用Q:
    everything:Q预设) 更新主要的可执行E序Qƈ且ؓ每一?源码文g生成或更C?'.d' 文g和一?'.o' 文g?
    deps: 只是为每一个源码程序生或更新一?'.d' 文g?
    objs: 为每一个源码程序生成或更新 '.d' 文g和目标文件?
    clean: 删除所有中介/依靠文gQ?*.d ?*.o Q?
    veryclean: ?`clean' 和删除可执行文g?
    rebuild: 先做 `veryclean' 然后 `everything' Q既完全重徏?
    除了预设?everything 以外Q这里头只有 clean Q?veryclean Q??rebuild 对用h有意义的?
    我还没有发现当给Z个源码文件的目录Q这?makefile 会失败的 情况Q除非依靠文件被弄ؕ。如果这U弄q情况发生了,只要输入 `make clean' Q所有的目标文g和依靠文件会被删除,问题应?被解决了。当Ӟ最好不要把它们弄ؕ。如果你发现在某U情况下q??makefile 文g不能完成它的工作Q请告诉我,我会把它整好的?
    
    3 ȝ
    ~~~~~~~~~~~~~~~
    
    我希望这文章够详l的解释了多文g目是怎么q作的,也说明了 怎样安全而合理的使用它。到此,你应该可以轻杄利用 GNU Make ?h理型的项目,如果你完全理解了后面几个部分的话Q这些对?你来说应该没什么困难?
    GNU Make 是一件强大的工具Q虽然它主要是用来徏立程序,它还有很?别的用处。如果想要知道更多有兌个工L知识Q它的句法,函数Q?和许多别的特点,你应该参看它的参考文?(info pages, 别的 GNU 工具也一P看它们的 info pages. )?

奇奇 2006-02-21 16:53 发表评论
]]>
Linux环境下用GDB调试 GCC E序http://www.shnenglu.com/jjbird/articles/3373.html奇奇奇奇Tue, 21 Feb 2006 06:19:00 GMThttp://www.shnenglu.com/jjbird/articles/3373.htmlhttp://www.shnenglu.com/jjbird/comments/3373.htmlhttp://www.shnenglu.com/jjbird/articles/3373.html#Feedback0http://www.shnenglu.com/jjbird/comments/commentRss/3373.htmlhttp://www.shnenglu.com/jjbird/services/trackbacks/3373.html  
  它你能监视你程序中变量的?
  
  它你能讄断点以ɽE序在指定的代码行上停止执行.
  
  它你能一行行的执行你的代?
  
  在命令行上键?gdb q按回R键就可以q行 gdb ? 如果一切正常的? gdb 被启动q且你将在屏q上看到cM的内?
  
  GDB is free software and you are welcome to distribute copies of it
  under certain conditions; type "show copying" to see the conditions.
  There is absolutely no warranty for GDB; type "show warranty" for details.
  GDB 4.14 (i486-slakware-linux), Copyright 1995 Free Software Foundation, Inc.
  (gdb)
  
  当你启动 gdb ? 你能在命令行上指定很多的选项. 你也可以以下面的方式来运?gdb :
  gdb
  
  当你用这U方式运?gdb , 你能直接指定惌调试的程? q将告诉gdb 装入名ؓ fname 的可执行文g. 你也可以?gdb L查一个因E序异常l止而生的 core 文g, 或者与一个正在运行的E序相连. 你可以参?gdb 指南|在命令行上键?gdb -h 得到一个有兌些选项的说明的单列?
  
  试编译代?Compiling Code for Debugging)
  
  Z?gdb 正常工作, 你必M你的E序在编译时包含调试信息. 调试信息包含你程序里的每个变量的cd和在可执行文仉的地址映射以及源代码的行号. gdb 利用q些信息使源代码和机器码相关? 在编译时?-g 选项打开调试选项.
  
  gdb 基本命o
  
  gdb 支持很多的命令你能实现不同的功? q些命o从简单的文g装入到允怽查所调用的堆栈内容的复杂命o, ?列出了你在用 gdb 调试时会用到的一些命?
  
  ?. 基本 gdb 命o.
  
  ???q 
  file 装入惌调试的可执行文g 
  kill l止正在调试的程?
  list 列出产生执行文g的源代码的一部分
  next 执行一行源代码但不q入函数内部
  step 执行一行源代码而且q入函数内部
  run 执行当前被调试的E序
  quit l止 gdb 
  watch 使你能监视一个变量的D不它何时被改?
  break 在代码里讄断点, q将使程序执行到q里时被挂v
  make 使你能不退?gdb 可以重C生可执行文g
  shell 使你能不d gdb 执?UNIX shell 命o
  
  gdb 支持很多?UNIX shell E序一L命o~辑特征. 你能象在 bash ?tcsh里那h Tab 键让 gdb 帮你补齐一个惟一的命? 如果不惟一的话 gdb 会列出所有匹配的命o. 你也能用光标键上下翻动历史命?

 gdb 应用举例
  
  本节用一个实例教你一步步的用 gdb 调试E序. 被调试的E序相当的简? 但它展示?gdb 的典型应?
  
  下面列出了将被调试的E序. q个E序被称?greeting , 它显CZ个简单的问? 再用反序它列出.
  
  #include <stdio.h>
  main ()
  {
   char my_string[] = "hello there";
   my_print (my_string);
   my_print2 (my_string);
  }
  void my_print (char *string)
  {
   printf ("The string is %s\n", string);
  }
  void my_print2 (char *string)
  {
   char *string2;
   int size, i;
   size = strlen (string);
   string2 = (char *) malloc (size + 1);
   for (i = 0; i < size; i++)
    string2[size - i] = string[i];
   string2[size+1] = `\0';
   printf ("The string printed backward is %s\n", string2);
  }
  
  
  
  用下面的命o~译?
  gcc -o test test.c
  
  q个E序执行时显C如下结?
  The string is hello there
  The string printed backward is
  
  输出的第一行是正确? 但第二行打印出的东西q不是我们所期望? 我们所设想的输出应该是:
  The string printed backward is ereht olleh
  
  ׃某些原因, my_print2 函数没有正常工作. 让我们用 gdb 看看问题I竟出在哪儿, 先键入如下命?
  gdb greeting
  
  注意: 记得在编?greeting E序时把调试选项打开.
  
  如果你在输入命o时忘了把要调试的E序作ؓ参数传给 gdb , 你可以在 gdb 提示W下?file 命o来蝲入它:
  (gdb) file greeting
  
  q个命o蝲?greeting 可执行文件就象你?gdb 命o行里装入它一?
  
  q时你能?gdb ?run 命o来运?greeting ? 当它?gdb 里被q行后结果大U会象这?
  
  (gdb) run
  Starting program: /root/greeting
  The string is hello there
  The string printed backward is
  Program exited with code 041
  
  
  
  q个输出和在 gdb 外面q行的结果一? 问题? Z么反序打印没有工? Z扑և症结所? 我们可以?my_print2 函数?for 语句后设一个断? 具体的做法是?gdb 提示W下键入 list 命o三次, 列出源代?
  (gdb) list
  (gdb) list
  (gdb) list
  
  技? ?gdb 提示W下按回车健重复上一个命?
  
  W一ơ键?list 命o的输出如?
  
  1    #include <stdio.h>
  2
  3    main ()
  4    {
  5     char my_string[] = "hello there";
  6
  7     my_print (my_string);
  8     my_print2 (my_string);
  9    }
  10
  
  
  
  如果按下回R, gdb 再执行一?list 命o, l出下列输出:
  
  11   my_print (char *string)
  12   {
  13    printf ("The string is %s\n", string);
  14   }
  15
  16   my_print2 (char *string)
  17   {
  18    char *string2;
  19    int size, i;
  20
  
  
  
  再按一ơ回车将列出 greeting E序的剩余部?
  
  21    size = strlen (string);
  22    string2 = (char *) malloc (size + 1);
  23    for (i = 0; i < size; i++)
  24     string2[size - i] = string[i];
  25    string2[size+1] = `\0';
  26    printf ("The string printed backward is %s\n", string2);
  27   }
  
  
  
  Ҏ列出的源E序, 你能看到要设断点的地方在W?4? ?gdb 命o行提C符下键入如下命令设|断?
  (gdb) break 24
  
  gdb 作出如下的响应:
  Breakpoint 1 at 0x139: file greeting.c, line 24
  (gdb)
  
  现在再键?run 命o, 生如下的输出:
  
  Starting program: /root/greeting
  The string is hello there
  Breakpoint 1, my_print2 (string = 0xbfffdc4 "hello there") at greeting.c :24
  24 string2[size-i]=string[i]
  
  
  
  你能通过讄一个观?string2[size - i] 变量的值的观察Ҏ看出错误是怎样产生? 做法是键?
  (gdb) watch string2[size - i]
  
  gdb 作出如下回?
  Watchpoint 2: string2[size - i]
  
  现在可以?next 命o来一步步的执?for 循环?
  (gdb) next
  
  l过W一ơ@环后, gdb 告诉我们 string2[size - i] 的值是 `h`. gdb 用如下的昄来告诉你q个信息:
  
  Watchpoint 2, string2[size - i]
  Old value = 0 `\000'
  New value = 104 `h'
  my_print2(string = 0xbfffdc4 "hello there") at greeting.c:23
  23 for (i=0; i<size; i++)
  
  
  
  q个值正是期望的. 后来的数ơ@环的l果都是正确? ?i=10 ? 表达?string2[size - i] 的值等?`e`, size - i 的值等?1, 最后一个字W已l拷到新串里?
  
  如果你再把@环执行下? 你会看到已经没有值分配给 string2[0] ? 而它是新串的W一个字W? 因ؓ malloc 函数在分配内存时把它们初始化为空(null)字符. 所?string2 的第一个字W是I字W? q解释了Z么在打印 string2 时没有Q何输Z.
  
  现在扑և了问题出在哪? 修正q个错误是很Ҏ? 你得把代码里写入 string2 的第一个字W的的偏U量改ؓ size - 1 而不?size. q是因ؓ string2 的大ؓ 12, 但v始偏U量?0, 串内的字W从偏移?0 ?偏移?10, 偏移?11 为空字符保留.
  
  Z使代码正常工作有很多U修改办? 一U是另设一个比串的实际大小?1 的变? q是q种解决办法的代?
  
  #include <stdio.h>
  main ()
  {
   char my_string[] = "hello there";
   my_print (my_string);
   my_print2 (my_string);
  }
  my_print (char *string)
  {
   printf ("The string is %s\n", string);
  }
  my_print2 (char *string)
  {
   char *string2;
   int size, size2, i;
   size = strlen (string);
   size2 = size -1;
   string2 = (char *) malloc (size + 1);
   for (i = 0; i < size; i++)
    string2[size2 - i] = string[i];
   string2[size] = `\0';
   printf ("The string printed backward is %s\n", string2);
  }

奇奇 2006-02-21 14:19 发表评论
]]>
linux下命令行下编译cE序http://www.shnenglu.com/jjbird/articles/3372.html奇奇奇奇Tue, 21 Feb 2006 06:13:00 GMThttp://www.shnenglu.com/jjbird/articles/3372.htmlhttp://www.shnenglu.com/jjbird/comments/3372.htmlhttp://www.shnenglu.com/jjbird/articles/3372.html#Feedback0http://www.shnenglu.com/jjbird/comments/commentRss/3372.htmlhttp://www.shnenglu.com/jjbird/services/trackbacks/3372.html  
  C 在过ȝ二十q中有了很大的发? ?0q代末期国国家标准协会(American NationalStandards Institute)发布了一个被UCؓ ANSI C ?C 语言标准.q更加保证了来在不同^C?C 的一致? ?0q代q出C一U?C 的面向对象的扩展UCؓ C++.
  
  Linux 上可用的 C ~译器是 GNU C ~译? 它徏立在自由软g基金会的~程许可证的基础? 因此可以自由发布. 你能?Linux 的发行光盘上扑ֈ?
  
  ?Slackware Linux 发行?GNU C ~译?GCC)是一个全功能?ANSI C 兼容~译? 如果你熟悉其他操作系l或gq_上的一U?C ~译? 你将能很快地掌握 GCC. q和java在命令行?BR>  
  ~译也很cM我们在下面介绍如何使用 GCC 和一?GCC ~译器最常用的选项.
  
  格式 gcc [option] [sourcefilename]
  
  gcc的选项十分J多,大约有上百中,不过qx常用的不是非常多,我们要介绍一些常用的选项:
  
  最单的?gcc hello.c
  
  默认的情况下生成a.out的可执行性文?你只需要在l端上输?/a.out可以看到执行的l果.
  
  如果你想指定生成目标文g的名字那么你可以加上 -o选项,命o如下:
  
  gcc -o hello hello.c
  
  gcc也允怽只编译源E序,q样可以只检查编译时ȝ错误,有利也调试程??c选项可以辑ֈq个目的
  
  命o如下:
  
  gcc -c hello hello.c
  
  l果生成了一个中间代码hello.o文g
  
   ~译选项告诉 GCC 在ؓ C 代码产生了汇~语a文g后停止编? GCC 产生的汇~语a文g的缺省扩展名?.s . -E 选项指示~译器仅对输入文件进行预处理. 当这个选项被用时, 预处理器的输送到标准输出而不是储存在文g?
  
  之后你可以对上述中间代码q行链接q行,使用命o:
  
  gcc -o hello.out hello.c
  
  ????BR>  
  当你?GCC ~译 C 代码? 它会试着用最的旉完成~译q且使编译后的代码易于调? 易于调试意味着~译后的代码与源代码有同L执行ơ序, ~译后的代码没有l过优化.有很多选项可用于告?GCC 在耗费更多~译旉和牺牲易调试性的基础上生更更快的可执行文? q些选项中最典型的是-O ?-O2 选项.
  
  -O 选项告诉 GCC Ҏ代码q行基本优化. q些优化在大多数情况下都会ɽE序执行的更? -O2 选项告诉 GCC 产生可能小和尽可能快的代码. -O2 选项ɾ~译的速度比?-O时慢. 但通常产生的代码执行速度会更?
  
  GCC 支持数种调试和剖析选项. 在这些选项里你会最常用到的?-g ?-pg 选项.
  
   选项告诉 GCC 产生能被 GNU 调试器用的调试信息以便调试你的E序. GCC 提供了一个很多其?C ~译器里没有的特? ?GCC 里你能 -g ?-O (产生优化代码)联用. q一炚w常有用因Z能在与最l品尽可能相近的情况下调试你的代码. 在你同时使用q两个选项时你必须清楚你所写的某些代码已经在优化时?GCC 作了改动. 关于调试 C E序的更多信息请看下一??gdb 调试 C E序" .
  
  如下命o gcc -c -g hello.c
  
  pg 选项告诉 GCC 在你的程序里加入额外的代? 执行? 产生 gprof 用的剖析信息以显CZ的程序的耗时情况.
  
  关于ggc的详l信息可用man gcc来查?img src ="http://www.shnenglu.com/jjbird/aggbug/3372.html" width = "1" height = "1" />

奇奇 2006-02-21 14:13 发表评论
]]>
ĻƷþþþ| ۺϾþúݺɫ99h| þþùҺ| ˾þóۺӰԺ| ޾Ʒרþþ| þۺϾɫۺϾƷ| þü޾Ʒ?V| 99ƷþþƷһ| þ㽶һëƬ| þþþ޹| 91þþþþۺ| һaƬþëƬ| þþþƷ鶹| ޹徫Ʒ߾þ | ƷŮٸaѾþ| þѿaëƬ| bƷþþþþþ| ɫۺϾþĻ| ŷ޾þav| 99þùһ | Ʒ91þþþþþ| þۺϾþڹ| 91Ʒþþþþ| þ99Ʒþþþþhb| ɫۺϾþ߹ۿ| 99þþƷþþþþ崿| ƷѸþ| ޳ɫWWWþվ| һaɫƬþ| þһ| þ99Ʒ鶹| þó鱬Ļ| ޼VëƬþþƷ| ճˮþ޾Ʒtv| ˾þۺ2020| ɫۺϾþ۾Ʒ| һһþþƷۺ| 91ƷѾþþþþþþ| þùŮѹۿƷ| պþëƬ| һaƬþëƬ |