下载 PDF 格式文档:
http://app.weiphone.com/files/how_to_make_deb.pdf
本贴由 http://bbs.weiphone.com/read-htm-tid-300101.html 修改更新。
一个 deb 安装包由两个部分组成,一个是安装控制/识别信息,另外一个就是实际的程序文件。
用7-zip或Linux下的存档管理器打开 deb 文件,其中安装控制/识别信息储存在 control.tar.gz 里面,而 data.tar.xxx 则储存了程序数据。
解包deb文件
准备打包deb的目录/文件
完成deb数据配置
DEBIAN之control
DEBIAN之脚本preinst/postinst/prerm/postrm/extrainst_
打包deb
【可选】deb文件规范命名
本贴由 http://bbs.weiphone.com/read-htm-tid-300101.html 修改更新。
引用
制作deb文件需要有dpkg-deb命令,Ubuntu/Debian 系统自带此命令,越狱过的 iPhone OS 也有此命令,Mac OS X 下需安装Fink,Windows 下需安装 Cygwin。
Fink 下载页面: http://www.finkproject.org/download/
Cygwin下载地址: http://www.cygwin.com/setup.exe
以上系统中,iPhone OS最适合用来打包deb文件,因为iPhone OS上的用户/组设置与所需要的设置是完全一致的。但因为iPhone/iPod Touch毕竟是手持设备,处理性能比不上电脑,在打包体积较大的deb文件时需要很长时间,有可能会导致失去连接或者SpringBoard崩溃。而且在WinSCP中涉及文本修改的部分,如果文本含有中文的话,编码是个问题(不会保存为UTF-8)。
Ubuntu/Debian 是 deb 文件系统的原生系统,在兼容性和处理性能上最好,但问题在于,Ubuntu/Debian 没有 iPhone OS 上的一些用户和组,最典型的就是wheel、mobile组和mobile用户。
Mac OS X的问题跟 Ubuntu/Debian 差不多,没有mobile用户/组,而且需要装 Fink 才能支持 deb。
Windows的问题最多,Cygwin体积超大不说,使用起来还很麻烦,加上 Windows 的文件系统和 Unix 标准完全不同,且 Windows 下会面临更严重的编码问题,所以不推荐用 Windows 来打包。
不管是哪个系统,打包 deb 的方法是一样的,只是在某些地方对于某些系统需要特别注意。
一个 deb 安装包由两个部分组成,一个是安装控制/识别信息,另外一个就是实际的程序文件。
用7-zip或Linux下的存档管理器打开 deb 文件,其中安装控制/识别信息储存在 control.tar.gz 里面,而 data.tar.xxx 则储存了程序数据。
解包deb文件
引用有时候不是需要制作一个全新的deb,而是需要修改现有的deb,那么第一步就是解包。假设deb的文件名是abc_1.0.deb
那么解包命令是和
- dpkg-deb -x abc_1.0.deb tmp
- dpkg-deb -e abc_1.0.deb tmp/DEBIAN
第一个命令是用于解压出实际数据到tmp目录下,后一个命令是解压出安装控制脚本到tmp/DEBIAN目录下,此处必须是大写的DEBIAN。
可以看到在tmp目录下出现了实际数据和DEBIAN目录。
以dpkg-deb -x 和- e 命令解包deb会保留文件的属性/权限/用户/组等信息。
关于dpkg-deb的命令,可以输入
- dpkg-deb --help
进入DEBIAN目录,可以看到有一个control文件,无后缀名,这个文件就是用来记录deb的安装信息。有时候还可以看到postinst,preinst,prerm,postrm,extrainst_这些文件,这些文件是deb安装的时候执行的脚本(类似于Windows下的批处理文件)。
另外一种解包deb的方法就是用7-zip或者存档管理器之类的软件直接解包到指定目录,但这样不会保留文件的属性/权限/用户/组等信息,因此除非这些信息不重要,或者这些信息是通过脚本来设置,否则不推荐使用该种方法。如果只是要提取某些文件的话倒是可以用,省事一些。
准备打包deb的目录/文件
引用
如果是解包已有的deb,那么目录已经配置好了。如果是新建一个deb,需要有一个主目录,这里以tmp为例,在tmp目录下新建一个目录,DEBIAN。
完成deb数据配置
引用
将程序文件放在tmp目录下。放置规则是,假如在iPhone OS上一个文件是 /Applications/ABC.app/ABC,那么就在 tmp 目录下依次新建目录Applications,ABC.app,然后把ABC放在ABC.app下。其余文件和目录也是一样的放置。
这里要注意的是文件的属性/权限/用户/组的问题,当然前提是知道文件的属性和权限等信息。
通常来说,可执行文件,比如应用程序的可执行文件,脚本等,属性需设为0755或更高(0775或0777),/var/mobile/下的绝大部分文件/文件夹的用户/组需设为mobile等。
要设置文件/文件夹的权限/属性,使用命令这样的格式,ABCD为需要的属性/权限,比如0644,0755等,一般来说,可行性文件需要设为0755(0775和0777大部分情况下是用不上的,有些特殊的需要设为4755等),其它文件默认就是0644(不可执行),XXX是文件名,可以加上路径。
- chmod ABCD XXX
要设置文件/文件夹的用户/组,使用命令其中user是需要设置的用户,group是组。最常用的是root:wheel和mobile:mobile。
- chown user:group XXXX
注意:
1. 如果当前用户是非root帐户,如果要将文件的用户/组设为root,需要使用sudo命令来提示权限。
2. 如果要递归设置以上信息,可以使用 -R 参数。比如要将tmp目录下的所有子目录和文件设为0755及root:wheel,可以使用命令
- chmod -R 0755 tmp
- chown -R root:wheel tmp
关于文件/文件夹的属性/权限/用户/组的更多说明:
- 因为deb打包是先将所有的文件/文件夹归档为tar文件之后再压缩,因此文件/文件夹的属性/权限/用户/组这些信息会被保留下来,因此如果直接设置好了以后再打包deb的话就不需要通过postinst之类的控制脚本来设置权限等信息。
- 如果无法直接设置属性/用户/组等信息,通常需要在postinst脚本里加入设置属性/权限/用户/组的命令
- 如果deb中的目录是在iPhone OS本身就有的,那么不需要另外设置属性/权限/用户/组等,即使现有的和需要的不一样。因为deb安装不会替换原有文件夹的数据。比如/Applications目录是root:admin,而要打包的deb中该目录是ABC:DEF,那么不需要修改ABC:DEF
- 尤其要注意的是mobile:mobile
- Ubuntu/Debian上虽然没有wheel组,但是root:root在iPhone上会自动转为root:wheel,所以如果是准备将root:root变为root:wheel,那么可以保留root:root就可以了。
- 理论上来说,在无安装脚本设置用户/组的前提下,如果不涉及mobile:mobile的用户/组,全部操作都可以直接在Ubuntu/Debian和Mac OS X上完成
DEBIAN之control
引用
control记录了软件包标识,软件名,介绍,作者,冲突软件等信息,用来标识一个软件包。在某些软件中,如Icy,是区分大小写的,但在Cydia中是不区分大小写的。
特别注意:
- control文件必须是UTF-8,Unix编码,Unix/Linux换行符(LF),不符合规范的control会导致Cydia无法打开。
- 文件末尾需有一个空行。
Package:
软件包标识符,类似于身份证,一个软件包必须要有一个唯一的标识符。通常是用com.xxx.abc这样的形式来命名。
Architecture:
架构,用于标识运行的系统,iPhone上为iphoneos-arm
Version:
版本号,不能用下划线和逗号和空格。格式有(以逗号分隔) 1.0,1.0f,0-1,1:1.0,其中1:1.0这种格式比较特殊,在Cydia中,1:1.0仍然会显示为1.0,但版本号实际是高于1.0的。
和
以上3项是必须的,缺了任何一项deb打包就不能成功。
以下均为可选项:
Name:
软件包在Cydia中的显示名称,中英文不限,也可以用空格,但不宜过长(长了显示不完全)。
和
Author:
软件作者。
Maintainer:
维护者,一般是软件源的拥有者。
Sponsor:
负责人,可以是个人也可以是网站。
Author,Maintainer,Sponsor 的格式相同,均为 名称+空格+<邮件地址或网址>,经测试,如果名称为中文的话,即使写了邮件地址和网址,在Cydia中点击也不会跳转。
示例: WEIP.Tech <weip.com@gmail,com> 或 WeiPhone.com < http://www.weiphone.com>
如果没有邮件地址或网址,则不需要 <> 及<>中的内容。
中文名或未提供邮件/网址,无 > 符号
Icon:
指定软件包的图标显示。当无Icon设定时,Cydia会显示该软件包所在的分类的图标。
格式:
- 在线地址,如 http://www.abc.com/abc.png
- 本地地址:file://+路径,如file:///Applications/Cydia.app/Sources/app.weiphone.com.png
注:在软件页面(非列表页面),自定义的图标是不会显示的,显示的是分类图标。
Section:
软件分类,中英文无限制,排列顺序是 英文->中文。
和
另外,如果在分类加上[],比如 [工具],那么这个是排在最前面的。
Installed-Size:
解包后的文件大小,可以有小数位,以kb为单位,不需要注明kb,这个不需要很精确,而且小数位在Cydia里显示不出来(不是四舍五入,全部舍了)。至于文件大小是否包含DEBIAN目录中的内容就随意了。
Priority:
优先级,可填 Required,Important,Standard,Optional,Extra,依次为 必须,重要,一般,可选,次要。虽然没有什么实际作用,但优先级为Required和Important的软件包在卸载时会有警告,这样可以避免删除一些系统必须的软件。但Required和Important不要滥用,一般用Standard,Optional或Extra即可。
优先级在Cydia中是不会显示的
Essential:
是否必须软件包,可填 yes 和 no, 填yes则为必须软件包,卸载时Cydia会有警告。卸载Essential标记为yes的软件包可能会导致系统问题。当然此功能需慎用,不要因为不希望用户删除自己的软件而加入Essential: yes。如果没有Essential这项的话默认就是非必须的,相当于Essential: no。
Depends:
Depends 字段应该包含您的软件包正常工作绝对必需的任何软件包的名称。
Pre-Depends:
"Pre-Depends"是为特例而保留的。当某个软件包被作为"Pre-Depends"列出时,它强制系统在试图安装您的软件包之前完全安装所指定的软件包。
Conflicts:
冲突软件包。比如软件包A和B有冲突,不能同时安装。比如说A和B冲突,当系统已经安装了A的时候尝试安装B,则不能继续。
Provides:
提供的软件包,比如说软件包A包含B的全部功能,那么则是A provides B,因此可以在安装了A的前提下不安装B。但此功能在非Cydia的软件管理工具中可能会无法识别(实际是这些软件不合deb标准)
Replaces:
替换软件包,安装A会替换B。
- 以上5项的格式相同,直接填软件包的Package标识即可,如果需要加入版本号,则为 软件表标识+空格+(判断符号 版本号)。
比如 Depends: apt-key, firmware (>=3.0), 这表示依赖于apt-key,不限版本,firmware,且版本大于或等于3.0。
- 判断符号:远远低于(<<)、低于(<)、低于或等于(<=)、仅等于(=)、等于或高于(>=)、大于(>)以及远远高于(>>)。
- 表示多个软件包,以英文逗号分隔。
- 表示“或”关系,用 | 分隔。比如软件包C依赖于A或B,可写Depends: A | B。 但“或”关系要慎用。原因是,当不存在“或”关系的时候,假设B依赖于A,且系统并未安装A,那么在Cydia中安装B的时候会自动下载安装A。而假如说C依赖于A或B,且A与B都未安装,那么在安装C的时候就会失败,因为系统无法判断是应该下载A还是B。除非系统已经安装了A或B,否则C不能安装。
- 一个特殊的依赖:firmware。这个Package记录了固件版本,在对固件版本有要求的软件包上特别重要。
- 假设B依赖于A,那么在卸载A的时候也会一起卸载B
Description:
软件描述,不能在control里直接换行,如果需要实现换行显示,可以使用<br>代码。当指定了Depiction时,在软件查看页面不会显示Description。
Depiction:
功能类似于软件描述,链接到一个网页,以网页的内容代替软件描述。只在软件查看页面显示,在软件包列表页面不显示。
可以使用本地网页,格式同Icon。
注意:此功能可能会消耗大量网络流量。
Homepage:
链接到页面,Cydia中显示为More Information。
页面不会主动加载。
Tag:
标签,用于分类软件包信息。
purpose:: 软件包类型,比如软件源,命令行,库等等。purpose::console表示该软件为命令行界面。可选项有 commercial, console, daemon, extension, library, uikit, x,对应图标文件在 /Applications/Cydia.app/Purposes 目录下。也可以自行添加 purpose 分类,并加入同名图标即可。
role:: 软件包使用者归类。developer开发者,hacker骇客,enduser普通用户,该标签用于Cydia中软件包显示过滤。
cydia::commercial Cydia Store软件。
示例: control.txt (1 K) 下载次数:738 去掉 .txt 后缀名
DEBIAN之脚本preinst/postinst/prerm/postrm/extrainst_
引用
很多时候deb安装并不是把文件复制到iPhone里就可以了,还需要执行一些命令,比如设置权限,备份文件,加载启动进程等等,那么这时候就需要一些脚本来实现这些操作。
标准的deb脚本有4个,preinst,postinst,prerm和postrm,pre是表示XX之前的前缀,post是表示XX之后的前缀,inst是install(安装)的缩写,rm是remove(移除)的缩写,所以这4个脚本的功能很明显:
- preinst:在复制文件前执行的脚本
- postinst:在复制文件之后执行的脚本
- prerm:在卸载前执行的脚本
- postrm:在卸载之后执行的脚本
在Cydia中还存在一个独立的脚本,extrainst_,从字面上来讲就是额外的安装脚本。这个脚本是Cydia的作者Saurik为解决某些脚本只需要在安装时执行,在升级时不执行而专门引入的一个脚本,功能跟postinst差不多,和Installer时代的“ahhhh”比较相似。关于extrainst_的详情可以看看这个: http://www.telesphoreo.org/pipermail/cydia-packagers/2008-September/000252.html
5个脚本的编写方法基本是一样的,但为了适应Cydia的安装,在某些情况下需要进行特定的配置。
查看某些deb可能会发现这样的语句:
- if [[ $1 == install || $1 == upgrade ]]; then
这种语句是为了区别安装/升级/卸载而准备的脚本。$1是一个外部变量,将这个外部变量传入脚本来执行,而这个外部变量是由Cydia软件自身生成的。
简单来说,如果是安装,则是 $1 == install ;如果是升级,则是$1 == upgrade;如果是卸载则是 $1 == remove。
if 是个判断语句,当满足if后[ ]中的指定条件时,if中的内容就会执行。那么这里就可以通过设定install/upgrade/remove来控制在不同操作时执行的命令。
但要注意的是,这个功能只能在Cydia中使用,其它的apt软件管理工具,如Icy,Rock等,不能识别这个命令,因此无法执行if中的语句,所以在写脚本的时候到底需不需要用这种格式,就看自己的需要了。
总体来说,Unix的脚本(Shell Script)有其固定的格式。
文件顶头为
- #!/bin/bash
表示调用bash这个shell
之后就是运行的命令了。
脚本中如果需要注释,可以使用 # 符号。 以 # 开头的行会被当作注释,里面的内容在执行过程中没有意义。
通配符: *
最常用的两个命令自然是设置属性/权限/用户/组
设置属性/权限
- chmod 【-R】 属性 文件名
由于deb的脚本执行都是在root用户下,因此不需要提升权限,即不需要使用sudo命令。
-R参数:表示递归,加上此参数会将指定的目录及其子目录的全部目录和文件的属性改变。
属性:有多种写法。具体可以看 http://baike.baidu.com/view/1229012.htm?fr=ala0_1
比较常用的几种属性:
- chmod +x XXXXX 为文件增加可执行权限
- chmod 0644 XXXXX 不可执行文件最常使用的权限
- chmod 0755 XXXXX 可执行文件最常使用的权限
实例:
- chmod -R 0755 /Applications/Cydia.app
设置用户/组
- chown 【-R】 用户:组 文件名
同样不需要sudo来提示权限。-R也是表示递归。
比如要将文件A设为root用户,wheel组,可以使用命令
- chown root:wheel A
要将 /var/mobile/Documents 下所有文件夹和文件设为mobile用户和mobile组,可以使用命令
- chown -R mobile:mobile /var/mobile/Documents
删除文件/文件夹
- rm 【参数】 文件名
- rmdir 文件夹名
rm 是广义的删除命令,可以用于删除文件和文件夹。
rm常用参数有 -f 和 -r
参数 -f :强制删除,即使文件不存在。当无 -f 参数时,要删除一个不存在的文件就会报错,从而中断脚本的执行,因此在绝大部分情况下 -f 参数都是必要的。
参数 -r :递归。要以rm命令删除文件夹,必须加上 -r 参数。该参数会删除目录下的全部子目录和文件,包括链接到的文件/文件夹。因此 -r 参数要慎用。比如有一个链接是指向根目录的,在 有 -r参数的情况下,删除这个链接会导致整个文件系统全部被删除。
实例:
删除 /var/mobile/abc文件
- rm -f /var/mobile/abc
删除 /var/mobile/trash/下的全部文件/文件夹
- rm -rf /var/mobile/trash
rmdir仅能用于删除空文件夹,也就是说,不能用于删除文件和非空的文件夹。
实例:
删除空目录 /var/mobile/trash
- rmdir /var/mobile/trash
复制文件/文件夹
- cp 【参数】 原始文件 目的文件
参数列表:
- -l(小写字母L):创建硬链接,相当于一个镜像,而不是实际创建两个文件
- cp -l abc def
- -f:强行复制,如果目的文件已存在,覆盖之且不提示
- cp -f abc def
- -p:保留文件的属性、用户、组、时间戳等信息
- cp -p abc def
- -r和-R:作用都是递归,将文件夹下的全部子文件和子文件夹一起复制
- cp -r abc/ def/
- -s:创建符号链接而不是创建双份文件
- cp -s abc/ def/
- -n:如果目的文件已存在,则不覆盖且不提示
- cp -n abc def
- -a:相当与-dR,保留文件自身的属性等数据,一并复制子文件/文件夹
- cp -a abc/ def/
移动文件/文件夹 & 重命名
- mv 【参数】 源文件 目的文件
参数:
-f:强行移动,如果目的文件已存在,覆盖之且不提示
其实 mv 命令就是复制之后再删除,但 mv 命令会自动保留文件的属性等数据,移动文件夹时会自动移动子文件/子文件夹,因此都不需要另外的参数。
重命名是由mv命令来实现的,mv 就是将 源文件 移动到 目标文件的位置并以目标文件的文件名保存。
显示语句
- echo “语句"
示例:显示语句“测试echo命令。”
- echo "test echo command"
管理自启动服务
- launchctl load或unload -w plist文件路径
实例:
让wefit3自启动
- launchctl load -w /System/Library/LaunchDaemons/com.weiphone.fitx.plist
禁用iPhone日志记录syslogd
- launchctl unload -w /System/Library/LaunchDaemons/com.apple.syslogd.plist
记录自启动进程的plist文件保存在以下两个目录:
/System/Library/LaunchDaemons/ 和 /Library/LaunchDaemons/
杀死进程
- killall 进程名
示例:关闭Safari进程
- killall safari
判断
基本格式是
- if [ 判断条件一 ]; then
- 执行命令
- else
- 执行命令
- fi
实例:
如果文件abc存在,则备份为abc.bak,否则将文件def重命名为abc
- if [ -f abc]; then
- mv -f abc abc.bak
- else
- mv def abc
- fi
其中[ -f abc ]可以由[ -e abc]取代
如果目录abc不存在,则新建一个目录abc
- if [ ! -e abc ]; then
- mkdir abc
- fi
获取固件系统版本号
- sw_vers -productVersion
获取设备型号
- uname -i
- uname -m
-i 参数是显示设备代号,-m参数是显示设备型号(实质效果相同)
比特说iPod Touch 1代,运行uname -i得到的结果是N45AP,而运行uname -m的结果是iPod1,1
iPhone 2G iPhone1,1 M68AP iPhone 3G iPhone1,2 N82AP iPhone 3G[S] iPhone2,1 N88AP iPhone 4 iPhone3,1 N90AP iPod Touch 1G iPod1,1 N45AP iPod Touch 2G iPod2,1 N72AP iPod Touch 3G iPod3,1 N18AP iPad iPad1,1 K48AP
Cydia中安装完之后重新启动SpringBoard
- declare -a cydia
- cydia=($CYDIA)
- if [[ ${CYDIA+@} ]]; then
- eval "echo 'finish:restart' >&${cydia[0]}"
- fi
Cydia中安装完之后重新启动设备
- declare -a cydia
- cydia=($CYDIA)
- if [[ ${CYDIA+@} ]]; then
- eval "echo 'finish:reboot' >&${cydia[0]}"
- fi
几个比较有用的实例:
备份
preinst(安装之前就要把原始文件备份,不能等到安装完已经覆盖以后才备份)
- if [ ! -f 原始文件备份 ]; then
- echo "原始文件的备份已存在,跳过备份"
- else
- cp -p 原始文件 原始文件备份
- echo "原始文件已备份"
- fi
postrm(还原备份)
- echo "还原备份"
- mv -f 原始文件备份 原始文件
备份操作在制作补丁的时候,尤其是替换类型的补丁时特别有用。
判别具体固件版本
在control里可以通过Depends来设置依赖的固件版本,但有时候需要在某个特定固件版本下进行操作
比如说一个软件,要求固件版本大于或等于3.0,但在固件版本为3.1的时候必须删除某一个文件才能运行,那么脚本可以这样写:
- firmware=$(sw_vers -productVersion)
- if [[ $firmware == 3.1 ]]; then
- 删除文件
- fi
判别设备型号
当设备型号为iPod Touch时删除某个文件
或
- platform=$(uname -i)
- if [[ $platform == "N45AP" || $platform == "N72AP" || $platform == "N18AP" ]]; then
- 删除文件
- fi
- platform=$(uname -m)
- if [ $platform == iPod* ]; then
- 删除文件
- fi
更多关于Shell Script的信息请见 http://www.hack base.com/tech/2009-10-10/56808.html (去掉空格)
打包deb
引用
如果在DEBIAN中有脚本存在,则需要将整个DEBIAN文件夹及子文件属性设为0755
- chmod -R 0755 DEBIAN
如果没有脚本的话保留0644属性即可,0755属性也没问题。
打包命令
- dpkg-deb -b PATH FILENAME
其中PATH是打包deb的工作目录,DEBIAN文件夹需位于PATH指定的目录下
FILENAME是deb的文件名,这个可以自己决定。
以上命令打包deb默认是采用gz格式压缩,压缩率有限,如果要获得更改的压缩率(更小的文件体积),可以使用bzip2和lzma格式。
压缩为bzip2格式
- dpkg-deb -bZ bzip2 PATH FILENAME
压缩为bzip2格式
- dpkg-deb -bZ lzma PATH FILENAME
默认的gz格式压缩率最低,bzip2格式居中,lzma格式压缩率最高。(当然也会有例外)
注意:
- 压缩率越高,压缩时间越长,在iPhone上使用较高的压缩率有更大概率导致失去响应。
- iPhone OS 2.x无lzma组件,因此无法安装lzma压缩的deb。iPhone OS 3.x可以解压lzma压缩。
- 如果deb包含的文件文本量比较大,那么一般可以获得不错的压缩率。但如果是像铃声,jpg/png图片这样文件本身就是压缩格式的情况,继续压缩的可能性就不高了,这类情况很难获得比较好的压缩率
【可选】deb文件规范命名
引用
引用
图形界面的deb制作工具 Debian Package Maker
网址: http://code.google.com/p/debianpackagemaker/
个人感觉不如直接在命令行里来的直观,有兴趣的朋友可以自己试试。