- 论坛徽章:
- 0
|
本帖最后由 duanjigang 于 2012-12-22 14:49 编辑
Macros (宏)
这里是根据自己的理解写点,如果有错误之处请指出。
RPM 不提供那种像C语言一样格式的对过程的宏定义,我们在spec 文件中能看到的都是单个变量的定义,比如:但是却很少或者说基本看不到类似于:
- #define TR_HLEN (sizeof(struct trh_hdr)+sizeof(struct trllc))
复制代码 这样定义过程代码的写法。
不过在RPM的 build 过程中有两个动作对于大多数包来说基本上都是一样的操作,因此 RPM 为它们设置了两个宏定义:源代码的解压缩 和 代码的 patch 过程
- The %setup macro, which is used to unpack the original sources.
- The %patch macro, which is used to apply patches to the original sources.
复制代码 %setup 宏在使用时大多数情况都是不加任何选项的,比如:
- Source: ftp://ftp.gnomovision.com/pub/cdplayer/cdplayer-1.0.tgz
- %prep
- %setup
复制代码 这个过程,解释成执行脚本,内容如下:
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd cdplayer-1.0
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
复制代码 我们能看到,就是目录切换,代码解压缩,检测解压缩结果,进入目录,修改属主/组和mode.
在这里需要注意几点,在 %setup 不加任何参数时,rpm 命令执行时默认了几个咚咚:
第一个:build 目录是,cdplayer-1.0,并且路径是 /usr/src/redhat/BUILD/cdplayer-1.0
第二:删除了原来的build 目录
第三:对源代码进行了解压缩。
第四:修改属性时需要进入cdplayer-1.0目录。
看到这里你可能会感觉到比较迷惑,难道这些不应该吗?呵呵。是的,不过 rpm 在 %setup 的宏定义中提供了几个执行选项,可以修改默认执行动作中的操作流程。
下来我们一一看下.
-n <name> : 设置build 目录的名字。
因为默认的build 目录名字是 <name>-<version>的方式,但是你也可以通过 -n name 来指定,比如:执行的脚本过程如下:
- cd /usr/src/redhat/BUILD
- rm -rf cd-player
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd cd-player
- cd /usr/src/redhat/BUILD/cd-player
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
复制代码 我们能看到,默认的build 名称,是被 -n 选项修改了。
-c 创建build目录,并且在解压缩前进入该目录
这一点,个人很有感触,有时候在制作rpm前压制源码文件时,经常会
- tar -czf mycode.tar.gz mycode
复制代码 把整个目录打包成一个压缩文件,而有时候则会直接把源代码压缩,而不包括目录
- cd mycode
- tar -czf mycode.tar.gz *
复制代码 ,这时,-c 选项就能帮上忙了,替你建立目录,然后在目录里面解压缩文件。
在该例中,加上 -c 后,解释执行的脚本过程如下:
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- mkdir -p cdplayer-1.0
- cd cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
复制代码 如果你的压缩包解压缩后就是白花花的代码,那就应该用上这个选项。
-D: 在解压缩前不删除目录
这种情况的应用场景就是你新解压缩的代码是要被加入到新的目录树中,因此以前的目录不能删除。
对应的解释脚本执行过程如下:
- cd /usr/src/redhat/BUILD
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd cdplayer-1.0
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
复制代码 -T: 不进行默认压缩文件的解压缩
有人可能会问:不解压缩代码,那还搞毛啊?先不要着急,我们会接后着后面的 option 一起来看这个 选项的应用场景.
首先看下加上 -T 时 %setup 执行的动作:
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- cd cdplayer-1.0
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w
复制代码 -b <n>: 在进入目录前解压缩第 n 个源码包
看下 openssl 中的source 定义片段:
- Source: openssl-fips-%{version}-usa.tar.bz2
- Source1: hobble-openssl
- Source2: Makefile.certificate
复制代码 RPM 对 Source 的解释是 编号是0的Source,也就是 Source0,然后我们看下在spec 中,如下写的执行结果:根据 -b 的解释,它的执行过程如下:
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd cdplayer-1.0
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
复制代码 可以看到对 Source0 的解压缩进行了两次,重复了。
我想这下你应该理解了 -T 的作用了,是为了避免不必要的冗余解压缩,当然这个场景是你直接想用Source0 以后的源码,而不用第一个Source.
然后看下 %setup -T -b 0 结合使用的效果:
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd cdplayer-1.0
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w
复制代码 这样就对了,当然重点是 -b 后面的参数你可以自己设置。
-a n: 在进入目录后解压缩第 n 个源码
这个跟 -b 有些像,不过 -b 是在进入目录前解压缩。反正他们都是跟目录相关的,具体场景自己应该可以去想了,我们只看下执行的动作:
%setup -T -a 0
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- cd cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
复制代码 可以看到没有创建目录直接就 cd 了,因此,它大多与 -c 一起结合使用:
%setup -c -T -a 0
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- mkdir -p cdplayer-1.0
- cd cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/cdplayer-1.0.tgz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
复制代码 然后把这些结合起来,看下 %setup 处理多个source 源码包的一个例子:
- %setup
- %setup -T -D -a 1
- mkdir database
- cd database
- gzip -dc /usr/src/redhat/SOURCES/source-two.tar.gz | tar -xvvf -
复制代码 按照上面的规范,它解释后的动作是:
- cd /usr/src/redhat/BUILD
- rm -rf cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/source-zero.tar.gz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- cd cdplayer-1.0
- cd /usr/src/redhat/BUILD/cdplayer-1.0
- chown -R root.root .
- chmod -R a+rX,g-w,o-w .
- cd /usr/src/redhat/BUILD
- cd cdplayer-1.0
- gzip -dc /usr/src/redhat/SOURCES/source-one.tar.gz | tar -xvvf -
- if [ $? -ne 0 ]; then
- exit $?
- fi
- mkdir database
- cd database
- gzip -dc /usr/src/redhat/SOURCES/source-two.tar.gz | tar -xvvf -
复制代码 我们能够看到是把 0 代码和 1代码解压缩到同一个目录下,然后在build 目录下建立 database 目录,把 2 代码解压缩到 database 目录下。
上面所有参数结合起来使用使得这个过程以最简洁的方式执行了。
得瑟点个人的感觉:spec 中这样去增加%setup 的多个选项来控制脚本执行的过程有些得不偿失,开发人员有记住这些选项的时间,自己会去研究原始的脚本怎么样写更合适。
不过也算是一种机制,其目的就在于你在使用它时,为用户提供能用实现功能的接口,至于接口的好坏,可能并没做太多考虑,有些烂,呵呵。
|
|