摘要: 一 概述: HttpWatch强大的网页数据分析工具.集成在Internet Explorer工具栏.包括网页摘要.Cookies管理.缓存管理.消息头发送/接受.字符查询.POST 数据和目录管理功能.报告输出 HttpWatch 是一款能够收集并显示页页深层信息的软件。它不用代理服务器或一些复杂的网络监控工具,就能够在显示网页同时显示网页请求和回应的日志信息。甚至可以显示浏览器缓存和IE之间...  阅读全文
posted @ 2008-12-26 10:31 小马歌 阅读(796) | 评论 (0)编辑 收藏
 

匹配中文字符的正则表达式: [\u4e00-\u9fa5]

匹配双字节字符(包括汉字在内):[^\x00-\xff]

应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}

匹配空行的正则表达式:\n[\s| ]*\r

匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/

匹配首尾空格的正则表达式:(^\s*)|(\s*$)

应用:javascript中没有像vbscript那样的trim函数,我们就可以利用这个表达式来实现,如下:

String.prototype.trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, "");
}

利用正则表达式分解和转换IP地址:

下面是利用正则表达式匹配IP地址,并将IP地址转换成对应数值的Javascript程序:

function IP2V(ip)
{
re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式
if(re.test(ip))
{
return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1
}
else
{
throw new Error("Not a valid IP address!")
}
}

不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:

var ip="10.100.20.168"
ip=ip.split(".")
alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

匹配网址URL的正则表达式:http://([/w-]+/.)+[/w-]+(/[/w- ./?%&=]*)?

利用正则表达式去除字串中重复的字符的算法程序:[注:此程序不正确,原因见本贴回复]

var s="abacabefgeeii"
var s1=s.replace(/(.).*\1/g,"$1")
var re=new RegExp("["+s1+"]","g")
var s2=s.replace(re,"")
alert(s1+s2) //结果为:abcefgi

这个方法对于字符顺序有要求的字符串可能不适用。

得用正则表达式从URL地址中提取文件名的javascript程序,如下结果为page1

s="http://www.9499.net/page1.htm"
s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$2")
alert(s)

利用正则表达式限制网页表单里的文本框输入内容:

用正则表达式限制只能输入中文:onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,´´)" onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\u4E00-\u9FA5]/g,´´))"

用正则表达式限制只能输入全角字符: onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,´´)" onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\uFF00-\uFFFF]/g,´´))"

用正则表达式限制只能输入数字:onkeyup="value=value.replace(/[^\d]/g,´´) "onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\d]/g,´´))"

用正则表达式限制只能输入数字和英文:onkeyup="value=value.replace(/[\W]/g,´´) "onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\d]/g,´´))"

文章出处:http://www.diybl.com/course/3_program/java/javajs/2008513/115720.html

posted @ 2008-12-26 10:26 小马歌 阅读(1689) | 评论 (0)编辑 收藏
 
转自:http://www.zengrong.net/?p=393

Flash Player 9.0.115发布了,这是一个支持H.264的正式版本。关于H.264,已经说得太多,播放H.264的视频也很简单,用NetStream即可(也就是播放FLV的那一套,想了解的可以看这篇官方提供的教程),但是怎么把现有的视频压缩成Flash Player支持的H.264格式呢?

首先,要了解Flash Player 9.0.115对视频编码到底支持到哪个程度。

下面是Adobe官方提供的一个Flash Player支持的视频编码列表(原文):

视频编码 SWF 文件格式版本(发布的版本) 支持播放的最小Flash Player版本
Sorenson Spark 6 6
On2 VP6 6 8
H.264 (MPEG-4 Part 10) 9 9.0.115.0*
音频编码 SWF 文件格式版本(发布的版本) 支持播放的最小Flash Player版本
ADPCM 6 6
MP3 6 6
HE-AAC (MPEG-4 Part 3) 9 9.0.115.0*

*Flash Player 可以播放视频编码为H.264,音频编码为AAC的标准MPEG-4文件。文件的扩展名可以是:F4V, MP4, M4A, MOV, MP4V, 3GP, 3G2等等。

注意:如果没有特别说明,下面的Flash Player都指Flash Player 9(v 9.0.115.0)

Flash Player 9 (v 9.0.115.0) 支持下面的 MPEG-4 标准的子集:

MPEG-4 标准 Flash Player Update 3
ISO/IEC 14496-3 (Audio AAC) AAC Main; AAC LC; SBR
ISO/IEC 14496-10 (Video AVC) Base (BP); Main (MP); High (HiP). All levels are supported.
ISO/IEC 14496-12 (Container) 1 Audio track; 1 Video track
3GPP TS 26.245 (Timed text format) Full support.

那么,什么是H.264?“MPEG4 Part 10”是什么?它和“Part 3”、“Part 2” 有什么关系?可以看这篇文章

简单的讲,H.264、MPEG4 Part 10、MPEG4 AVC和ISO/IEC 14496-10 都是一个东东,就是一种视频编码格式,同时也是高清电影采用的视频编码格式之一(另外两种是MPEG2和VC-1)。

而平常我们熟悉的DivX以及XviD编码,都属于MPEG4标准的范畴,但它们属于MPEG4 Part 2,Flash Player是不支持它们的。

了解了基础知识之后,我们首先需要找到一个编码工具。

选择一个优秀的压缩工具至关重要。Flash CS3自带的用于压缩FLV的压缩器自然是无法胜任了。可是网上的视频转换工具多如牛毛,要找一款好用的真的很难。本着“免费、易用、专业、通吃”这四个标准,经过大量测试,终于找到一款优秀的国产编码软件MediaCoder(中文名:影音转码宝盒),以下是来自MediaCoder官方网站的介绍:

MediaCoder是一个免费的通用音频/视频批量转码工具,它将众多来自开源社区的优秀音频视频编解码器和工具整合为一个通用的解决方案,可以将音频、视频文件在各种格式之间进行转换。

功能和特点

  • 基于优秀的众多的开源编解码后台,能够解码和编码的格式多
  • 极为丰富的可调整的编码参数
  • 全部编解码器自带,不依赖于系统的编解码器和任何组件
  • 良好的可扩展的程序架构,快速适应新的需求,不断增加新的格式的支持
  • 利用脚本语言扩展的界面,有支持众多影音设备(如PSPiPod)的专用界面
  • 高性能,特别在双核处理器上表现优异


典型应用

  • 提高影音文件压缩率,减小其文件尺寸
  • 转换至可在各种影音设备上播放的影音文件,如MP3播放器、MP4播放器、手机、PDA、VCD/DVD播放机
  • 提取视频文件中的音轨并转换成MP3、AAC、WMA等音频文件
  • 修复和改善一些损坏的、部分下载的或质量不佳的影音文件

