gcc的-E选项什么意思

gcc的-E选项可以为你生成预编译后的文件。预编译后的文件将把c文件中的宏以及该文件包含的所有头文件展开。这样就没有了一层一层进入嵌套包含的头文件。下面是一个使用gcc的-E选项的例子。

下面是来自gcc mannual page的解释:

-E Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of  preprocessed source code, which is sent to the standard output. Input files which don't require preprocessing are ignored.

 

$ gcc -E drivers/char/mydrv.c -D__KERNEL__ -Iinclude -Iinclude/asm-x86/mach-default > mydrv.i

 

其中的-I选项告诉编译器在哪些目录中搜索所需要的头文件。

还可以用gcc的-S选项生成汇编码的文件。如:

$ gcc -S drivers/char/mydrv.c -D__KERNEL__ -Iinclude -Ianother/include/path

ykyi.net

 

 

 

读论文 宏观层面的软件演化

软件工程进展读论文报告

论文:Macro-level software evolution: a case study of a large software compilation (宏观层面的软件演化:举例研究一个大型软件的编译)于2008年11月29号发表于实证软件工程。

论文的背景和动机:

软件演化(Software Evolution)一般研究的是由相互合作的团队开发的单个的软件产品。但是越来越多的软件系统包含了大量了不同的应用和运行库。很多这些应用和运行库是由不同的团队面向不同的目的开发的。这种大型软件系统是如何演化的呢?他们有些什么特性特点呢。但要研究这样的大型软件系统需要有这个系统所涉及的所有应用和库在各个时间点的源代码。这并非一件易事。因此才鲜有研究文献涉及该类型的系统。

这些年,很多大型自由软件系统取得了巨大成功,例如Fedora Linux, Debian GNU/Linux, FreeBSD, OpenBSD。这些大型自由软件集成成百上千独立应用和库,并且几乎所有自由件的授权都充许自由得到相应的源代码。这为我们研究大型软件系统的演化提供了必要条件。

构成大型软件系统的各个工程是独立开发的(某些软件系统把这些独立开发的工程称之为包),但从整个软件系统的视角来看,它们之间却存在复杂的依存关系,甚至在某些情况下会是冲突关系。因此,单个的研究某特定工程的演化与在整个软件系统中研究软件的演化是不同的。

论文旨在通过分析一个大型自由软件系统的演化来揭示大型自由软件系统的一般规律以至私有大型软件的某些规律和特点。

论文中实证研究的定义、规划、执行与分析:

Debian GNU/Linux是一个非常流行的大型软件系统。它包括了各种大大小小的应用和库,其中一些演化的非常迅速,其中一些又长期没有变化,不断有新的包加入该系统又不断有过时的包被抛弃。仅管这些包是相互独立开发并自我演化,但在Debian系统中,它们之前有着非常复杂的关系。这个复杂关系随着Debian系统的演化而变得更加复杂,使之越来越难以维护。

 

[定义]

这篇论文,即以Debian软件系统为例,主要考察了九年以来Deiban系统中包的总数,包的大小,开发语言,包之间的相互依赖性等多个指标,在宏观上研究整个Debian软件系统的演化。最终得出一些大型自由软件的特点,分析这些特点能指导单独的软件研发使之能更好的集成进大型系统中。

 

[规划和执行]

Debian组织成一个个包(package),一般地讲每个包对应于一个应用或一个库,少数情况下对应于文档或其它。包分两种,一种是包含运行的二进制文件的包,另一个是源文件包。源代码包在构建以后通常生成一个或多个二进制包。Debian为每一个发行版本维护了一系列配置文件,这些配置文件设定了每个发行版所需要的运行环境,包含了哪些包。而每个包的配置文件也约定了它所依赖的其它包的关系。

这份报告研究了Debian从2.0到4.0的所有稳定发行版号,即2.0,2.1,2.2,3.0,3.1,4.0。对于每一个待考察的版本,配置文件被事先写好的脚本分析,把分析到的数据存入数据库中。然后,每一个源码包被自动获取,源代码行数被SLOC工具分析得出;源代码所使用的编程语言也用SLOC工具识别到。而包与包之间的依赖性亦可由Debian发行版的配置文件中记录的Depends,Pre-Depends,Suggests,Recommends字段得到。这些信息被分析出来以后,包与包之间的依赖关系由一个有向图描述出来。有向图中的结点表示一个包,连接结点的边表示包与包之间的依赖关系。每个待研究的Debian发行版都会生成一个这样的IDG(Inter-Dependency Graph),通过运用有向图的算法可以得到很多研究关心的数据,比如最流行的包(The most popular package)。

