Jun
28
前面的[原]自己制作rpm软件包(1)和[原]自己制作rpm软件包(2),两篇文章比较详细的介绍了rpmbuild命令的使用,以及.spec文件的编写。而[原]关于rpm打包的一个补充也描述了,针对特定的平台如何加入变量、修改标准宏,然后再进行编译的情况。
而实际上,通常我们都希望一个套件只针对一个.spec文件,这可以很方便的管理。所以,我们可以在.spec中加入条件判断语句,以便根据不同的条件,执行相对应的编译和打包动作。
一、写法
.spec中的条件判断语句有两种:
1、if结构
其中%{str}是条件,0为假,非0为真。
2、?:结构
其中{}用于控制范围,而“?”号和“:”号是分割符,如果要判断条件是非的情况,可以在“?”号前加“!”号。
此条件与前面的%if有点不同,其只判断变量是否定义,定义了就为真,否则就为假,即使变量定义为0,也为真,并运行后面的语句。
这请特别留意!不用混乱了两语句的作用,其是不相等的。
二、实例
语句很容易理解,下面截取一个实际chkrootkit.spec文件来说明:
开头:
BuildRequires部分:
install部分:
files部分:
※说明
三、使用
既然增加了变量,那就可以在使用rpmbuild的时候使用。
1、不给变量赋值的情况
假设我的系统中并没有安装desktop-file-utils这个rpm包,那么默认结果如下:
2、使用-D参数赋值
第一种方式:
第二种方式:
可以看到,第二种方式只是绕过了开始的asianux2变量判断而已,结果是相同的。
而实际上,通常我们都希望一个套件只针对一个.spec文件,这可以很方便的管理。所以,我们可以在.spec中加入条件判断语句,以便根据不同的条件,执行相对应的编译和打包动作。
一、写法
.spec中的条件判断语句有两种:
1、if结构
引用
%if %{str}
%else
动作
%endif
%else
动作
%endif
其中%{str}是条件,0为假,非0为真。
2、?:结构
引用
%{?变量:动作1}动作2
其中{}用于控制范围,而“?”号和“:”号是分割符,如果要判断条件是非的情况,可以在“?”号前加“!”号。
此条件与前面的%if有点不同,其只判断变量是否定义,定义了就为真,否则就为假,即使变量定义为0,也为真,并运行后面的语句。
这请特别留意!不用混乱了两语句的作用,其是不相等的。
二、实例
语句很容易理解,下面截取一个实际chkrootkit.spec文件来说明:
开头:
引用
%{?asianux2:%define _without_freedesktop 1}
BuildRequires部分:
引用
%{!?_without_freedesktop:BuildRequires: desktop-file-utils}
install部分:
引用
%install
......
%if %{?_without_freedesktop:1}0
%{__install} -Dp -m0644 chkrootkit.desktop %{buildroot}%{_datadir}/gnome/apps/Utilities/chkrootkit.desktop
%else
%{__install} -d -m0755 %{buildroot}%{_datadir}/applications/
desktop-file-install --vendor %{desktop_vendor} \
--add-category X-Red-Hat-Base \
--dir %{buildroot}%{_datadir}/applications \
chkrootkit.desktop
%endif
......
%if %{?_without_freedesktop:1}0
%{__install} -Dp -m0644 chkrootkit.desktop %{buildroot}%{_datadir}/gnome/apps/Utilities/chkrootkit.desktop
%else
%{__install} -d -m0755 %{buildroot}%{_datadir}/applications/
desktop-file-install --vendor %{desktop_vendor} \
--add-category X-Red-Hat-Base \
--dir %{buildroot}%{_datadir}/applications \
chkrootkit.desktop
%endif
files部分:
引用
%files
......
%{?_without_freedesktop:%{_datadir}/gnome/apps/Utilities/chkrootkit.desktop}
%{!?_without_freedesktop:%{_datadir}/applications/%{desktop_vendor}-chkrootkit.desktop}
......
%{?_without_freedesktop:%{_datadir}/gnome/apps/Utilities/chkrootkit.desktop}
%{!?_without_freedesktop:%{_datadir}/applications/%{desktop_vendor}-chkrootkit.desktop}
※说明
引用
1、通过在开始部分增加一个asianux2变量,即可针对该变量是否定义进行判断
2、并且根据结果,给予_without_freedesktop变量1或0的值;
3、后续,根据_without_freedesktop变量的情况,执行不同的动作;
4、变量中不能带“-”、“.”号等分隔符,但可使用“_”下划线;
5、变量应尽可能使用整数作为标识,若使用字符串,可能会有误解;
6、变量未定义,其值为-1,是不可识别的值。所以,在使用判断前,应使用?:架构做一个默认值的定义,以避免出错。
2、并且根据结果,给予_without_freedesktop变量1或0的值;
3、后续,根据_without_freedesktop变量的情况,执行不同的动作;
4、变量中不能带“-”、“.”号等分隔符,但可使用“_”下划线;
5、变量应尽可能使用整数作为标识,若使用字符串,可能会有误解;
6、变量未定义,其值为-1,是不可识别的值。所以,在使用判断前,应使用?:架构做一个默认值的定义,以避免出错。
三、使用
既然增加了变量,那就可以在使用rpmbuild的时候使用。
1、不给变量赋值的情况
假设我的系统中并没有安装desktop-file-utils这个rpm包,那么默认结果如下:
引用
# rpmbuild -bb chkrootkit.spec
error: Failed build dependencies:
desktop-file-utils is needed by chkrootkit-0.47-1.i386
error: Failed build dependencies:
desktop-file-utils is needed by chkrootkit-0.47-1.i386
2、使用-D参数赋值
第一种方式:
# rpmbuild -bb chkrootkit.spec -D 'asianux2 1'
第二种方式:
# rpmbuild -bb chkrootkit.spec -D '_without_freedesktop 1'
可以看到,第二种方式只是绕过了开始的asianux2变量判断而已,结果是相同的。
要实现你的要求,可以有两种方法:
1、使用define macros %(command)的方式,从命令来定义一个宏,然后使用%if判断;
2、可以在进行configure或者make的时候,通过bash的if语句去判断,然后执行不同的命令即可。
参考一下这里:
http://www.linuxfly.org/post/148.htm
还可以看看/usr/lib/rpm/macros中默认宏的定义咯。
# rpmbuild -bb chkrootkit.spec -D asianux2=1
应该写为:
# rpmbuild -bb chkrootkit.spec -D 'asianux2 1'
及后的命令也有类似的错误,已修正。