支持格式

*仅支持输入

编码工具搞定,接着就可以“制作”影片了。

我采用的源片是著名的Backkom Assa Game Contest片段,片源编码如下:

G:\Movie\Backkom\Assa Game Contest.wmv
General
Complete name : G:\Movie\Backkom\Assa Game Contest.wmv
Format : Windows Media
File size : 1.89 MiB
PlayTime : 33s 991ms
Bit rate : 467 Kbps
Movie name : Assa
Performer : Aaron Lim
Copyright : rg animation studios
Comment : rg animation studios
Video
Codec : WMV3
Codec/Info : Windows Media Video 9
Bit rate : 408 Kbps
Width : 320 pixels
Height : 240 pixels
Aspect ratio : 4/3
Audio
Codec : WMA2
Codec/Info : Windows Media Audio 2
Bit rate : 48 Kbps
Channel(s) : 2 channels
Sampling rate : 44 KHz

在压缩前,最重要的就是在MediaCoder中选择视频编码和音频编码。根据上面的表格我们知道,Flash Player 9.0.115支持H.264视频编码和HE-AAC音频编码。下图是我在MediaCoder中的设置。

H.264视频设置
H.264视频设置

 

HE-AAC音频编码
HE-AAC音频设置

 

h264video2
视频大小设置

将这三个设置调整好即可。H.264的编码优于WMV9,所以在压缩的时候,选择的视频和音频码率都小于源文件的码率。

转换完后的视频扩展名为MP4,详细编码信息如下:

G:\Movie\Backkom\Assa Game Contest.mp4
General
Complete name : G:\Movie\Backkom\Assa Game Contest.mp4
Format : MPEG-4
Format/Info : ISO 14496-1 Base Media
Format/Family : MPEG-4
File size : 1.40 MiB
PlayTime : 33s 920ms
Bit rate : 347 Kbps
StreamSize : 11.2 KiB
Encoded date : UTC 2007-12-06 15:51:38
Tagged date : UTC 2007-12-06 15:51:38
Video #1
Codec : H.264
Codec/Info : H.264 (3GPP)
PlayTime : 33s 920ms
Bit rate : 314 Kbps
Width : 320 pixels
Height : 240 pixels
Aspect ratio : 4/3
Frame rate : 25.000 fps
Bits/(Pixel*Frame) : 0.160
StreamSize : 1.27 MiB
Encoded date : UTC 2007-12-06 15:51:38
Tagged date : UTC 2007-12-06 15:51:38
Audio #2
Codec : AAC LC-SBR
Codec/Info : AAC Low Complexity with Spectral Band Replication
PlayTime : 32s 415ms
Bit rate : 32 Kbps
Bit rate mode : VBR
Channel(s) : 2 channels
Sampling rate : 44 KHz
Resolution : 16 bits
StreamSize : 126 KiB
Encoded date : UTC 2007-12-06 15:51:38
Tagged date : UTC 2007-12-06 15:51:38

此视频在Flash Player 9.0.115中顺利播放,声音也没有问题。

研究一下视频和音频的组合

到了这里,就有一些问题了。H.264视频是否一定要搭配AAC音频呢?搭配MP3行么?我压缩了一个采用H.264视频编码,Mp3音频编码(采用LAME MP3)的影片,用终极解码播放正常,但是在Flash Player中,只有图像可以显示,却听不到声音。下面是这个文件的编码信息:

F:\Material\Flash Platform\Flash\Cases\播放H.264视频\333.mp4
General
Complete name : F:\Material\Flash Platform\Flash\Cases\播放H.264视频\333.mp4
Format : MPEG-4
Format/Info : ISO 14496-1 Base Media
Format/Family : MPEG-4
File size : 2.59 MiB
PlayTime : 33s 920ms
Bit rate : 641 Kbps
StreamSize : 13.9 KiB
Encoded date : UTC 2007-12-05 09:21:21
Tagged date : UTC 2007-12-05 09:21:21
Video #1
Codec : H.264
Codec/Info : H.264 (3GPP)
PlayTime : 33s 920ms
Bit rate : 516 Kbps
Width : 320 pixels
Height : 240 pixels
Aspect ratio : 4/3
Frame rate : 25.000 fps
Bits/(Pixel*Frame) : 0.260
StreamSize : 2.09 MiB
Encoded date : UTC 2007-12-05 09:21:21
Tagged date : UTC 2007-12-05 09:21:21
Audio #2
Codec : MPEG-1 Audio
PlayTime : 32s 365ms
Bit rate : 128 Kbps
Bit rate mode : CBR
Channel(s) : 2 channels
Sampling rate : 44 KHz
Resolution : 16 bits
StreamSize : 506 KiB
Encoded date : UTC 2007-12-05 09:21:21
Tagged date : UTC 2007-12-05 09:21:21

又测试了H.264+MP3用AVI封装和3GP封装,在Flash Player中都无法播放声音。看来只有H.264+AAC可以被Flash Player支持。封装可以使用3GP或者MP4,但不支持MKV封装。

关于封装容器和视频文件后缀

我们知道,我们不能仅仅从视频文件的扩展名判断文件的编码。因为很多扩展名是支持多种编码的。例如AVI就只是一种封装容器,它里面的视频和音频编码可以有很多种组合。可以是DivX,也可以是XviD,还可以是MPEG-1。下面的表格(表格来源,ZRong做部分调整)简单的描述了几种封装容器和视频、音频编码的对应情况:

封装容器 视频流编码格式 音频流编码格式 Flash Player是否支持
AVI Xvid MP3 不支持
AVI Divx MP3 不支持
MKV Xvid MP3 不支持
MKV Xvid AAC 不支持
MKV H.264 AAC 不支持
MP4 H.264 AAC 支持
3GP H.263 AAC 不支持
3GP H.264 AAC 支持
FLV Sorenson Spark MP3 支持
FLV On2 VP6 MP3 支持

从上表可以看出,要让Flash Player成功播放H.264视频,最好采用3GP或者MP4封装容器。

AAC编码的混乱情况

上面的压缩,AAC编码器使用的都是Nero Encoder,其中“规格”有这样几个选项:Auto、LC-AAC、LE-AAC和HE-AAC v2。经过测试,这几个规格压缩的音频都可以被Flash Player支持。

Nero Encoder的规格|
Nero Encoder的选项

如果采用CT AAC+编码器,选项就变成了下面这样,更加复杂了。经过测试,这几个选项的组合也都可以被Flash Player支持。不论选择MPEG-4 AAC还是MPEG-2 AAC,都没有问题。