[分析]

1. 发行版总大小

结果显示每隔两年,发行版的大小(统计发行版的所有源代码行数)就会增加一倍。截止2007年的Debian 4.0,已经共有4亿行代码和1万个包。如此大的规模会为未来的继续发展带来不小的麻烦,在最新的发行版中已经可以看到超大规模的几数级增长已经给某些时间点带来了延迟。

2. 包的大小

而包的平均大小指标在九年内几乎维持不变。因为软件系统的总代码量迅速增长而平均包大小不变,这意味着越来越多的包被增加到系统中。Debian .4.0的包数目是Debian 2.0的包数目的10倍。为了应对包的不断增多,Debian系统需要迅速增加包维护者以及每个维护者需要应对的包数目。包数目的迅速增长也是一个非常棘手的问题,特别影响了包维护者的相互配合。

3. 包的维护

Debian维护者的任务之一就是跟踪新版本的软件包,给它们重新打包,更新相应的包描述。一但一个新版本的包发布了,包的名字就会相应变化。因此可以通过分析发行版的包的名称确定软件包有没有被维护过。

分析数据后显示Debian 2.0的1096个包里面有721个可以在4.0中找到。这意味着Debian2.0中只有30%的包在九年后的Debian 4.0中被移除。再之,Debian 3.1的10106个包中,而在4.0中仍然存在的有7300个,这个比例也大概是30%。

对于没有改变过的包。Debian 4.0中有132个包与Debian 2.0中毫无改变。换言之,Debian 2.0中不少于15%的包在九年后仍然没有任何改变在Debian 4.0中。

必须指出的是未改变的包所包含的文件数目并不能反应所有的未改变的文件数目。后者的数字应该高一些:有相当多的文件在Debian的各个发行版之间没有改变,即使它们所属的包的名字变化了。

4. 开发语言

统计数据显示Debian各个发行版中最多使用的开发语言仍然是C语言,并且较之于第二名优势明显。但对于C语言,在第Debian 2.0中,C占了77%的份额;到了Debian 4.0,C语言的份额下降到了51%。而对于C++,则是从2.0时占6%的市场份额上升到了4.0时的19%。总体上看,C语言的重要性一直在相对减弱,而C++和其它一些开发语言都保持了一定增长的趋势。必须说明的一点时,仅管C语言的份额在下降,但从C语言代码绝的绝对数量上看仍然在快速增加。

Shell语一直处在第三的位置,因为这种语言在几乎每个包中都有。从大量的小尺寸包到重量级的包,Shell无所不在。

另一个值得关注的必然是Java。在Debian 3.0时,Java编写的应用仅仅占到0.5%。到了Debian 3.1发布时,这个数字飞速上升到1.7%,到了Debian 4.0時,增加到了3.1%,稳定地占据了第四的位置。Java的快速增长得益于几个大型应用使用Java语言进行开发,比如:Eclipse和Azureus。实际上,Java还是被低估了。因为授权许可证的问题,包含大量Java代码的Sun JDK和Sun JRE没有统计在内,而其它语言则至少包含了一个常用的开发环境。

就代码量而言,一些比较生僻冷门的语言也占据了比较明显的份额。这是因为虽然这些生僻语言仅仅出现在少量包中,但这些开发包的尺寸却很大。比如,Ada语言在Debian 3.0中有57万行代码,其中的43万行都来自于Ada的编译器,开发库和开发工具。

通过观察开发语言的使用率趋势,可以估算出有多少开发者比较熟悉某种开发语言。同时,不同语言的不断演化也反映出自由软件在开发语言层面的变化。

5. 文件大小

大多数开发语言的源代码文件大小,一直没有太大的变化。C语言文件的平均大小保持在260行到295行之间,而C++的文件大小则是在140到196行之间。但有一个例外则是Shell语言的文件尺寸,这个尺寸从Debian 2.0到Debian 4.0翻了三倍。个中原由应该是几乎所有的包都有Shell代码来安装,配置或当作胶水语言使用。Shell代码很少被切成多个文件,如果要增加更多功能的时候,增加的代码则被添加到以前的文件里面。因此,Shell文件变得越来越大。

