2011年9月20日星期二
2008年5月6日星期二
工具链技术说明(摘自Linux From Scratch - 版本 6.1.1 Chapter 5. 构建临时编译环境 )
5.2. 工具链技术说明
本节阐述了整个构建方法的一些基本原理和技术细节,您不必马上就理解本节中的所有内容。在您实际操作之后,就会了解大多数的东西,您可以在任何时候回顾本节。
Chapter 5 的总体目标是提供一个临时环境,您可以 chroot 到这个环境,在里面构建一个 Chapter 6 中的干净、没有问题的目标 LFS 系统。为了尽量的与宿主系统分开,我们创建了一个自包含、自依赖的工具链。要注意的是,这个创建过程被设计为尽量减少新手犯错误的可能,同时尽可能多的提供教育价值。
重要
在继续之前,要先知道工作平台的名称,就是所谓的"target triplet"(目标三元组),许多时候,target triplet 可能是 i686-pc-linux-gnu 。要确定 target triplet 的名称,有一个简单的方法就是运行许多源码包里都有的 config.guess 脚本。解开 Binutils 的源码包,然后运行脚本 ./config.guess 并注意输出的内容。
工作平台的动态连接器名称也需要知道,这里指的是动态加载器(不要与 Binutils 里的标准连接器 ld 混淆了)。动态连接器由 Glibc 提供,用来找到并加载一个程序运行时所需的共享库,在做好程序运行的准备之后,运行这个程序。动态连接器的名称通常是 ld-linux.so.2 ,在不怎么流行的平台上则可能是 ld.so.1 ,而在新的 64 位平台上更可能是别的完全不同的名称。查看宿主系统的 /lib 目录可以确定动态连接器的名称。确定这个名称还有一个必杀技,就是在宿主系统上随便找一个二进制文件,运行 readelf -l <二进制文件名> | grep interpreter 并查看输出的内容。涵盖所有平台的权威参考请查看 Glibc 源码根目录里的 shlib-versions 文件。
Chapter 5 中构建方法是如何工作的一些技术要点:
-
这个过程在原理上与交叉编译类似,通过把工具安装在同一个目录(使用相同的"prefix")中以便协同工作,还利用了一点 GNU 的 "magic"。
-
小心处理标准连接器的库文件搜索路径,确保程序仅连接到指定的库上。
-
小心处理 gcc 的 specs 文件,告诉编译器要使用哪个动态连接器。
首先安装的是 Binutils ,因为 GCC 和 Glibc 的 configure 脚本要在汇编器和联接器上执行各种各样的特性测试,以确定软件的哪些功能要启用,哪些功能要禁用。这样做比你想像的还要重要,配置不正确的 GCC 或者 Glibc 会导致工具链出现微妙的错误,这样的错误造成的影响可能直到整个系统快要编译完成的时候才显现出来。测试程序通常会在其它的许多工作进行之前给出错误警告(以避免其后的无效劳动)。
Binutils 的汇编器和连接器安装在两个位置:/tools/bin 和 /tools/$TARGET_TRIPLET/bin ,一个位置的程序是另外一个位置的硬链接。连接器的一个重要方面是它的库搜索顺序,将 --verbose 选项传递给 ld 可以获得详细的信息。例如,输入命令:ld --verbose | grep SEARCH 将显示当前搜索路径和顺序。要显示 ld 连接的是哪些文件,可以编译一个伪(dummy)程序并把 --verbose 选项传递给连接器。举个例子,输入 gcc dummy.c -Wl,--verbose 2>&1 | grep succeeded 将显示所有连接成功的文件。
第二个安装的软件包是 GCC 。下面是运行 configure 脚本时,输出内容的一个示例:
checking what assembler to use...
/tools/i686-pc-linux-gnu/bin/as
checking what linker to use... /tools/i686-pc-linux-gnu/bin/ld
基于上面提到过的原因,这是重要的步骤,它同时证明了 GCC 的配置脚本并不是搜索 PATH 里的目录来寻找要使用哪个工具的,而且,在 gcc 的实际操作中,相同的搜索路径不一定会被使用。要知道 gcc 会使用哪个标准连接器,请运行命令:gcc -print-prog-name=ld 。
在编译一个伪程序的时候,给 gcc 命令传递 -v 选项可以获得详细的信息。举个例子:gcc -v dummy.c 将显示在预处理、编译和汇编各个阶段的详细信息,包括 gcc 文件包含的搜索路径及其顺序。
接下来安装的软件包是 Glibc 。编译 Glibc 的时候,最需要注意的地方是编译器、二进制工具(Binutils)和内核头文件。编译器一般不是问题,因为 Glibc 总是使用在 PATH 目录里找到的 gcc 二进制工具和内核头文件则有点复杂。因此,为慎重起见,明确使用配置开关(选项)来强制进行正确的选择。在运行 configure 之后,请检查 config.make 文件的内容(位于 glibc-build 目录下),查看所有重要的细节。注意,CC="gcc -B/tools/bin/"的作用是控制要使用哪个二进制工具;而 -nostdinc 和 -isystem 选项则是控制编译器的文件包含搜索路径。这些选项表明了 Glibc 软件包的一个重要特征:根据其编译方法,它是非常自给自足的,而且一般不依赖于工具链的默认值。
装完 Glibc 之后,需要做一些调整使得只在 /tools 目录里搜索和连接。安装一个调整好的 ld ,它的固化搜索路径限制在 /tools/lib 目录。然后修改 gcc 的 specs 文件以指向 /tools/lib 目录里新的动态连接器。最后这一步在整个过程中至关重要,像上面提到的,指向动态连接器的固化路径被嵌入到每个 ELF 可执行文件里。运行命令来检查:readelf -l <二进制文件名> | grep interpreter 。修改 gcc 的 specs 文件以确保本章后面编译的每一个程序都使用位于 /tools/lib 目录里新的动态连接器。
需要使用新动态连接器也是第二遍编译 GCC 需要打 Specs 补丁的原因。不这样做的结果是 GCC 会把宿主系统 /lib 目录下动态连接器的名字嵌入进来,这样有悖于与宿主系统隔离的目标。
第二遍编译 Binutils 的过程中,我们利用 --with-lib-path 选项来控制 ld 的库搜索路径。如前面所指出的,核心工具链是自包含和自依赖的,所以 Chapter 5 余下的软件包的编译将依赖于 /tools 下新的 Glibc 。
在 Chapter 6 中进入 chroot 环境后,第一个安装的主要软件包就是 Glibc ,原因是上面所提到的 Glibc 自给自足的特性。一旦 Glibc 安装到 /usr 目录后,马上改变工具链的默认值,然后构建目标 LFS 系统的其它部分。
2008年4月29日星期二
GNU Toolchain的构建
GNU Toolchain的构建
| 作者: | A.TNG |
|---|---|
| 邮箱: | tang.jiyu at gmail dot com |
| 时间: | 4/29/2008 |
| 参考: | http://www.gnu.org |
My Story
先介绍一下我的Story:两台PC,分别安装了CentOS 4.5,安装的 过程中都选择不安装任何开发工具,PC-1启动NFS服务,共享 Dir-1,并在其中安装GNU Toolchain;PC-2挂载Dir-1,设置 好对应环境变量,即可使用GNU Toolchain进行开发;往后, 有新的PC-3, PC-4等到来时,直接挂载Dir-1,设置好环境变量 即可使用GNU Toolchain进行开发。
准备工作
如同鸡生蛋、蛋孵鸡,我们若想自己构建整套GNU Toolchain, 必须有可以正常工作的GNU Toolchain。 在PC-1上,我们需要安装 下列软件包,来得到一个基础的编译环境:
cpp-4.1.1-52.el5.i386.rpm
glibc-headers-2.5-12.i386.rpm
glibc-devel-2.5-12.i386.rpm
libgomp-4.1.1-52.el5.i386.rpm
gcc-4.1.1-52.el5.i386.rpm
libstdc++-devel-4.1.1-52.el5.i386.rpm
gcc-c++-4.1.1-52.el5.i386.rpm
zlib-devel-1.2.3-3.i386.rpm
还有一些额外的软件包需要安装,编译完毕GCC时,进行测试时 会用到。
expect-5.43.0-5.1.i386.rpm
dejagnu-1.4.4-5.1.noarch.rpm
至此,PC-1已经是一台具备了基本开发环境的机器,可以作为 构建GNU Toolchain的火种了。
GNU Toolchain的族谱
构建GNU Toolchain之初,我简单的认为GCC能解决所有的问题, 有了GCC,我就可以开始开发之旅了。随着对GCC了解的深入, 我才发现了GCC身后庞大的家族,包括:
- GNU Make:编译和构建程序的自动化工具,Linux中常用 到的make命令。
- GNU Compiler Collection (GCC):一组编译器,支持多种 语言,包括:C, C++, Java, Objective-C, fortran。
- GNU Binutils:一组二进制工具,在编译完成后,链接 并生成二进制的工具。包括:ld, as等。
- GNU Lib C:标准的C库,软件开发的必需品。
- GNU Debugger (GDB):代码调试工具。
- GNU Build System (Autotools):一组自动化工具,在编译 的时候经常能用到,包括:autoconf、automake和libtool。
- GNU M4:宏预处理器,是最高级的文本宏处理系统之一。
编译和构建
上节提到的每种工具都需要下载源代码,并进行安装。曾经希望有 一些捷径,例如使用RPM包等,但是为了到达完全定制的效果,最终 只能选择下载源代码包,手动编译安装。
- 各工具的编译和安装大同小异,在PC-1上,configure/make/make install 三步曲,其中GCC的编译和安装最为复杂,耗时最长,具体可以参考 之前的文章 《Linux上编译和安装GCC》 。
- 在configure的时候,一定要设置 prefix 参数,都指定到 Dir-1目录下,特别是在编译glibc等库的时候,一旦make install 完成,就不要将安装好的库文件移动到其他路径了,不然会造成很多 关于路径的问题。
GNU Toolchain的配置和验证
配置
都安装好以后,并不能直接使用,配置也是个很重要的问题。首先, 介绍有用的命令,能帮助检查咱们的GNU Toolchain是不是在正常的 工作。
- gcc的-v参数。gcc命令有一个很有用的参数, -v ,他表示在 gcc编译源代码的过程中,动态输出相关的信息。信息中,不仅仅 包含源代码的error/warning,同时还包含gcc是在哪些路径下搜索 头文件,在哪里路径下链接哪些库文件。
- ldd。这是binutils下的一个工具,用来查看当前可执行文件中 用到了哪些共享库。
- readelf。这也是binutils下的工具,对二进制文件进行分析,可以 输出很多有用信息。
需要修改gcc的specs文件,specs文件是指示gcc如何工作的一个配置文件。 默认情况下,gcc的安装目录下是不包括specs的,gcc在编译的时候使用 其内建的specs文件,当有特殊需求时,例如,在当前情况下,我需要gcc 默认链接我自己编译的glibc库,因此需要对specs进行修改。
- 首先使用gcc的 -dumpspecs 参数来输出specs,并保存至 /Dir-1/gcc-4.2.3/lib/gcc/i686-pc-linux-gnu/4.2.3/specs
- 找到/lib/ld-linux.so.2,修改成/Dir-1/glibc-2.3.4/lib/ld-linux.so.2
需要设置的环境变量包括:
- C_INCLUDE_PATH=/Dir-1/glibc-2.3.4/include
- CPLUS_INCLUDE_PATH=/Dir-1/glibc-2.3.4/include
- LIBRARY_PATH=/Dir-1/glibc-2.3.4/lib
- LD_LIBRARY_PATH=/Dir-1/gcc-4.2.3/lib
这样才可以在编译的时候找到需要的头文件和库。同时,别忘了把 安装好的软件的bin目录设置到环境变量PATH中。
验证
可以编写一个超级简单的输出hello world的小程序。
C语言版:
#include
int main() {
printf("hello world.\n");
return 0;
}
保存为hello.c,用下列命令编译:
gcc hello.c -o hello -v
通过分析gcc的输出,查看gcc所搜索头文件的路径是否是你设置的环境 变量的路径;查看gcc链接的路径是否是你环境变量设置的路径,以及gcc 链接使用的库,都是你之前编译好的那些,如果使用到了系统的一些动态库, 你就要小心了,应该是什么地方设置出现错误了。
使用下列命令,查看动态链接库的路径是否正确:
ldd hello
输出:
libc.so.6 => /Dir-1/glibc-2.3.4/lib/libc.so.6 (0x00356000)
/Dir-1/glibc-2.3.4/lib/ld-linux.so.2 (0x00e79000)
表示链接到之前编译的glibc中。
对于C++,也可以使用类似的方法进行验证。
2008年4月27日星期日
Linux上编译和安装GCC
Linux上编译和安装GCC
| 作者: | A.TNG |
|---|---|
| 邮箱: | jiyucn@163.com |
| 参考: | Installation document of GCC |
| 时间: | 4/13/2008 |
前言
最近在构建一套开发环境,对GCC有特殊的要求,使用RPM包安装 的GCC已经不能满足要求了,因此决定手动编译安装GCC。
原本想走一些捷径,希望RPM包安装也可以达到手动安装的灵活性, 后来发现此路不通;接下来又想找网络上是否提供编译好的tar包下 载,解压后就可直接运行,后来发现GCC平台依赖性很强,此路亦 不通。
于是只能选择源代码编译和安装GCC了。
第一步:准备工作
我是从一台最小化安装CentOS 5的Linux PC上开始安装GCC的, 其实如果你有一台安装了开发环境的Linux PC,则可以跳过这一 步。
首先,机器上必须安装好GCC,才能够从源代码编译和安装新的GCC, 因此我安装了下列RPM包作为开发环境。(注意,我的系统是 CentOS 5,其他平台可以选择相关的开发工具包)。
- rpm -ivh cpp-4.1.1-52.el5.i386.rpm
- rpm -ivh glibc-headers-2.5-12.i386.rpm
- rpm -ivh glibc-devel-2.5-12.i386.rpm
- rpm -ivh libgomp-4.1.1-52.el5.i386.rpm
- rpm -ivh gcc-4.1.1-52.el5.i386.rpm
- rpm -ivh libstdc++-devel-4.1.1-52.el5.i386.rpm
- rpm -ivh gcc-c++-4.1.1-52.el5.i386.rpm
- rpm -ivh zlib-devel-1.2.3-3.i386.rpm
安装完以上的工具包后,系统中gcc/g++命令就可用了。
GCC的tar包里面提供了test suite,编译完成后可以执行这些测试, 用以分析编译是否成功。因此系统中需要安装另外的工具包:
- rpm -ivh expect-5.43.0-5.1.i386.rpm
- rpm -ivh dejagnu-1.4.4-5.1.noarch.rpm
安装完以上工具包后,系统中runtest命令就可以用了。
第二步:configure和make
configure
configure是个很关键的步骤,如果遇到编译错误,首先应该想到 可能是configure的问题,接下来想到可能是系统中缺少相关的软 件包,编译过程中找不到头文件等。
我使用的编译参数是:
./configure --prefix=/opt/gcc-x.y.z --enable-shared \
--enable-threads=posix --enable-clocale=gnu \
--enable-__cxa_atexit --disable-checking \
--enable--long-long
依次解释:
- --prefix=/opt/gcc-x.y.z 是用来指定安装目录,注意,该目录尽量不要与源代码是同一目录, 也不能是源代码的子目录。
- --enable-shared 创建共享库
- --enable-threads=posix 启用线程支持,在某些平台上是默认值。它对Obj-C的库以及C++、 Java的异常处理有影响。
- --enable-clocale=gnu 本参数确保C++库在任何情况下都使用正确的locale 模块。如果配置脚本查找到de_DE这个locale,它就会 使用正确的gnu模块。然而,有的人没有安装de_DE,就有可能创建 出ABI不兼容的C++库文件,这是因为错误的使用了generic作为 locale模块。
- --enable-__cxa_atexit 使用 __cxa_atexit来代替 atexit,用来记录本地和全局的 C++ destructors,这是为了完全符合标准的规定。它还会影响到C++ ABI, 因此生成的C++共享库,在其他的Linux发行版上也能使用。
- --disable-checking 为节省编译时间,我们使用此选项,对结果没有影响。
- --enable--long-long 支持long long数据类型,某些开源项目使用了该数据类型。
完成configure工作后,会自动生成Makefile,接下来就可以开始漫长 的编译工作了。
如果configure的参数把你绕得很晕, 传递尽量少的参数给configure,默认 的参数在大多数情况下是适用的。
第三步:执行测试(可选)
GCC的tar包里面提供了test suite,帮助进行测试,用来分析编译是否 成功。
执行如下命令开始测试:
make -k check > check.log
同样,这是个漫长的过程。
测试完成后,可以访问 http://gcc.gnu.org/buildstat.html ,对比测试结果。
Windows下FFmpeg快速入门
Windows下FFmpeg快速入门
| 作者: | A.TNG |
|---|---|
| 邮箱: | jiyucn@163.com |
| 参考: | http://www.ffmpeg.com.cn/ |
FFmpeg简介
FFmpeg是什么?
FFmpeg是用于录制、转换和流化音频和视频的完整解决方案, 包括 libavcodec ,一套领先的音/视频编解码类库。FFmpeg 在Linux上开发,当可以在大多数操作系统下编译,包括Windows。
Note
- FFmpeg对GCC的依赖很强,所以就算是在Windows上, 用VC编译FFmpeg也不是一件轻松的事情。请尽量使用 GCC来编译FFmpeg,比较事半功倍。
FFmpeg的官方网址是 http://ffmpeg.mplayerhq.hu/。
中文Wiki是 http://www.ffmpeg.com.cn/ ,资料很多。
FFmpeg的组成结构
FFmpeg主要由一下几个部分组成:
libavcodec: 一个包含了所有FFmpeg音视频编解码器的库。 为了保证最优性能和高可复用性,大多数编解码器从头开发的。
libavformat: 一个包含了所有的普通音视格式的解析器和 产生器的库。
- 三个实例程序,这三个实例较为复杂,基本可以作为API使用手册:
- ffmpeg:命令行的视频格式转换程序。
- ffplay:视频播放程序。(需要SDL支持)
- ffserver:多媒体服务器
了解完组成结构后,你会发现,如果你在寻找一种视频格式转换 的方式,那FFmpeg绝对是你的第一选择, libavcodec 则又是重 中之重。如果遇上API不会使用的情况,可以参考ffmpeg.c、ffplay.c、 ffserver.c、apiexample.c(解码)和output_example.c(编码)。
FFmpeg的编译
要使用FFmpeg,第一步就是编译,对于Linux上的用户,可以参考 http://www.ffmpeg.com.cn/index.php/Ffmpeg%E7%BC%96%E8%AF%91%E8%AF%A6%E8%A7%A3
对于Windows用户,可以参考 http://bbs.chinavideo.org/viewthread.php?tid=1897&extra=page%3D1
Note
- 编译FFmpeg是一个复杂的过程,如果你想加快速度,领略FFmpeg 的风采,则可以跳过这一步,直接进入下一章节。
FFmpeg的SDK
FFmpeg是一个复杂的工程,第一步编译,特别是Windows下的编译 过程,更是复杂。 因此,好心的网友提供了Windows下编译好的 dll和lib库文件,以及相关的头文件。新手们则可直接下载,并开始编写 FFmpeg库的程序了。
- SDK下载和编译参数可以参考 http://www.ffmpeg.com.cn/index.php/SDK_Download 。
- SDK入门宝典可以从 http://www.bairuitech.com/html/ruanjianxiazai/20070713/49.html 下载。
以上两者已经足以完成FFmpeg的入门,最新的SDK版本是3.0, 对应于FFmpeg的版本是 r10087。新手们可以从编译源代码库中的 output_example.c开始,同时参考 SDK入门宝典 。
编译output_example.c的时候需要注意以下问题:
- VC的是不支持C语言中的inline,所以可以把相关的inline删除。
- 对于snprintf的支持,可以考虑从 http://www.ijs.si/software/snprintf/ 下载 snprintf.h和snprintf.c放入工程中。
准备了一个 output_example.c 的VC (2008 express edtion)工程,有兴趣的朋友 可以邮件至 tang.jiyu at gmail dot com 索取。
J2ME开发中的构建管理 (Build Management in J2ME)
J2ME开发中的构建管理 (Build Management in J2ME)
| 作者: | A.TNG |
|---|---|
| 邮箱: | jiyucn@163.com |
| 时间: | 4/26/2008 |
在一个J2ME项目中干了半年的CM (Configuration Management)/BM (Build Management),学习到了很多普通开发人员较少机会接触, 但是对项目本身又十分重要的知识,写出来与大家分享。
前言
手机应用软件的开发越来越流行,其中又以J2ME开发为甚。放眼当前 各品牌手机,大多数都支持J2ME,而Java中的“一次编写,到处运行” 的概念也极大的吸引了开发者。但是,手机开发平台与PC比仍然有很大 的差距,J2ME的开放性也造成了各个手机J2ME程序的不兼容性,各大 厂商都极力的推自己的特性开发包,而不注重与其他手机兼容。因此, 我们在开发J2ME程序的时候,不但要注意程序本身的开发,更要注意 为不同品牌、型号的手机进行特定构建,特别是开发人员人数在10-20的 开发团队中。
1. 关于JDK/WTK的选择
JDK属于基础设施,选择的版本越新越好。通常,高版本的JDK可以设置 按照低版本的语法进行编译,可以指定生成低版本的class文件格式。
WTK也是同样的道理,高版本的通常具有较好的兼容性,这里给一个提示, 如果你需要将你的程序再多种品牌的手机上运行,你可以同时安装特定手机 品牌放出的J2ME WTK,通过在这类特定的WTK上进行测试,可以较早于真 机发现问题。在J2ME的开发过程中,JSR包的选择十分重要,当使用某些 特定JSR时,一定要调研清楚,所需要支持的手机中是否都支持该JSR包。
2. 编译脚本的编写
如同开发C/C++程序一样编译的时候需要写Makefile,开发J2ME程序的 时候也需要有类似的脚本来完成整个编译和构建的过程,这里面有一些 选择,简单的构建过程,Windows平台上可以考虑编写bat脚本,基本 能够满足需求。对于较为负责的构建过程,推荐选择Ant。Ant是一个 用于简单或复杂Java工程的自动化构建、部署工具,它对于那些具有 分布式开发团队或者相信通过频繁的构建来进行不间断集成的公司尤 其有用。在J2ME开发上,同样可用。同时Ant有丰富的插件,帮助完成 Ant本身无法完成的功能,对于特定的需求,构建管理者可以自己编写 插件,集成到Ant中。
用Ant来构建应用通常是编写一个build.xml文件,将该文件传给Ant, Ant根据build.xml文件中的指示进行编译和构建,在使用Eclipse+EclipseMe 开发J2ME应用时,可以从Eclipse导出build.xml,不过还是推荐大家 自己编写build.xml文件。编写build.xml时,也建议进行良好的设计, 越是复杂的构建过程,对build.xml要求也越高。
3. Antenna
Antenna是Ant的扩展包,它是专用来构建、编译、打包、部署J2ME 应用的辅助工具。
Antenna中非常实用的工具就是WtkPreprocess,它给Java开发添加 了类似C/C++中的宏定义和代码预处理的功能。Antenna支持的宏定义 包括:
- #ifdef
- #ifndef
- #elifdef
- #elifndef
- #if
- #elif
- #else
- #endif
- #condition
- #debug
- #mdebug
- #enddebug
- #define
- #undefine
- #expand
可以从 http://antenna.sourceforge.net/wtkpreprocess.php 获得 详细的说明。
使用Antenna的过程中,会有一些缺陷。例如,在开发过程中,我们 通过定义宏来代表某个功能,对于不同的手机,当我们需要支持 该功能时,在编译的过程中,打开这个宏即可,反之则关闭这个宏。 如果该功能只与代码有关系,情况就十分简单,Antenna的WtkPreprocess 可以完成我们需要的功能。但是如果该功能同时与资源有关系,当 我们选择不支持该功能时,我们不但想在编译的过程中,通过预处理, 去掉相关的代码,也希望该功能相关的资源也不被放入JAR包中, 而WtkPreprocess除了处理源代码,其他都无能为力。因此在构建脚本 的编写过程中,需要特别注意这类问题。
4. Proguard
ProGuard是一款免费的Java类文件压缩器、优化器和混淆器。 它能发现并删除无用类、字段(field)、方法和属性值(attribute)。 它也能优化字节码并删除无用的指令。最后,它使用简单无意义的 名字来重命名你的类名、字段名和方法名。经过以上操作的jar文件 会变得更小,并很难进行逆向工程。
在J2ME开发中,通常都会使用到该工具,并且该工具是开源的, 很容易获取。
5. Preverify
Preverify是WTK带的一个验证class文件的工具,通过了Preverify的 class文件,在手机上运行前仅需要做一些二次验证的工作。
6. Size Control
编写J2ME程序的时候,JAR包的大小是个大问题,手机上的存储空间 和程序运行空间都十分珍贵,因此我们需要尽最大的能力减小 JAR包 的大小。
6.1 kjar/kzip
在制作JAR包时,有很多方法。JDK本身提供了jar命令,可以制作JAR包, JAR包其实可以理解为标准的ZIP包。
此处,我们推荐使用一个称为kjar的工具,可以从 http://supremej2me.bambalam.se/guides/optimization-tools/kjar/ 下载到,他是通过改写压缩算法,使制作的JAR包能比普通JAR包减小10% 左右的大小。同时,由于kjar只能运行于Windows平台,并且通常被病毒 防火墙误认为病毒,用起来并不方便,因此你可以从 http://advsys.net/ken/utils.htm 下载kzip,包括Windows和Linux版本,能实现同样的功能。
6.2 BamFS
BamFS是另一个减少JAR包大小的工具,可以从 http://supremej2me.bambalam.se/guides/optimization-tools/bamfs/ 下载。该工具可以将所有资源文件,包括图片、文本等,打成一个大 的二进制文件,并且提供了一个java类,方便开发人员从这个大的二 进制文件中读取所有资源。通过减少JAR包中文件的数目(或者文件夹 的层次),同样也可以减少JAR包的大小。
6.3 mbooster
mbooster是一个很强的工具,但同时,也是个收费的工具,开发者 可以向该公司申请trial的license,网址是 http://www.innaworks.com/mBooster.html , mbooster可以减小JAR包的大小,同时也能提高程序的运行速度, 它可以优化class文件,PNG文件,普通情况小可以减小30-40%左右的 大小。
7. 自动构建工具
选择一个自动构建的工具,会极大的减少构建管理者的工作量, 在这里推荐 CruiseControl ,该工具被广泛的用于Java项目和 极限开发之中。CruiseControl内建支持各类的版本管理工具, 支持Ant、Maven等多种构建工具,支持定时构建,支持多种发布 方式。
构建管理者所需要做的事情就是,将自己制作的构建环境放入 CruiseControl之中,对其进行适当的配置,接下来的事情就十分 简单了,每次需要构建时,只需要登陆到CruiseControl提供的 Web界面,鼠标点击某链接来trigger构建,后台会自动完成构建、 发布,并发邮件通知相关人员,一旦编译出错,也会以邮件的 方式通知大家。
8. 需要遵守的一些原则
- 整个Build Environment需要有良好的结构,可以参考一些开源 项目的结构。为目标构建人员(例如开发人员、测试人员等) 提供简单的接口,即通过简单的设置,就能构建出想要得东西。 对于提供的接口,一定要有详细的文档描述。
- 要求开发人员尽量使用标准的构建环境进行构建。J2ME的开发, 通常都会在Eclipse/NetBeans里面完成,但一定要求开发人员 在提交代码到版本控制系统中之前,至少需要使用标准构建环境 构建一次JAR包,并验证。这样可以帮助尽早发现问题,因为IDE 与自订制的构建环境总是存在差别的。
- 建议将所有用到的第三方库/代码/程序都放入Build Environment中, 而整个Build Environment是应该放入版本控制系统中的。对于 JDK/WTK/Ant等基础设施工具,可以要求开发人员自己安装,并 设置好环境变量。可以编写适当的脚本,对环境以及版本进行判断。 每次构建之前,先判断,若不满足,则不予构建。