h264ctaac
CT AAC+的选项

如果采用FAAC编码器,选项就变成了下面这样。经过测试,这几个选项的组合也都可以被Flash Player支持,MPEG版本的选择也没有关系。

h264faac
FAAC的选项

事实上,NERO Encoder和CT AAC+中的LC-AAC,就是FAAC中的Low Complexity(无长时预测的AAC);而NERO Encoder中的HE-AAC,就是CT AAC+中的aacPlus,它加了SBR(spectral band replication),HE代表high efficiency。这也是为什么前面压缩WMV视频的时候,选择的是HE-AAC编码,在编码之后的文件信息里面显示的却是下面这些内容的原因了:

Codec : AAC LC-SBR
Codec/Info : AAC Low Complexity with Spectral Band Replication

根据Adobe公布的信息,Flash Player支持这些AAC编码:AAC Main; AAC LC; SBR ,因此,我一般选择使用NERO Encoder的HE-AAC

参考链接

  1. http://bbs.lmtw.com/dispbbs.asp?boardID=111&ID=141583&page=1
  2. http://mediacoder.sourceforge.net/index_zh.htm
  3. http://www.sxzkw.com/1Qm/MediaCoder_jiaocheng_cn.swf
  4. http://www.adobe.com/devnet/flashplayer/articles/http://www.adobe.com/devnet/flashplayer/articles/hd_video_flash_player.html
  5. http://tech.163.com/05/0624/11/1N0Q0HJ800091589.html
  6. http://kb.adobe.com/selfservice/viewContent.do?externalId=kb402866&sliceId=1
posted @ 2008-12-23 17:44 小马歌 阅读(858) | 评论 (0)编辑 收藏
 

用 MEncoder 编码 H. 264 流
In Mac, Miscs, Tools on 9 July 2008 tagged h264, mencoder with no comments

MEncoder 是常用的离线编码器,属于 mplayer 项目的一部分,这里介绍了怎样用 MEncoder 编码常见的视频流。

首先,要安装 x264 编码库,mplayer 需要这个库才能加上 H. 264 编码支持:


$ git clone git://git.videolan.org/x264.git
$ cd x264
$ ./configure
$ make && sudo make install


注意 x264 库需要 yasm 汇编器,MacPorts 下可以用 sudo port install yasm 安装。

然后编译 mplayer (包括 mencoder)。


$ svn co svn://svn.mplayerhq.hu/mplayer/trunk mplayer
$ cd mplayer
$ ./configure # 注意输出中是否有 "Checking for x264 ... yes" 字样
$ make && sudo make install


然后就可以调用 MEncoder 了:


$ mencoder input.fmt -o output.fmt -ovc x264 -oac copy -x264encopts \
    bframes=4:b_pyramid:weight_b:pass=1:psnr:bitrate=1500:turbo=1


其中 input.fmt, output.fmt 分别是输入和输出文件,其调用格式见 MEncoder 的文档,而后面 -x264encopts 的参数制定的是 x264 编码参数,这是影响编码质量和速度的地方,文档中也有专门一节详细说明,这里选取的是一个中等偏上的效果。

posted @ 2008-12-22 14:55 小马歌 阅读(990) | 评论 (0)编辑 收藏
 
下载最新的svn压缩包http://subversion.tigris.org/downloads/subversion-1.4.5.tar.gz
//解压SubVersion安装包 (root用户进行下面的操作) # tar xvzf subversion-1.4.5.tar.gz

//进入解压后的目录

# cd Subversion-1.4.5

//配置subversion安装

#./configure --with-apxs=/usr/local/apache2/bin/apxs --prefix=/usr/local/subversion
--with-apr=/usr/local/apache2 --with-apr-util=/usr/local/apache2 --with-ssl --with-zlib
--enable-maintainer-mode
# make

//安装

# make install

//创建库文件所在的目录 (svnroot用户进行下面的操作)

# mkdir /home/svnroot/repository

//进入subversion的bin目录

# cd /usr/local/subversion/bin

//创建仓库"test"

# ./svnadmin create /home/svnroot/repository/test
# cd /home/svnroot/repository/test

//看看是不是多了些文件,如果是则说明Subversion安装成功了

# ls –l
# cd /usr/local/subversion/bin

//这条语句将把路径/home/user/import下找到的文件导入到你创建的Subversion 仓库中去,
//提交后的修订版为1。

# ./svn import /home/user/import file:///home/svnroot/repository/test –m "注释"

修改Apache配置文件
# cd /usr/local/apadche2/bin
//启动Apache
# ./apachect1 start
# vi /usr/local/apache2/conf/httpd.conf
//在最下面添加
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
<Location /svn>
DAV svn
SVNParentPath /home/svnroot/repository/ //svn父目录
AuthzSVNAccessFile /home/svnroot/repository/authz.conf //权限配置文件
AuthType Basic //连接类型设置
AuthName "Subversion.zoneyump" //连接框提示
AuthUserFile /home/svnroot/repository/authfile //用户配置文件
Require valid-user //采用何种认证
</Location>

//其中authfile是通过"htpasswd [–c] /home/svnroot/repository/authfile username password"来创建的
//"Require valid-user"告诉apache在authfile中所有的用户都可以访问。如果没有它,
//则只能第一个用户可以访问新建库

6. 权限管理
1)增加用户
# htpasswd [-c] /home/svnroot/repository/authfile wooin
//第一次设置用户时使用-c表示新建一个用户文件。回车后输入用户密码,完成对用户的增加
# htpasswd authfile 用户名(加入新的用户)

2)权限分配
# vi /home/svnroot/repository/authz.conf
[test:/] //这表示,仓库test的根目录下的访问权限
wooin = rw //test仓库wooin用户具有读和写权限
bao = r //test仓库bao用户具有读权限
[test2:/] //test2仓库根目录下的访问权限
wooin = r //wooin用户在test2仓库根目录下只有读权限
bao = //bao用户在 test2仓库根目录下无任何权限
[/] //这个表示在所有仓库的根目录下
* = r //这个表示对所有的用户都具有读权限
#[groups] //这个表示群组设置
#svn1-developers = wooin, bao //这个表示某群组里的成员
#svn2-developers = wooin
#[svn1:/]
#@svn1-developers = rw //如果在前面加上@符号,则表示这是个群组权限设置


将这个设置完成后。重启Apache,就可以通过
http://localhost/svn/test
这个URL来访问仓库了,当然,受权限的限制,必须是合法用户才能访问且具有相应的权限
posted @ 2008-12-18 15:21 小马歌 阅读(201) | 评论 (0)编辑 收藏
 