同时很明显地是,过程性语言通常比面向对象的开发语言的源文件要长。比如,C或YACC较之C++通常要大一些。这是因为类继承和其它一些面向对象语言的特性能够有效帮助减少代码量。

6. 依赖性

大型自由软件也是模块化设计。因为没有商用软件的诸多限制,软件复用在自由软件社区里是非常容易的。Debian的各个包之间通常有着非常复杂的依赖关系。

统计数据显示,在Debian 2.0时,有最多依赖项的是phython-gdk-imlib,共19个依赖项。到了Debian 4.0发布时,kde有多达561个依赖项,紧排其后的是gnome,共486个依赖项。

随着新的发行版的发布,包之间的关系变得愈来愈复杂。举例来讲,Mozilla包在Debian 2.1时只有7个依赖项,而到了4.0时则有72个依赖项。PostgreSql在2.0时仅有9个依赖项,到了4.0时则有42个依赖项。

从另一个角度看依赖性有项图。每一个结点表示一个包,有多少有向边指向该结点则表示这个包被多少其它的包依赖,我们把这些依赖它的包称为下属(Subordinate)。则一个包愈重要,则它的下属愈多。对于大多数包,它们的下属数目为零。而只有少数包拥有大量的下属。总体来看,包的平均下属数目随着整个软件系统包总数的增多而不断快速增多。比如,在Debian 2.0时,perl有118个下属,而到了Debian 4.0这个数量增长到11459。毫不奇怪,有最多下属的包是一些运行库,如libc,脚本语言解析器,如perl,传统Unix工具,如binutils和sed,awk。在某种程度上,一个包拥有越来多的下属数目则表示它的开发越成功。

对论文的个人评价和理解:

因为个人兴趣爱好,我对Unix/Linux相关的技术比较感兴趣,并有多年使用Debian OS的经验。因此我选择了这篇以Debian为研究对象的论文。全篇论文没有很难理解的地方,只是统计了Debian发展过程中的各种指标,把统计数据列出来再概括一个趋势。我想,这其间最困难的地方应该是编写分析Debian发行版配置文件的自动化程序。

另外我觉得这篇文章概括出来的一些大型软件系统的特点仅适用于自由软件。而商业软件在很多特性上很可能同自由软件相差甚远。比如,自由软件重代码轻文档,因些有这样的说法“代码即文档”。很多自由软件的项目代码编写优先入文档编写,文档通常相当程度落后于实际的开发进度。而商业大型软件则基本上是先确定文档再编写代码。开发方式的大相径庭使得该论文的结论不适用于大型商业软件。

另一个注意到的地方是关于流行开发语言的统计数据。虽然该篇论文发表于2008年,已是4年之前,Sun还没被Oracle收购,OpenJava还未加入Debian。但即便是4年之前,在整个软件开发工业里,Java已然是占有份额最多的开发语言,C语言紧随其后。该篇论文的数据则显示在Debian 4.0版本中,C语言占51%的份额,Java仅占3%的市场份额。虽然论文中有指出因为没有统计私有许可证的Sun SDK和Sun JRE的Java代码量。Java和C的占用率仍然是相差甚远,都不在一个数量级之上。我个人的理解主要有两点原因。其一,Debian搭建的是一个桌面生态环境,Java主要用到Web开发移动开发企业开发,开发桌面应用还是不多。其二,开源社区排斥由商业公司控制的开发语言,如果要开发效率,社区宁可选择选择自由许可证的Python。

从论文中提供的数据看来,Debian的规模是每两年增加一倍,如此迅速的演化速度,以前的组织方式必然需要提出创新和改变。我觉得论文不足的地方是对大型自由软件的未来发展趋势以及技术创新涉及甚少,没有一个前瞻性的预判。

copyright ykyi.net

怎么为Linux源代码生成补丁

怎么为Linux源代码生成补丁

 

用diff命令来为linux源代码生成补丁。如:

$ diff -Nur /path/to/original/kernel /path/to/your/kernel > change.patch

注意原始的源代码在前,更改后的源代码在后。2.6.x内核的补丁包提交约定指出你需要在每个patch后面写上这样一行:

Sined-off-by: name <email>

这样注明这个补丁包由你制作并贡献给社区。

 

参看 Documentation/SubmittingPatches可以知道更多关于提交linux源代码补丁的内容 。

参看 Documentation/applying-patches.txt 可以知道更多如果打补丁包。

copyright ykyi.net