BuildSystem
1、组成
MagicInstaller 选用 scons 而不是 autoconf + automake + libtools + make
是因为 scons 能够比较容易、清晰而准确地控制依赖关系。目前 scons 对文件安装的
支持还很不够,所以在 MagcInstaller 的 BuildSystem 增加了一些函数以进行弥补。
由于本人对 scons 的了解尚不深入,这些必要的弥补还不够完善。
BuildSystem 能够使创建过程尽可能地自动化,从而提高创建效率、减少手工操作
引入错误的机会。这是引入 BuildSystem 的主要理由。在比较复杂的项目中,
BuildSystem 是必不可少的。
MagicInstaller 的 BuildSystem 由 MagicInstaller/SConstruct、所有子目录中的
SConscript、MagicInstaller 和 MagicInstaller/scripts 目录中的 .py 脚本组成。
MagicInstaller/scripts 目录是专门用来保存 BuildSystem 需要的脚本的。其中:
- MagicInstaller/SConstruct:此脚本是 scons 的主创建文件。
- MagicInstaller/mkmbsys.py:此脚本用于组建 MagicBooter 所运行的文件系统。
虽然 MagicBooter 的运行环境只含有一个可执行文件,但它的运行还需要一些设备文件
和目录以便加载文件系统。详情请参见这里。
- MagicInstaller/mkstep1.py:此脚本用于将运行环境中从 RPM 包中选出的文件安装
到 MagicInstaller/tmp/root.step1 中(为处理方便还要做成
MagicInstaller/bindir/root.step1.tar.gz)。详情请参见
这里。
- MagicInstaller/mkstep2.py:此脚本用于将
MagicInstaller/bindir/root.step1.tar.gz 和 MagicInstaller/bindir/root.src.tar.gz 组合
成最终的运行环境,并保存在 MagicInstaller/tmp/root.initrd (还要做成
MagicInstaller/tmp/root.initrd.tar.gz) 中。详情请参见
这里。
- MagicInstaller/scripts/CreateISO.py:此脚本根据
MagicInstaller/result/pkginfor.py 和命令行参数,为发行者生成 .iso 文件。
- MagicInstaller/scripts/PkgArrange.py:此脚本读取
MagicInstaller/tmp/pkginfor.py、MagicInstaller/scripts/pkgpubic.py 和由发行者
编辑的 MagicInstaller/pkgarrangement.py,生成 MagicInstaller/result/pkgarr.py。
详情请参见这里。
- MagicInstaller/scripts/pkgpublic.py:此脚本给出一些用于多个包处理脚本的
公共数据,以便于调整和修改。
- MagicInstaller/scripts/RpmPkgInfor.py:此脚本读取发行者指定目录中的 rpm
包,从中收集必要的信息 (包括包的大小和依赖关系),并将标准化后的结果存入
MagicInstaller/tmp/pkginfor.py。详情请参见这里。
- MagicInstaller/scripts/xmlgettext.py:此脚本是 xmlgtk 的一部分,用于从
描述界面的 xml 文件中抽取需要进行国际化本地化的字符串,转换成
MagicInstaller/src/magic.installer/po/xmltranslation.py。而后即可用 xgettext
转化为标准的 pot 文件进行处理。详情请参见这里。
各目录中的 SConscript 在相应的页面中根据情况进行介绍。
2、MagicInstaller 源代码目录结构
- Build:保存编译 busybox 和 linux 时使用的配置文件。
- MagicBooter:保存 MagicBooter 的源代码和 MagicBooter 需要的其它软件包(busybox-0.60.5 和 mxml-1.0)。
- bindir:保存用于生成主运行环境的 rpm 包,编译好的内核。
- themes:保存安装程序支持的场景。其中的 themes.xml 用于说明场景。
- cdadd:保存需要直接复制到发行版 CD 中的文件。
- docs:保存文档。
- design:保存设计和实现的说明文档。
- tech:保存有关某些技术细节的文档。
- examples:保存作为范例的 rpm 包列表和 pkgarrangement.py。
- mbtest:此目录是临时目录,不归 CVS 管理。它用于保存测试版 MagicBooter 的
可执行文件(此测试版可以在普通 linux 环境中运行,以便于测试)。
- pystep1:保存为组建主运行环境而从 rpm 包中选取文件所用的 python 脚本。
- realmbtest:此目录是临时目录,不归 CVS 管理。它用于保存测试版 MagicBooter
的可执行文件(此测试版需重新启动以进行测试,在运行过程中将输出较多的调试信息)。
- result:保存创建结果。包括所有 .iso 文件、initrd.gz、mbboot、miinitrd、
miinitrd.cramfs、pkgarr.py、vmlinuz。
- scripts:保存所有 BuildSystem 需要的脚本。
- src:保存安装程序主体源代码。
- etc:保存将要安装到主运行环境的 /etc 目录下的文件。
- fonts:保存将要安装到主运行环境的 /etc/fonts 目录下的文件。
- gtk-2.0:保存将要安装到主运行环境的 /etc/gtk-2.0 目录下的文件。
- init.d:保存将要安装到主运行环境的 /etc/init.d 目录下的文件。
- python:保存将要安装到主运行环境的 /etc/python 目录下的文件。
- sysconfig:保存将要安装到主运行环境的 /etc/sysconfgi 目录下的文件。
- X11:保存将要安装到主运行环境的 /etc/X11 目录下的文件。
- magic.installer:安装程序主体核心代码。
- helptext:保存求助文本。
- images:保存安装程序需要使用的图片(全部使用 png 格式)。
- modules:保存安装程序各个步骤界面的处理代码。
- fdisk:此处原为自行实现的分区代码,后改用 GNU Parted,故废弃不用。
- operations:保存安装程序各个步骤后台操作的处理代码。
- po:国际化、本地化安装程序。包括生成 xmltranslation.py、
magic.installer.pot。
- tests:对 xmlgtk 的测试代码。
- UIxml:保存说明安装程序各个界面的 xml 文件。
- pyext:此目录没有内容,它的所有子目录都是安装程序需要,而 python 无法实现
必须用 C 实现的功能
- extioctl:此目录本意是提供一些必要的 ioctl,但后来又不需要了。
- iconv:由于 python2.2 处理中文的能力不足,增加此模块加以弥补。
- isys:从 anaconda 中的 isys 中选取的部分需要的代码。
- lowlevel:本打算用来实现 makedev、mknode,但后来又不需要了。
- miactions:实现安装程序界面、短操作进程、长操作进程之间的通讯控制。其中
t-miactions.py 和 t-mia.py 用于测试 miactions。
- parted:此代码来自 parted-1.6.3。由于有些版本的 GNU Parted 不含有 python
接口,所以在此处给出。
- tests:一些对 GNU Parted 的 python 的测试脚本。
- tftpc:python 的 tftp client 接口。
- tmp:保存发行版映象创建的中间结果。
- bootcd:需存入第一张发行光盘的目录和文件保存于此。
- cd-%d:需存入第 %d 张发行光盘的目录和文件保存于此。
- devroot:安装程序需要的,自行编译的库将安装于此,以便于安装程序的其它部分
引用和连接。
- MagicInstaller-%date:为第一张发行光盘准备 MagicInstaller 源代码时,将
从 cvs 中 check 的代码存入此目录。
- mbboot.mnt:制作 mbboot 时,将 mbboot 加载于此。
- mbroot.initrd:制作 mbboot 时,将 mbroot.src 的内容复制至此,再由
mkmbsys.py 制作成完成的运行文件系统。
- mbroot.src:制作 mbboot 时,将 MagicBooter 安装于此。
- miinitrd.mnt:制作 miinitrd 时,将 miinitrd 加载于此。
- root.initrd:制作 minitrd.cramfs 时,将 root.step1、root.src 复制至此,再由
mkstep2.py 制作完成的运行文件系统。调试时,可以 chroot 进入此目录。
- root.src:安装程序主体将安装至此。
- root.step0:用于组建主运行环境的 rpm 包或 tar 包,将首先展开至此。
- root.step1:主运行环境组建于此。
3、创建参数和创建目标
3.1、scons 参数
BuildSystem 的使用者,是 MagicInstaller 的开发者和 MagicLinux 的发行者。在
本文以后的部分以“使用者”表示开发者和发行者。
为了简化使用者获得目标文件的工作,BuildSystem 允许使用者提供参数以控制
BuildSystem 的行为。在 MagicInstaller 中,可以运行 scons -h 以获得关于创建参数
的求助信息。目前支持的创建参数有:
- distname:默认值为 MagicLinux。用于给出发行版名称;
- distver:默认值为 0.0。用于给出发行版的版本;
- pkgtype:默认值为 rpm。用于给出发行版使用的包管理方式,目前 MagicInstaller
仅支持 rpm;
- pkgdirs:默认值为 packages。用于指定发行版所包含软件包所在的目录;
- cvsroot:默认值为空。当 cvsroot 的值不为空的时候,即以此为 cvsroot,从中
checkout MagicInstaller 的源代码,做成 MagicInstaller-日期.tar.bz2 并安装到
发行版的第一张光盘的 .iso 文件中。
除了直接在调用 scons 的时候给出命令行参数以外,使用者还可以通过编辑
MagicInstaller/pkgarrangement.py 这个文件以控制各光盘的容量、软件包在不同光盘
内的分布,并对软件包之间的依赖关系进行微调。详情请参见
这里。
3.2、创建目标
BuildSystem 的默认创建目标是 allisos,也就是创建发行版的所有光盘 .iso 文件。
为了完成此目标,它依赖于一些其它目标。下面给出各个创建目标之间的依赖层次关系
(名称后接(V)的表示虚拟目标):
- allisos(V):创建所有发行版 .iso 文件。
- MagicInstaller/result/miinitrd:含有安装程序主运行环境和安装程序主体映象
cramfs 文件系统的 ext2 文件系统。
- MagicInstaller/result/miinitrd.cramfs:安装程序主运行环境和安装程序主体
映象。
- MagicInstaller/tmp/root.initrd.tar.gz:安装程序主运行环境和安装程序主体
tar 包。
- MagicInstaller/bindir/root.step1.tar.gz:安装程序主运行环境 tar 包。
- MagicInstaller/bindir/root.src.tar.gz:安装程序主体 tar 包。
- MagicInstaller/result/mbboot:MagicBooter 和 MagicBooter 运行环境。
- MagicInstaller/syslinux.cfg。
- MagicInstaller/m4.syslinux.cfg。
- MagicInstaller/result/vmlinuz:MagicInstaller 使用的内核。
- MagicInstaller/bindir/mb-vmlinuz-2.4.19。
- MagicInstaller/result/initrd.gz:MagicBooter 及 MagicBooter 运行环境。
- MagicInstaller/tmp/mb-initrd:未压缩的 MagicBooter 及 MagicBooter
运行环境。
- MagicInstaller/bindir/mbroot.src.tar.gz:MagicBooter 及 MagicBooter 运行环境
tar 包。
- mbroot_src(V):安装 MagicBooter 和 MagicBooter 运行环境。
- MagicInstaller/result/pkgarr.py:软件包管理信息。此文件是
MagicInstaller/scripts/PkgArrange.py 生成的。
- MagicInstaller/tmp/pkginfor.py:与软件包格式无关的软件包信息。目前
MagicInstaller 仅支持 RPM 格式。因此此文件是由
MagicInstaller/scripts/RpmPkgInfor.py 根据使用者提供的 rpm 包生成的。
- MagicInstaller/packages.list:此文件是需加入发行版的软件包的列表。
由 MagicInstaller/SConstruct 生成。
- MagicInstaller/pkgarrangement.py:由 MagicInstaller 使用者编辑的软件包控制信息。
- MagicInstaller/packages.list:见前。
- MagicInstaller/result/distname-distver.tar.bz2:源代码包。
4、源代码说明
此处只说明比较复杂的几个 SConstruct、SConscript。
4.1、MagicInstaller/SConstruct
此脚本是主创建脚本,除了组成了所有 3.2 节中说明的目标及相互的依赖关系之外,
还完成了以下功能:
- 定义求助信息。(约 28-55 行)
- 获取各 scons 参数的参数值 (用户未给出时使用默认值)。(约 56-76 行)
- 定义最大发行 CD 数量 max_cd_no。当前值为 9。(约 77 行)
- 定义 miinitrd 的容量 EXT2FSSIZE,单位是兆。当前值为 18。(约 79 行)
- 定义并导出函数 depInstall、depInstallAs、depPyModule。定义这几个函数是为了
弥补 scons 对安装支持的不足。 (约 81-100 行)
- 创建并将必要的依赖关系添加到主创建环境 env 中。其中导出了 isofn_fmt、
bootcdfn、bootcdfn_debug、env、destdir、binfilesdir、devrootdir,并引入
MagicInstaller/src/SConscript。(约 101-216 行)
- 创建并将必要的依赖关系添加到 MagicBooter 创建环境 mbenv 中。其中导出了
mbenv、mbdestdir、mbdestdebugdir。(约 217-283 行)
- 创建并将必要的依赖关系添加到 MagicBooter 测试创建环境 testenv 中。其中导出
了 testenv。(约 284-294)
- 设定三种不同的 MagicBooter 的创建方式:实际运行模式 (real)、实地测试模式
(realtest)、本地测试模式(test)。(约 295-311 行)
4.2、MagicInstaller/MagicBooter/SConscript
此脚本分三种模式创建 MagicBooter。三种创建模式共享实际运行模式负责创建的
busybox-0.60.5/init.o、busybox-0.60.5/libbb.a、mxml-1.0/libmxml.a。不同的创建
模式,定义不同的宏来编译 MagicBooter.c。
4.3、MagicInstaller/src/magic.installer/SConscript
此脚本的内容如下:
- 准备 MagicInstaller/src/magic.installer/po/SConscript 需要的一些变量。
(约 23-32 行)
- 将一些安装时需要的目录的路径保存到变量中。(约 33-38 行)
- 定义 m4bld,进行必要的 m4 变换。(约 39-44 行)
- 将 magic.toplevel、magic.installer、magic.actions.server 和
magic.actions.quit 安装到目标文件系统中的 /usr/bin 目录下。(约 39-54 行)
- 将 magic.installer.xml、magic.values.xml 安装到 /usr/share/MagicInstaller
目录下。(约 55-63 行)
- 编译 mipublic.py、mivalues.py、xmlgtk.py、magicstep.py、magicpopup.py、
short_operations.py、long_operations.py 并将编译生成的 .pyc 文件安装到
/usr/lib/python2.2/site-packages 目录中。(约 64-71 行)
- 导出变量并引入子目录的 SConscript。(约 72-83 行)
4.4、MagicInstaller/src/magic.installer/po/SConscript
此脚本主要完成:
- 从 MagicInstaller/src/magic.installer/UIxml 目录下各个 xml 文件收集需要
进行本地化的字符串 (通过调用 MagicInstaller/scripts/xmlgettext.py),并生成
xmltranslation.py;
- 调用 xgettext 以生成 magic.installer.pot;
- 将 zh_CN.po 转换为 zh_CN.utf8.po,再转换为 zh_CN.mo,并安装到目标文件系统的
/usr/share/locale/zh_CN/LC_MESSAGES/magic.installer.mo。