在1.0的时候是好使的 换成2.0的时候
就出现 Missing method or missing parameter converters 这个错误了

2007-11-29 17:44:14 org.directwebremoting.util.CommonsLoggingOutput warn

警告: Marshalling exception: Missing method or missing parameter converters:

主要原因就是DWR2中更新了的内容,原文如下:

The callback-as-first-parameter system has been deprecated since version 0.9 in favor of the callback-as-last-parameter system. In version 2.0 we removed support for the first-parameter option because it caused some hard to detect bugs with null parameters. From version 2.0 the callback must be the last parameter, and can not be the first parameter.

就是说以前版本callback参数是放在参数列表第一个参数,而在0.9版本中callback参数改为参数列表最后一个参数。到2.0版本取消了对callback参数前置的支持。



说明:dwr1.0本身解析器就有点问题,所以推荐 要有dwr2.0.
posted @ 2008-12-16 14:48 小马歌 阅读(250) | 评论 (0)编辑 收藏
 
进入测试环境:
代码:
@echo off
echo proj 本地测试环境
echo.
c:
cd \
if not exist proj-test\con md proj-test
if exist proj-test\hosts.bak goto backup_exists
echo 正在创建备份……
cd \windows\system32\drivers\etc
copy /y hosts \proj-test\hosts.bak > null
echo 完成!
echo.
goto backup_start
:backup_exists
echo 备份文件已经存在,无需备份。
echo.
:backup_start
echo 正在写入测试数据……
echo 127.0.0.1       localhost > hosts
echo 192.168.3.170   proj.com >> hosts
echo 192.168.3.170   www.proj.com >> hosts
echo 192.168.3.170   pics.proj.com >> hosts
echo 192.168.3.170   files.proj.com >> hosts
echo 完成!
echo.
echo 建立 proj 本地测试环境完成。按任意键退出……
pause > null
退出测试环境:
代码:
@echo off
echo proj 本地测试环境
echo.
c:
cd \
if not exist proj-test\hosts.bak goto backup_not_exists
echo 正在还原备份……
copy /y \proj-test\hosts.bak \windows\system32\drivers\etc > null
cd \windows\system32\drivers\etc
if exist hosts del /q hosts
ren hosts.bak hosts
echo 完成!
echo.
echo 正在移除备份……
cd \
rmdir /s/q \proj-test\
echo 完成!
echo.
goto backup_done
:backup_not_exists
echo 备份文件不存在,无法恢复。
echo.
:backup_done
echo 退出 proj 本地测试环境完成。按任意键退出……
pause > null
posted @ 2008-12-15 18:22 小马歌 阅读(4018) | 评论 (3)编辑 收藏
 
作者:肖文鹏 发文时间:2004.03.22
在为Linux开发应用程序时,绝大多数情况下使用的都是C语言,因此几乎每一位Linux程序员面临的首要问题都是如何灵活运用C编译器。目前Linux下最常用的C语言编译器是GCC(GNU Compiler Collection),它是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。GCC不仅功能非常强大,结构也异常灵活。最值得称道的一点就是它可以通过不同的前端模块来支持各种语言,如Java、Fortran、Pascal、Modula-3和Ada等。

开放、自由和灵活是Linux的魅力所在,而这一点在GCC上的体现就是程序员通过它能够更好地控制整个编译过程。在使用GCC编译程序时,编译过程可以被细分为四个阶段:

◆ 预处理(Pre-Processing)

◆ 编译(Compiling)

◆ 汇编(Assembling)

◆ 链接(Linking)

Linux程序员可以根据自己的需要让GCC在编译的任何阶段结束,以便检查或使用编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为今后的调试做好准备。和其它常用的编译器一样,GCC也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。

GCC提供了30多条警告信息和三个警告级别,使用它们有助于增强程序的稳定性和可移植性。此外,GCC还对标准的C和C++语言进行了大量的扩展,提高程序的执行效率,有助于编译器进行代码优化,能够减轻编程的工作量。

GCC起步

在学习使用GCC之前,下面的这个例子能够帮助用户迅速理解GCC的工作原理,并将其立即运用到实际的项目开发中去。首先用熟悉的编辑器输入清单1所示的代码:

清单1:hello.c

 #include <stdio.h>
 int main(void)
 {
  printf ("Hello world, Linux programming!\n");
  return 0;
 }
 
然后执行下面的命令编译和运行这段程序:

 # gcc hello.c -o hello # ./hello Hello world, Linux programming!
 
从程序员的角度看,只需简单地执行一条GCC命令就可以了,但从编译器的角度来看,却需要完成一系列非常繁杂的工作。首先,GCC需要调用预处理程序cpp,由它负责展开在源文件中定义的宏,并向其中插入“#include”语句所包含的内容;接着,GCC会调用ccl和as将处理后的源代码编译成目标代码;最后,GCC会调用链接程序ld,把生成的目标代码链接成一个可执行程序。

为了更好地理解GCC的工作过程,可以把上述编译过程分成几个步骤单独进行,并观察每步的运行结果。第一步是进行预编译,使用-E参数可以让GCC在预处理结束后停止编译过程:

 # gcc -E hello.c -o hello.i
 
此时若查看hello.cpp文件中的内容,会发现stdio.h的内容确实都插到文件里去了,而其它应当被预处理的宏定义也都做了相应的处理。下一步是将hello.i编译为目标代码,这可以通过使用-c参数来完成:

 # gcc -c hello.i -o hello.o
 
GCC默认将.i文件看成是预处理后的C语言源代码,因此上述命令将自动跳过预处理步骤而开始执行编译过程,也可以使用-x参数让GCC从指定的步骤开始编译。最后一步是将生成的目标文件链接成可执行文件:

 # gcc hello.o -o hello
 
在采用模块化的设计思想进行软件开发时,通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用GCC能够很好地管理这些编译单元。假设有一个由foo1.c和foo2.c两个源文件组成的程序,为了对它们进行编译,并最终生成可执行程序foo,可以使用下面这条命令:

 # gcc foo1.c foo2.c -o foo
 
如果同时处理的文件不止一个,GCC仍然会按照预处理、编译和链接的过程依次进行。如果深究起来,上面这条命令大致相当于依次执行如下三条命令:

 # gcc -c foo1.c -o foo1.o # gcc -c foo2.c -o foo2.o # gcc foo1.o foo2.o -o foo
 
在编译一个包含许多源文件的工程时,若只用一条GCC命令来完成编译是非常浪费时间的。假设项目中有100个源文件需要编译,并且每个源文件中都包含10000行代码,如果像上面那样仅用一条GCC命令来完成编译工作,那么GCC需要将每个源文件都重新编译一遍,然后再全部连接起来。很显然,这样浪费的时间相当多,尤其是当用户只是修改了其中某一个文件的时候,完全没有必要将每个文件都重新编译一遍,因为很多已经生成的目标文件是不会改变的。要解决这个问题,关键是要灵活运用GCC,同时还要借助像Make这样的工具。

警告提示功能

GCC包含完整的出错检查和警告提示功能,它们可以帮助Linux程序员写出更加专业和优美的代码。先来读读清单2所示的程序,这段代码写得很糟糕,仔细检查一下不难挑出很多毛病:

◆main函数的返回值被声明为void,但实际上应该是int;

◆使用了GNU语法扩展,即使用long long来声明64位整数,不符合ANSI/ISO C语言标准;

◆main函数在终止前没有调用return语句。

清单2:illcode.c

 #include <stdio.h>
 void main(void)
 {
  long long int var = 1;
  printf("It is not standard C code!\n");
 }

下面来看看GCC是如何帮助程序员来发现这些错误的。当GCC在编译不符合ANSI/ISO C语言标准的源代码时,如果加上了-pedantic选项,那么使用了扩展语法的地方将产生相应的警告信息:

 # gcc -pedantic illcode.c -o illcode illcode.c: In function `main': illcode.c:9: ISO C89 does not support `long long' illcode.c:8: return type of `main' is not `int'

需要注意的是,-pedantic编译选项并不能保证被编译程序与ANSI/ISO C标准的完全兼容,它仅仅只能用来帮助Linux程序员离这个目标越来越近。或者换句话说,-pedantic选项能够帮助程序员发现一些不符合ANSI/ISO C标准的代码,但不是全部,事实上只有ANSI/ISO C语言标准中要求进行编译器诊断的那些情况,才有可能被GCC发现并提出警告。

除了-pedantic之外,GCC还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W开头,其中最有价值的当数-Wall了,使用它能够使GCC产生尽可能多的警告信息:

 # gcc -Wall illcode.c -o illcode illcode.c:8: warning: return type of `main' is not `int' illcode.c: In function `main': illcode.c:9: warning: unused variable `var'

GCC给出的警告信息虽然从严格意义上说不能算作是错误,但却很可能成为错误的栖身之所。一个优秀的Linux程序员应该尽量避免产生警告信息,使自己的代码始终保持简洁、优美和健壮的特性

在处理警告方面,另一个常用的编译选项是-Werror,它要求GCC将所有的警告当成错误进行处理,这在使用自动编译工具(如Make等)时非常有用。如果编译时带上-Werror选项,那么GCC会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改。只有当相应的警告信息消除时,才可能将编译过程继续朝前推进。执行情况如下:

 # gcc -Wall -Werror illcode.c -o illcode cc1: warnings being treated as errors illcode.c:8: warning: return type of `main' is not `int' illcode.c: In function `main': illcode.c:9: warning: unused variable `var'

对Linux程序员来讲,GCC给出的警告信息是很有价值的,它们不仅可以帮助程序员写出更加健壮的程序,而且还是跟踪和调试程序的有力工具。建议在用GCC编译源代码时始终带上-Wall选项,并把它逐渐培养成为一种习惯,这对找出常见的隐式编程错误很有帮助。

库依赖

在Linux下开发软件时,完全不使用第三方函数库的情况是比较少见的,通常来讲都需要借助一个或多个函数库的支持才能够完成相应的功能。从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(.so或者.a)的集合。虽然Linux下的大多数函数都默认将头文件放到/usr/include/目录下,而库文件则放到/usr/lib/目录下,但并不是所有的情况都是这样。正因如此,GCC在编译时必须有自己的办法来查找所需要的头文件和库文件。

GCC采用搜索目录的办法来查找所需要的文件,-I选项可以向GCC的头文件搜索路径中添加新的目录。例如,如果在/home/xiaowp/include/目录下有编译时所需要的头文件,为了让GCC能够顺利地找到它们,就可以使用-I选项:

 # gcc foo.c -I /home/xiaowp/include -o foo

同样,如果使用了不在标准位置的库文件,那么可以通过-L选项向GCC的库文件搜索路径中添加新的目录。例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so,为了让GCC能够顺利地找到它,可以使用下面的命令:

 # gcc foo.c -L /home/xiaowp/lib -lfoo -o foo

值得好好解释一下的是-l选项,它指示GCC去连接库文件libfoo.so。Linux下的库文件在命名时有一个约定,那就是应该以lib三个字母开头,由于所有的库文件都遵循了同样的规范,因此在用-l选项指定链接的库文件名时可以省去lib三个字母,也就是说GCC在对-lfoo进行处理时,会自动去链接名为libfoo.so的文件。

Linux下的库文件分为两大类分别是动态链接库(通常以.so结尾)和静态链接库(通常以.a结尾),两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。默认情况下,GCC在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static选项,强制使用静态链接库。例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so和libfoo.a,为了让GCC在链接时只用到静态链接库,可以使用下面的命令:

 # gcc foo.c -L /home/xiaowp/lib -static -lfoo -o foo
 
代码优化

代码优化指的是编译器通过分析源代码,找出其中尚未达到最优的部分,然后对其重新进行组合,目的是改善程序的执行性能。GCC提供的代码优化功能非常强大,它通过编译选项-On来控制优化代码的生成,其中n是一个代表优化级别的整数。对于不同版本的GCC来讲,n的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从0变化到2或3。

编译时使用选项-O可以告诉GCC同时减小代码的长度和执行时间,其效果等价于-O1。在这一级别上能够进行的优化类型虽然取决于目标处理器,但一般都会包括线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化。选项-O2告诉GCC除了完成所有-O1级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项-O3则除了完成所有-O2级别的优化之外,还包括循环展开和其它一些与处理器特性相关的优化工作。通常来说,数字越大优化的等级越高,同时也就意味着程序的运行速度越快。许多Linux程序员都喜欢使用-O2选项,因为它在优化长度、编译时间和代码大小之间,取得了一个比较理想的平衡点。

下面通过具体实例来感受一下GCC的代码优化功能,所用程序如清单3所示。

清单3:optimize.c

 #include <stdio.h>
 int main(void)
 {
  double counter;
  double result;
  double temp;
  
  for (counter = 0; counter < 2000.0 * 2000.0 * 2000.0 / 20.0 + 2020; counter += (5 - 1) / 4)
  {
    temp = counter / 1979; result = counter;
  }
  printf("Result is %lf\n", result); return 0;
 }

首先不加任何优化选项进行编译:

 # gcc -Wall optimize.c -o optimize
 
借助Linux提供的time命令,可以大致统计出该程序在运行时所需要的时间:

 # time ./optimize Result is 400002019.000000 real 0m14.942s user 0m14.940s sys 0m0.000s
 
接下去使用优化选项来对代码进行优化处理:

 # gcc -Wall -O optimize.c -o optimize
 
在同样的条件下再次测试一下运行时间:

 # time ./optimize Result is 400002019.000000 real 0m3.256s user 0m3.240s sys 0m0.000s
 
对比两次执行的输出结果不难看出,程序的性能的确得到了很大幅度的改善,由原来的14秒缩短到了3秒。这个例子是专门针对GCC的优化功能而设计的,因此优化前后程序的执行速度发生了很大的改变。尽管GCC的代码优化功能非常强大,但作为一名优秀的Linux程序员,首先还是要力求能够手工编写出高质量的代码。如果编写的代码简短,并且逻辑性强,编译器就不会做更多的工作,甚至根本用不着优化。

优化虽然能够给程序带来更好的执行性能,但在如下一些场合中应该避免优化代码:

◆ 程序开发的时候 优化等级越高,消耗在编译上的时间就越长,因此在开发的时候最好不要使用优化选项,只有到软件发行或开发结束的时候,才考虑对最终生成的代码进行优化。

◆ 资源受限的时候 一些优化选项会增加可执行代码的体积,如果程序在运行时能够申请到的内存资源非常紧张(如一些实时嵌入式设备),那就不要对代码进行优化,因为由这带来的负面影响可能会产生非常严重的后果。

◆ 跟踪调试的时候 在对代码进行优化的时候,某些代码可能会被删除或改写,或者为了取得更佳的性能而进行重组,从而使跟踪和调试变得异常困难。

调试

一个功能强大的调试器不仅为程序员提供了跟踪程序执行的手段,而且还可以帮助程序员找到解决问题的方法。对于Linux程序员来讲,GDB(GNU Debugger)通过与GCC的配合使用,为基于Linux的软件开发提供了一个完善的调试环境。

默认情况下,GCC在编译时不会将调试符号插入到生成的二进制代码中,因为这样会增加可执行文件的大小。如果需要在编译时生成调试符号信息,可以使用GCC的-g或者-ggdb选项。GCC在产生调试符号时,同样采用了分级的思路,开发人员可以通过在-g选项后附加数字1、2或3来指定在代码中加入调试信息的多少。默认的级别是2(-g2),此时产生的调试信息包括扩展的符号表、行号、局部或外部变量信息。级别3(-g3)包含级别2中的所有调试信息,以及源代码中定义的宏。级别1(-g1)不包含局部变量和与行号有关的调试信息,因此只能够用于回溯跟踪和堆栈转储之用。回溯跟踪指的是监视程序在运行过程中的函数调用历史,堆栈转储则是一种以原始的十六进制格式保存程序执行环境的方法,两者都是经常用到的调试手段。

GCC产生的调试符号具有普遍的适应性,可以被许多调试器加以利用,但如果使用的是GDB,那么还可以通过-ggdb选项在生成的二进制代码中包含GDB专用的调试信息。这种做法的优点是可以方便GDB的调试工作,但缺点是可能导致其它调试器(如DBX)无法进行正常的调试。选项-ggdb能够接受的调试级别和-g是完全一样的,它们对输出的调试符号有着相同的影响。

需要注意的是,使用任何一个调试选项都会使最终生成的二进制文件的大小急剧增加,同时增加程序在执行时的开销,因此调试选项通常仅在软件的开发和调试阶段使用。调试选项对生成代码大小的影响从下面的对比过程中可以看出来:

 # gcc optimize.c -o optimize # ls optimize -l -rwxrwxr-x 1 xiaowp xiaowp 11649 Nov 20 08:53 optimize (未加调试选项) # gcc -g optimize.c -o optimize # ls optimize -l -rwxrwxr-x 1 xiaowp xiaowp 15889 Nov 20 08:54 optimize (加入调试选项)
 
虽然调试选项会增加文件的大小,但事实上Linux中的许多软件在测试版本甚至最终发行版本中仍然使用了调试选项来进行编译,这样做的目的是鼓励用户在发现问题时自己动手解决,是Linux的一个显著特色。

下面还是通过一个具体的实例说明如何利用调试符号来分析错误,所用程序见清单4所示。

清单4:crash.c

 #include <stdio.h>
 int main(void)
 {
  int input =0;
  
  printf("Input an integer:");
  scanf("%d", input);
  printf("The integer you input is %d\n", input);
  return 0;
 }
 
编译并运行上述代码,会产生一个严重的段错误(Segmentation fault)如下:

 # gcc -g crash.c -o crash # ./crash Input an integer:10 Segmentation fault
 
为了更快速地发现错误所在,可以使用GDB进行跟踪调试,方法如下:

 # gdb crash GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) …… (gdb)
 
当GDB提示符出现的时候,表明GDB已经做好准备进行调试了,现在可以通过run命令让程序开始在GDB的监控下运行:

 (gdb) run Starting program: /home/xiaowp/thesis/gcc/code/crash Input an integer:10 Program received signal SIGSEGV, Segmentation fault. 0x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
 
仔细分析一下GDB给出的输出结果不难看出,程序是由于段错误而导致异常中止的,说明内存操作出了问题,具体发生问题的地方是在调用_IO_vfscanf_internal ( )的时候。为了得到更加有价值的信息,可以使用GDB提供的回溯跟踪命令backtrace,执行结果如下:

 (gdb) backtrace #0 0x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6 #1 0xbffff0c0 in ?? () #2 0x4008e0ba in scanf () from /lib/libc.so.6 #3 0x08048393 in main () at crash.c:11 #4 0x40042917 in __libc_start_main () from /lib/libc.so.6
 
跳过输出结果中的前面三行,从输出结果的第四行中不难看出,GDB已经将错误定位到crash.c中的第11行了。现在仔细检查一下:

 (gdb) frame 3 #3 0x08048393 in main () at crash.c:11 11 scanf("%d", input);
 
使用GDB提供的frame命令可以定位到发生错误的代码段,该命令后面跟着的数值可以在backtrace命令输出结果中的行首找到。现在已经发现错误所在了,应该将

 scanf("%d", input); 改为 scanf("%d", &input);
 
完成后就可以退出GDB了,命令如下:

 (gdb) quit
 
GDB的功能远远不止如此,它还可以单步跟踪程序、检查内存变量和设置断点等。

调试时可能会需要用到编译器产生的中间结果,这时可以使用-save-temps选项,让GCC将预处理代码、汇编代码和目标代码都作为文件保存起来。如果想检查生成的代码是否能够通过手工调整的办法来提高执行性能,在编译过程中生成的中间文件将会很有帮助,具体情况如下:

 # gcc -save-temps foo.c -o foo # ls foo* foo foo.c foo.i foo.s
 
GCC支持的其它调试选项还包括-p和-pg,它们会将剖析(Profiling)信息加入到最终生成的二进制代码中。剖析信息对于找出程序的性能瓶颈很有帮助,是协助Linux程序员开发出高性能程序的有力工具。在编译时加入-p选项会在生成的代码中加入通用剖析工具(Prof)能够识别的统计信息,而-pg选项则生成只有GNU剖析工具(Gprof)才能识别的统计信息。

最后提醒一点,虽然GCC允许在优化的同时加入调试符号信息,但优化后的代码对于调试本身而言将是一个很大的挑战。代码在经过优化之后,在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化。

上次的培训园地中介绍了GCC的编译过程、警告提示功能、库依赖、代码优化和程序调试六个方面的内容。这期是最后的一部分内容。

加速

在将源代码变成可执行文件的过程中,需要经过许多中间步骤,包含预处理、编译、汇编和连接。这些过程实际上是由不同的程序负责完成的。大多数情况下GCC可以为Linux程序员完成所有的后台工作,自动调用相应程序进行处理。

这样做有一个很明显的缺点,就是GCC在处理每一个源文件时,最终都需要生成好几个临时文件才能完成相应的工作,从而无形中导致处理速度变慢。例如,GCC在处理一个源文件时,可能需要一个临时文件来保存预处理的输出、一个临时文件来保存编译器的输出、一个临时文件来保存汇编器的输出,而读写这些临时文件显然需要耗费一定的时间。当软件项目变得非常庞大的时候,花费在这上面的代价可能会变得很沉重。

解决的办法是,使用Linux提供的一种更加高效的通信方式—管道。它可以用来同时连接两个程序,其中一个程序的输出将被直接作为另一个程序的输入,这样就可以避免使用临时文件,但编译时却需要消耗更多的内存。

在编译过程中使用管道是由GCC的-pipe选项决定的。下面的这条命令就是借助GCC的管道功能来提高编译速度的:

 # gcc -pipe foo.c -o foo
 
在编译小型工程时使用管道,编译时间上的差异可能还不是很明显,但在源代码非常多的大型工程中,差异将变得非常明显。

文件扩展名

在使用GCC的过程中,用户对一些常用的扩展名一定要熟悉,并知道其含义。为了方便大家学习使用GCC,在此将这些扩展名罗列如下:

.c C原始程序;

.C C++原始程序;

.cc C++原始程序;

.cxx C++原始程序;

.m Objective-C原始程序;

.i 已经过预处理的C原始程序;

.ii 已经过预处理之C++原始程序;

.s 组合语言原始程序;

.S 组合语言原始程序;

.h 预处理文件(标头文件);

.o 目标文件;

.a 存档文件。

GCC常用选项

GCC作为Linux下C/C++重要的编译环境,功能强大,编译选项繁多。为了方便大家日后编译方便,在此将常用的选项及说明罗列出来如下:

-c 通知GCC取消链接步骤,即编译源码并在最后生成目标文件;

-Dmacro 定义指定的宏,使它能够通过源码中的#ifdef进行检验;

-E 不经过编译预处理程序的输出而输送至标准输出;

-g3 获得有关调试程序的详细信息,它不能与-o选项联合使用;

-Idirectory 在包含文件搜索路径的起点处添加指定目录;

-llibrary 提示链接程序在创建最终可执行文件时包含指定的库;

-O、-O2、-O3 将优化状态打开,该选项不能与-g选项联合使用;

-S 要求编译程序生成来自源代码的汇编程序输出;

-v 启动所有警报;

-Wall 在发生警报时取消编译操作,即将警报看作是错误;

-Werror 在发生警报时取消编译操作,即把报警当作是错误;

-w 禁止所有的报警。

小结

GCC是在Linux下开发程序时必须掌握的工具之一。本文对GCC做了一个简要的介绍,主要讲述了如何使用GCC编译程序、产生警告信息、调试程序和加快GCC的编译速度。对所有希望早日跨入Linux开发者行列的人来说,GCC就是成为一名优秀的Linux程序员的起跑线。

posted @ 2008-12-11 16:14 小马歌 阅读(85) | 评论 (0)编辑 收藏
 

来源:http://www.7880.com/Info/Article-33fb30a0.html

2004年4月20日最新版本的GCC编译器3.4.0发布了。目前,GCC可以用来编译C/C++、FORTRAN、JAVA、OBJC、ADA等语言的程序,可根据需要选择安装支持的语言。GCC 3.4.0比以前版本更好地支持了C++标准。本文以在Redhat Linux上安装GCC3.4.0为例,介绍了GCC的安装过程。

  安装之前,系统中必须要有cc或者gcc等编译器,并且是可用的,或者用环境变量CC指定系统上的编译器。如果系统上没有编译器,不能安装源代码形式的GCC 3.4.0。如果是这种情况,可以在网上找一个与你系统相适应的如RPM等二进制形式的GCC软件包来安装使用。本文介绍的是以源代码形式提供的GCC软件包的安装过程,软件包本身和其安装过程同样适用于其它Linux和Unix系统。

  系统上原来的GCC编译器可能是把gcc等命令文件、库文件、头文件等分别存放到系统中的不同目录下的。与此不同,现在GCC建议我们将一个版本的GCC安装在一个单独的目录下。这样做的好处是将来不需要它的时候可以方便地删除整个目录即可(因为GCC没有uninstall功能);缺点是在安装完成后要做一些设置工作才能使编译器工作正常。在本文中我采用这个方案安装GCC 3.4.0,并且在安装完成后,仍然能够使用原来低版本的GCC编译器,即一个系统上可以同时存在并使用多个版本的GCC编译器。

  按照本文提供的步骤和设置选项,即使以前没有安装过GCC,也可以在系统上安装上一个可工作的新版本的GCC编译器。

  1. 下载

  在GCC网站上(http://gcc.gnu.org/)或者通过网上搜索可以查找到下载资源。目前GCC的最新版本为 3.4.0。可供下载的文件一般有两种形式:gcc-3.4.0.tar.gz和gcc-3.4.0.tar.bz2,只是压缩格式不一样,内容完全一致,下载其中一种即可。

  2. 解压缩

  根据压缩格式,选择下面相应的一种方式解包(以下的“%”表示命令行提示符):

  % tar xzvf gcc-3.4.0.tar.gz
  或者
  % bzcat gcc-3.4.0.tar.bz2 | tar xvf -

  新生成的gcc-3.4.0这个目录被称为源目录,用${srcdir}表示它。以后在出现${srcdir}的地方,应该用真实的路径来替换它。用pwd命令可以查看当前路径。

  在${srcdir}/INSTALL目录下有详细的GCC安装说明,可用浏览器打开index.html阅读。

  3. 建立目标目录
 
  目标目录(用${objdir}表示)是用来存放编译结果的地方。GCC建议编译后的文件不要放在源目录${srcdir]中(虽然这样做也可以),最好单独存放在另外一个目录中,而且不能是${srcdir}的子目录。

  例如,可以这样建立一个叫 gcc-build 的目标目录(与源目录${srcdir}是同级目录):

  % mkdir gcc-build
  % cd gcc-build

  以下的操作主要是在目标目录 ${objdir} 下进行。

  4. 配置
 
  配置的目的是决定将GCC编译器安装到什么地方(${destdir}),支持什么语言以及指定其它一些选项等。其中,${destdir}不能与${objdir}或${srcdir}目录相同。

  配置是通过执行${srcdir}下的configure来完成的。其命令格式为(记得用你的真实路径替换${destdir}):

  % ${srcdir}/configure --prefix=${destdir} [其它选项]

  例如,如果想将GCC 3.4.0安装到/usr/local/gcc-3.4.0目录下,则${destdir}就表示这个路径。

  在我的机器上,我是这样配置的:

  % ../gcc-3.4.0/configure --prefix=/usr/local/gcc-3.4.0 --enable-threads=posix --disable-checking --enable--long-long --host=i386-redhat-linux --with-system-zlib --enable-languages=c,c++,java

  将GCC安装在/usr/local/gcc-3.4.0目录下,支持C/C++和JAVA语言,其它选项参见GCC提供的帮助说明。

  5. 编译

  % make

  这是一个漫长的过程。在我的机器上(P4-1.6),这个过程用了50多分钟。

  6. 安装

  执行下面的命令将编译好的库文件等拷贝到${destdir}目录中(根据你设定的路径,可能需要管理员的权限):

  % make install

  至此,GCC 3.4.0安装过程就完成了。

  6. 其它设置

  GCC 3.4.0的所有文件,包括命令文件(如gcc、g++)、库文件等都在${destdir}目录下分别存放,如命令文件放在bin目录下、库文件在lib下、头文件在include下等。由于命令文件和库文件所在的目录还没有包含在相应的搜索路径内,所以必须要作适当的设置之后编译器才能顺利地找到并使用它们。

  6.1 gcc、g++、gcj的设置

  要想使用GCC 3.4.0的gcc等命令,简单的方法就是把它的路径${destdir}/bin放在环境变量PATH中。我不用这种方式,而是用符号连接的方式实现,这样做的好处是我仍然可以使用系统上原来的旧版本的GCC编译器。

  首先,查看原来的gcc所在的路径:

  % which gcc

  在我的系统上,上述命令显示:/usr/bin/gcc。因此,原来的gcc命令在/usr/bin目录下。我们可以把GCC 3.4.0中的gcc、g++、gcj等命令在/usr/bin目录下分别做一个符号连接:

  % cd /usr/bin
  % ln -s ${destdir}/bin/gcc gcc34
  % ln -s ${destdir}/bin/g++ g++34
  % ln -s ${destdir}/bin/gcj gcj34

  这样,就可以分别使用gcc34、g++34、gcj34来调用GCC 3.4.0的gcc、g++、gcj完成对C、C++、JAVA程序的编译了。同时,仍然能够使用旧版本的GCC编译器中的gcc、g++等命令。

  6.2 库路径的设置

  将${destdir}/lib路径添加到环境变量LD_LIBRARY_PATH中,最好添加到系统的配置文件中,这样就不必要每次都设置这个环境变量了。

  例如,如果GCC 3.4.0安装在/usr/local/gcc-3.4.0目录下,在RH Linux下可以直接在命令行上执行或者在文件/etc/profile中添加下面一句:

  setenv LD_LIBRARY_PATH /usr/local/gcc-3.4.0/lib:$LD_LIBRARY_PATH

  7. 测试
 
  用新的编译命令(gcc34、g++34等)编译你以前的C、C++程序,检验新安装的GCC编译器是否能正常工作。

  8. 根据需要,可以删除或者保留${srcdir}和${objdir}目录。

posted @ 2008-12-11 16:13 小马歌 阅读(124) | 评论 (0)编辑 收藏
 

1,lame下低点的版本,比如 lame-3.93.1
2,x264下载列表:ftp://ftp.videolan.org/pub/videolan/x264/snapshots [每天一个版本]
3,make版本要3.81以上:ftp://ftp.gnu.org/gnu/
4,今天在公司编译ffmpeg,结果./configure 正常,但是在make的时候出现了下面的错误,在网上寻找,居然找到了解决办法,特转过来作为自己的总结,方便日后查看

# make
gcc -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I. -I"/home/yujingtao/soft/ffmpeg" -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -fasm -std=c99 -fomit-frame-pointer -pthread -g -Wdeclaration-after-statement -Wall -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wcast-qual -Wwrite-strings -O3 -fno-math-errno       -c -o libavdevice/v4l.o libavdevice/v4l.c
In file included from libavdevice/v4l.c:32:
/usr/include/linux/videodev.h:55: error: syntax error before "ulong"
/usr/include/linux/videodev.h:71: error: syntax error before '}' token
libavdevice/v4l.c: In function `grab_read_header':
libavdevice/v4l.c:77: error: storage size of 'tuner' isn't known
libavdevice/v4l.c:141: error: invalid application of `sizeof' to incomplete type `video_tuner'
libavdevice/v4l.c:148: error: invalid application of `sizeof' to incomplete type `video_tuner'
libavdevice/v4l.c:77: warning: unused variable `tuner'
make: *** [libavdevice/v4l.o] 错误 1


vi /usr/include/linux/videodev.h

查找rangelow, rangehigh;      /* Tuner range */这一行
把  ulong rangelow, rangehigh;      /* Tuner range */
改为:
     unsigned long rangelow, rangehigh;      /* Tuner range */

参考:
http://www.2hei.net/mt/2008/08/ffmpeg-3gp-install.html

posted @ 2008-12-10 18:17 小马歌 阅读(992) | 评论 (1)编辑 收藏
仅列出标题
共95页: First 上一页 75 76 77 78 79 80 81 82 83 下一页 Last