打包常用的 RPM 宏
构建服务教学 - 技巧和花样 - 跨发行版打包 - Debian 打包指南 - 打包检查
桌面菜单分类 - 打包常用的 RPM 宏 - 小脚本片段 - SysVinit 脚本 - 源代码服务
OBS 打包互助问答 - 打包黑名单
目录
- 1 RPM 宏
- 1.1 语法
- 1.2 %{_docdir} 文档目录
- 1.3 %{_infodir} 信息页面目录
- 1.4 %{_lib}
- 1.5 %{_libdir} 函数库目录
- 1.6 %{_mandir} 帮助页面目录
- 1.7 %desktop_database_post / %desktop_database_postun 更新桌面 Mimetype 数据库
- 1.8 %fdupes 清理冗余文件
- 1.9 %fillup_and_insserv 初始化启动脚本
- 1.10 %fillup_only
- 1.11 %find_lang
- 1.12 %icon_theme_cache_post / %icon_theme_cache_postun
- 1.13 %insserv_cleanup
- 1.14 %insserv_force_if_yast
- 1.15 %install_info
- 1.16 %install_info_delete
- 1.17 %perl_archlib
- 1.18 %perl_gen_filelist
- 1.19 %perl_make_install
- 1.20 %perl_process_packlist
- 1.21 %perl_sitearch
- 1.22 %perl_sitelib
- 1.23 %perl_vendorarch
- 1.24 %perl_vendorlib
- 1.25 %perl_version
- 1.26 %py_incdir
- 1.27 %py_libdir
- 1.28 %py_requires
- 1.29 %py_sitedir
- 1.30 %py_ver
- 1.31 %remove_and_set
- 1.32 %restart_on_update
- 1.33 %run_ldconfig (deprecated)
- 1.34 %run_permissions
- 1.35 %set_permissions
- 1.36 %sles_version
- 1.37 %stop_on_removal
- 1.38 %suse_update_config
- 1.39 %suse_update_desktop_file
- 1.40 %suse_version
- 1.41 %tcl_version
- 1.42 %ul_version
- 1.43 %verify_permissions
RPM 宏
语法
本章节阐述了 openSUSE 软件包常用的预定义 RPM 宏。许多都是通用 RPM 宏。但也有一些是 openSUSE 专有宏。想要了解其他的已有通用 RPM 宏,也可以参考其他的文档,比如 RPM 完全指南 或者 RPM 宏语法。
如果你对特定的宏感兴趣,你可以参考下列的链接:
如果你想要尝试写一些高级的 RPM 宏,RPM 也内置了 Lua 编程语言支持。
你可以在 /usr/lib/rpm/macros 和 suse_macros 文件中找到所有预定义的宏和它们的解释。其他额外的某类包专用的宏是由 /usr/lib/rpm/macros.d 文件夹下的文件来添加的。目录 /etc/rpm 是用于由系统管理员进行的每个系统的调整。如果你把宏%dump放在你的规格文件中,并使用 `rpmbuild -bp specfile`,它将列示出你系统上所有可用的宏。然而,直接执行 `rpm --showrc' 更容易一些。
RPM 宏和正常的 Linux 命令的一个显著区别就是『选项』和『参数』是如何定义的。RPM 只提供了基本的『选项』处理支持。一个限制是所有的『选项』必须在参数之前定义,不可以让『选项』和它相关的参数成对出现。例如,Linux 命令 top 提供了如下的命令概述:
top
[-bcisS
] [-d
delay
] [-n
iterations
] [-p
pid
] [, pid
...]
里面使用的『对』 -d delay, -n iterations, -p pid 和所有其他的参数都是可选的。参数之前的选项定义了命令行中真正使用的参数。这样就可以这么调用:
例 1: top -n 20 -p 10345
例 2: top -d 1 -p 10345
命令明白 20 是迭代次数,1 是延迟,10345 是进程号。
但由于 RPM 处理能力的限制,相关的 RPM 宏的命令概述应该像这样:
%top
[-bcisSdnp
] [delay
] [iterations
] [pid
] [,pid
...]
所有的『选项』必须在参数之前定义,然后选项再来定义那些参数是需要的。这意味着上例中的同功能 RPM 宏(如果有的话)应该这么调用:
例 1: %top -n -p 5 10345
例 2: %top -d -p 1 460
也就是说,选项要在前面一次性写完,然后再顺序写那些选项的参数。
%{_docdir} 文档目录
该宏用来指代默认的文档目录,也就是 /usr/share/doc/packages。可以使用 Docdir 标签来重定义它。通常它是当在 %files 章节的 %doc 标签不足以安装全部文档时用在 %install 章节安装文档的。另外,在 %files 章节中,%{_docdir} 前面不需要 %doc 标签。该目录会自动视为文档的。
下面是 aeolus 包的例子:
%install [...] mkdir -p %{buildroot}%{_docdir}/%{name} cp .aeolusrc %{buildroot}%{_docdir}/%{name}/aeolusrc cp -R stops-* %{buildroot}%{_docdir}/%{name} [...]
%files [...] %{_docdir}/%{name}
%{_infodir} 信息页面目录
该宏指代的是默认的 info 信息页面目录,/usr/share/info。它经常用于 `./configure --infodir=%{_infodir}
`,和 %install_info 宏一起使用,还有就是在文件列表里面使用。就像 %{_docdir} 一样,在 %files 章节里 %doc 标签不用和 %{_infodir} 一起用。这个文件夹也是自动视为文档的。
%{_lib}
该宏指代了 lib 或 lib64,具体替换哪个看编译环境的操作系统架构是 i586 还是 x86_64。后一个变种出现在 x86_64 上,它既支持 64 位也支持 32 位的程序。在这种系统上,同一个函数库的两个变种可以同时存在。因此,把 64 位的函数库装到 lib64 目录,32 位函数库装到传统的 lib 目录。
%{_lib} 被用于 %{_libdir} 不足以匹配的情况下,例如,当函数库应该要装到 /usr/X11R6/lib(64)/时。通常随着 `.configure --libdir=/usr/X11R6/%{_lib}
` 一起用,或者用于文件列表。
%{_libdir} 函数库目录
该宏指代了 %{_prefix}%{_lib} 目录。它和 %{_lib} 宏的功能一样,且比它常见,因为函数库经常被安装到 /usr/lib(64) 目录。和 `./configure --libdir=%{_libdir}
` 一起使用,或用于文件列表。
%{_mandir} 帮助页面目录
该宏替代了帮助手册的默认目录,/usr/share/man。它经常和 `./configure --mandir=%{_mandir}
` 一起使用,以及用于文件列表,例如:
%files %{_mandir}/*/*
和 %{_docdir} 一样,文件列表的 %{_mandir} 不需要 %doc 标签。它自动被视为文档。
%desktop_database_post / %desktop_database_postun 更新桌面 Mimetype 数据库
任何应用程序安装了一个 .desktop 桌面文件后,都需要在 %post/%postun 章节调用一次该宏。该宏会调用 update-desktop-database 命令来更新系统 MIME 缓存。
该宏只适用于 openSUSE 11.4 以后的版本。
需要 desktop-file-utils 软件包才能在编译时运行该宏(宏定义在那里面)。以 meld 为例:
BuildRequires: update-desktop-files [...] %if 0%{?suse_version} >= 1140 %post %desktop_database_post %postun %desktop_database_postun %endif [...]
另外注意该宏总是成对出现,也就是 %post 里用了,%postun 里相应也要用。
BuildRequires: desktop-file-utils
不需要显式写,因为大部分情况下你安装 .desktop 都会需要 BuildRequires: update-desktop-files
来运行 %suse_update_desktop_file,那个软件包已经依赖了 desktop-file-utils 软件包,所以会自动引入它到编译环境。%fdupes 清理冗余文件
该宏用于硬软链接您 %{buildroot} 编译安装根目录中的冗余文件。这会降低您的包的安装文件体积,在某些情况下也会降低生成的 RPM 软件包的体积。
请留心这些冗余文件不能处于不同的子软件包。另外就是这些文件也不能跨越两个硬盘分区,比如 /etc 和 /usr(有些用户的硬盘中这两个目录不处于同一分区,因此一般地, /usr/lib/%{name}/ 这样的结构,第一个 /usr/ 层级的不同,我们都会视为装到了两个不同分区上。)。
如果怕出错的话,可以使用 %fdupes -s, 这会创建更容易被 RPM 抓取的软链接。如果文件和它的软链接处在不同的子软件包中, rpmlint 会给出一个 "dangling symlink"(不稳定系统链接)错误。而不同分区的错误 rpmlint 无论怎样都会给出,错误名为 "跨分区硬链接"。
你也可以这么做:
.. BuildRequires: fdupes .. %install .. # create symlinks for man pages %fdupes -s %{buildroot}%{_mandir} # create hardlinks for the rest %fdupes
如果有冗余文件忘记了使用该宏,openSUSE 打包检查 会提示错误说该包 "文件冗余",浪费了空间。 如果没有 Buildrequires: fdupes 你会收到 "no job control" 错误。
%fillup_and_insserv 初始化启动脚本
该宏用来插入系统配置文件到 /etc/sysconfig,然后启用软件包安装的启动脚本。
命令概要:
%fillup_and_insserv
[-finyY
] [sysconfig_filename
] [init_script_name
] ...
%fillup_and_insserv 宏把两种功能捆绑到一个命令里。它用来插入配置文件到 /etc/sysconfig 文件夹,然后启动各个运行级别下的脚本服务。插入环节使用了存储在 /var/adm/fillup-templates/sysconfig_filename.%name 的模板。
该宏用在 %post</code> 章节来安装并启用软件包安装的脚本服务。更多请参考 启动脚本的『安装』部分。不要忘记在 <tt>PreReq 里写出将使用到的工具(由于该宏只用在 %post 里面,因此也可以使用 Requires(post):)。也可以用 %insserv_prereq 和%fillup_prereq 宏。
选项说明:
-
-f
跳过插入配置文件环节 -
-i
跳过启用脚本服务环节 -
-n
定义了sysconfig_filename
使用的参数。 -
-y
如果软件包是第一次安装而不是升级的话,就默认启用脚本服务。如果启动脚本中指定了X-UnitedLinux-Default-Enabled
,那么该选项自动忽略而使用指定的。 -
-Y
强制启用脚本服务。这意味着在下一次该包升级前,无论启动脚本里面的设置是怎样的,该脚本都会默认启用。
参数:
- sysconfig_filename creates a pair with the option -n and defines the filename where the configuration is filled up, /etc/sysconfig/sysconfig_filename. In addition, it defines a name of the file with templates. The macro searches for two possible template files. It prefers /var/adm/fillup-templates/sysconfig.sysconfig_filename.%name if it is available. Otherwise, it searches for /var/adm/fillup-templates/sysconfig.sysconfig_filename. The longer variant must be used if multiple packages write to the same config file. By default (that is, when the -n option is not used), the template is /var/adm/fillup-templates/sysconfig.%name and the target sysconfig file is /etc/sysconfig/%name.
- init_script_name defines a name of the init script processed by `
insserv
`. It must be defined if the -i option is not used. More init scripts names can be defined (see examples below).
Example from the mailman package:
PreReq: %insserv_prereq %fillup_prereq ... %post %{fillup_and_insserv mailman}
It fills the configuration file /etc/sysconfig/mailman from the template /var/adm/fillup-templates/sysconfig.mailman.
Example taken from the hwinfo package:
PreReq: %insserv_prereq %post %{fillup_and_insserv -f -y hwscan}
It runs `insserv
` on /etc/init.d/hwscan and enables the service by default. Note that only the insserv part is in PreReq because the fillup part is omitted, as the -f option was used.
Example from the openssh package:
%{fillup_and_insserv -n -y ssh sshd}
It fills the configuration file /etc/sysconfig/ssh. The template is taken either from /var/adm/fillup-templates/sysconfig.ssh.openssh or from /var/adm/fillup-templates/sysconfig.ssh. The first one is preferred. It runs `insserv
` on /etc/init.d/sshd and enables the service by default during a new installation.
Example from the openldap2 package:
%{fillup_and_insserv -n openldap ldap slurpd}
It fills the configuration file /etc/sysconfig/openldap. The template is taken either from /var/adm/fillup-templates/sysconfig.openldap.openldap2 or from /var/adm/fillup-templates/sysconfig.openldap. The former is preferred.
%fillup_only
This macro can be used to fill up sysconfig files.
Synopsis:
%fillup_only
[-adns
] [sysconfig_filename
] [suffix
] [sysconfig_subdir
]
The %fillup_only macro is used to insert (fill up) the variables from a template /var/adm/fillup-templates/sysconfig.sysconfig_filename[-suffix] into a config file /etc/sysconfig/sysconfig_filename. The base function is similar to %fillup_and_insserv -i, but it allows modifying config files in subdirectories of /etc/sysconfig.
The macro is typically used in the %post section. Do not forget to mention the utilities used in the PreReq tag. The macro %fillup_prereq is intended for this purpose.
Options:
-
-a
uses the package name as a suffix of the syconfig template filename. -
-d
defines that the parametersysconf_subdir
is used (see below). -
-n
defines that the parametersysconfig_filename
is used (see below). -
-s
defines that the parametersuffix
is used (see below).
Parameters:
- sysconfig_filename creates a pair with the -n option and defines the name of the sysconfig file and a name of the file with templates. By default (that is, when the -n option is not used), the package name is used instead. So the template /var/adm/fillup-templates/sysconfig.%name is filled up to /etc/sysconfig/%name.
- sysconfig_template_filename_suffix creates a pair with the -s option and defines a suffix of the filename with templates.
- sysconfig_subdir creates a pair with the -d option and defines a subdirectory of /etc/sysconfig where the synconfig file is located.
Example from the tetex package:
PreReq: %fillup_prereq %post %fillup_only
It fills up the config file /etc/sysconfig/tetex from the template /var/adm/fillup-templates/sysconfig.tetex.
Example from the man package:
%{fillup_only -an cron}
It fills the config file /etc/sysconfig/cron from the template /var/adm/fillup-templates/sysconfig.cron-man.
Example from the dhcp package:
%{fillup_only -ans syslog dhcpd}
It fills the config file /etc/sysconfig/syslog</t> from the template <tt>/var/adm/fillup-templates/sysconfig.syslog-dhcpd.
Example from the samba package:
%fillup_only -nsd dhcp samba-client network
It fills the config file /etc/sysconfig/network/dhcp from the template /var/adm/fillup-templates/sysconfig.dhcp-samba-client.
%find_lang
This macro helps to mark locale-dependent files with the respective %lang
tag in the file list.
Synopsis
%find_lang options name [filelist]
The %find_lang
macro searches the directories /usr/share/locale and locale/*/LC_MESSAGES for name.mo files. It also searches gnome/help/name and kde*/share/doc/HTML/*/name directories for a localized documentation. Then it creates the file filelist where the files are marked with the respective %lang(locale)
and %doc
tags. Such a file list can be then passed to the %files
tag via the -f
option. See below for an example.
It is recommended to use this macro only if the BuildRoot tag is defined as otherwise the entire system will be searched.
Options
- --without-gnome
- do not find GNOME help files.
- --without-kde
- do not find KDE help files.
- --with-qt
- find Qt translation files.
- --with-man
- find localized man pages.
- --all-name
- match all package/domain names.
- --without-mo
- do not find locale files.
Parameters
- name
- defines the name of .mo files and the name of sub-directories where GNOME and KDE localized documentation is stored. It is also used for the filelist where the generated file list is stored if the parameter filelist is not given.
- filelist
- defines the name of the file where the generated list of files is stored. name.lang is used if not otherwise defined.
Example from the package pan:
%install make -i DESTDIR="%buildroot" install %find_lang %name # generate a special file list %files -f %name.lang # use the special file list %defattr(-,root,root) # list the other files %doc README ChangeLog AUTHORS TODO COPYING CREDITS %attr(755,root,root) %prefix/bin/pan […]
%icon_theme_cache_post / %icon_theme_cache_postun
This macro is used to update the icon theme cache for packages which install icons into hicolor or other icon themes. It is meant to be called in %post and %postun sections and takes an option argument which is the name of the updated icon theme where hicolor is the default.
These macros are available from 11.4 on only!
FIXME: Which tag is needed as Requires(post/postun)?
%insserv_cleanup
This macro is used to run `insserv
` after a package is removed. Each package providing an init script should call this macro in the %postun section.
Example from the openldap2 package:
%postun %restart_on_update ldap slurpd %insserv_cleanup
%insserv_force_if_yast
This macro is a plain call of the `insserv
` if the package is not installed by YaST. When YaST is used, it calls `insserv -f
` instead. This helps to avoid errors on "out-of-sequence" package installations.
The macro is used in the %post script of packages that install an init script and which want to enable it by default. It is also used if the init script existed prior to SL 8.0 when the START variables were used. See openSUSE:Packaging_init_scripts#Installation, “Installation” for more details. Do not forget to mention the used utilities in the PreReq tag. There are the macros %insserv_prereq
and %fillup_prereq
for this purpose.
Example from the glibc package, nscd subpackage:
%package -n nscd PreReq: %insserv_prereq %post -n nscd %{insserv_force_if_yast nscd}
%install_info
This macro updates dir entries for info files.
Synopsis:
%install_info
install_info_options
The %install_info macro runs `bin/install-info
` with some additional tests. It accepts any option from the install-info utility. See `man install-info
` for more details.
Each package providing info pages should call this macro in the %post section. Do not forget to mention all the used utilities in the PreReq tag. The %install_info_prereq
macro exists for this purpose.
Examples:
Example from the zsh package:
PreReq: %install_info_prereq
%post %install_info --info-dir=%_infodir %_infodir/%name.info.gz
Example from the rplay package (a package with multiple info pages):
PreReq: %install_info_prereq
%post %install_info --info-dir=%_infodir %_infodir/%name.info.gz %install_info --info-dir=%_infodir %_infodir/RPLAY.info.gz %install_info --info-dir=%_infodir %_infodir/RPTP.info.gz %install_info --info-dir=%_infodir %_infodir/librplay.info.gz
%install_info_delete
This macro removes dir entries for info files.
Synopsis:
%install_info_delete
install_info_options
The macro %install_info_delete is a complement to the macro %install_info. It runs sbin/install-info --quiet –delete with some additional tests. It accepts any option from the install-info utility. See man install-info for more details.
Each package providing info pages should call this macro in %postun
script. Do not forget to mention all the utilities used in the PreReq
tag. The macro %install_info_prereq
is intended for this purpose.
Examples:
- This example is taken from the package
zsh
(also shows the relatedPreReq
tag):
PreReq: %install_info_prereq [...] %postun %install_info_delete --info-dir=%_infodir %_infodir/%name.info.gz
- This example is taken from the package
rplay
(a package with multiple info pages). The example also shows the relatedPreReq
tag):
PreReq: %install_info_prereq [...] %postun for infoname in %name RPLAY RPTP librplay; do %install_info_delete --info-dir=%_infodir %_infodir/$infoname.info.gz done
%perl_archlib
This macro is substituted by the path where architecture-specific parts of Perl are installed, for example, /usr/lib/perl5/5.8.5/i586-linux-thread-multi
.
It is normally only used by the perl
package itself and by the macro %perl_process_packlist
. See below.
%perl_gen_filelist
Generates an rpmlint happy filelist of your installed files.
In most cases you only need to check the %doc part sometimes there is a "Changes" or "ChangeLog",....
You have to define following parts inside your spec file
Example:
BuildRequires: perl-macros %install %perl_make_install %perl_process_packlist %perl_gen_filelist %files -f %{name}.files %defattr(-,root,root) %doc Changes README
And here an Example of the generated filelist:
%dir /usr/lib/perl5/vendor_perl/5.8.8/Algorithm /usr/lib/perl5/vendor_perl/5.8.8/Algorithm/DiffOld.pm /usr/lib/perl5/vendor_perl/5.8.8/Algorithm/diff.pl /usr/lib/perl5/vendor_perl/5.8.8/Algorithm/Diff.pm /usr/lib/perl5/vendor_perl/5.8.8/Algorithm/diffnew.pl /usr/lib/perl5/vendor_perl/5.8.8/Algorithm/cdiff.pl /usr/lib/perl5/vendor_perl/5.8.8/Algorithm/htmldiff.pl %dir /usr/lib/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi/auto/Algorithm %dir /usr/lib/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi/auto/Algorithm/Diff /usr/lib/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi/auto/Algorithm/Diff/.packlist /usr/share/man/man?/* /var/adm/perl-modules/perl-Algorithm-Diff
%perl_make_install
This macro does the make install call correctly on various products. Before SL 9.0, the normal way to invoke it was:
make PREFIX=$RPM_BUILD_ROOT/%_prefix \ INSTALLMAN1DIR=$RPM_BUILD_ROOT/%_mandir/man1 \ INSTALLMAN3DIR=$RPM_BUILD_ROOT/%_mandir/man3 \ install
For 9.0 and later versions:
make DESTDIR=$RPM_BUILD_ROOT install_vendor
With the macro %perl_make_install
, this is done correctly according to the version.
This example comes from the package perl-URI
:
%install %perl_make_install
%perl_process_packlist
This macro prepares some files, related to perl modules, for the final package. It does the following actions:
Each package including a perl module should call this macro in the section %install
.
for 0%{?suse_version} > 1130
- Searches for the installed
.packlist
files and removes them from$RPM_BUILD_ROOT%perl_vendorarch/auto
.
If %{_target_cpu} == noarch
then empty dirs are removed from $RPM_BUILD_ROOT%perl_vendorarch/auto
.
- Removes the
$RPM_BUILD_ROOT%perl_archlib/perllocal.pod
file.
This example is taken from the package perl-HTML-Parser
:
%install %perl_make_install %perl_process_packlist %perl_gen_filelist %files -f %{name}.files %doc Changes mkhctype mkpfunc README TODO eg %changelog
for 0%{?suse_version} <= 1130
- Removes
$RPM_BUILD_ROOT
from%perl_archlib/perllocal.pod
and renames the file to a package-specific file. See below for more details. - Searches for the installed
.packlist
files and removes$RPM_BUILD_ROOT
from them.
The file %perl_archlib/perllocal.pod
must be renamed because it contains information about additional installed perl modules and evidently cannot be installed at the same place from multiple packages. Therefore, it is renamed and a special SuSEconfig module, /sbin/conf.d/SuSEconfig.perl
, adds this information to the system %perl_archlib/perllocal.pod
after the package is installed.
This example is taken from the package perl-URI
:
%install %perl_make_install %perl_process_packlist %files [...] /var/adm/perl-modules/%name
%perl_sitearch
This macro is substituted by the path where architecture-specific parts of Perl modules are installed by a local administrator (/usr/lib/perl5/site_perl/5.8.5/i586-linux-thread-multi
). The packages distributed within SUSE Linux use the path defined by %perl_vendorarch
instead. See below.
%perl_sitelib
This macro is substituted by the path where architecture-independent parts of Perl modules are installed by a local administrator (/usr/lib/perl5/site_perl/5.8.5
). The packages distributed within SUSE Linux use the path defined by %perl_vendorlib
instead (see below).
%perl_vendorarch
This macro is substituted by the path where architecture-specific parts of Perl modules are installed by a Linux vendor (/usr/lib/perl5/vendor_perl/5.8.5/i586-linux-thread-multi
). The macro is typically used in the file list. This example comes from the package perl-URI
:
%files [...] %perl_vendorarch/auto/URI
This path has been used since SL 9.0. Until then, the Perl modules were installed below /usr/lib/perl5/site_perl
using the macro %perl_sitearch
. The directory site_perl
is now intended for modules installed by a local administrator (see above at %perl_sitearch
).
%perl_vendorlib
This macro substitutes for the path where architecture-independent parts of Perl modules are installed by a Linux vendor (/usr/lib/perl5/vendor_perl/5.8.5
). The macro is typically used in the file list. This example comes from the package perl-URI
:
%files [...] %perl_vendorlib/URI.pm %perl_vendorlib/URI
This path has been used since SL 9.0. Until then, the Perl modules were installed below /usr/lib/perl5/site_perl
using the macro %perl_sitearch
. The directory site_perl
is now intended for modules installed by a local administrator (see above at %perl_sitelib
).
%perl_version
This macro is substituted by the version of Perl used for building the package, such as 5.8.5
. It is used in packages providing a perl module to define the dependency on Perl.
It is typically used the following way. This example is taken from the package perl-URI
:
%{perl_requires}
and is expanded this way :
%perl_requires() \ %if 0%{?suse_version} > 0 && 0%{?suse_version} < 1700 \ Requires: perl = %{perl_version} \ %endif
%py_incdir
This macro substituted by the path where Python header files are installed, such as /usr/include/python2.3
. See openSUSE:Packaging_Python, “Python Modules” for an example.
%py_libdir
This macro is substituted by the path where Python modules are installed, such as /usr/lib/python2.3
. See openSUSE:Packaging_Python, “Python Modules” for an example.
%py_requires
This macro is substituted by PreReq
and BuildRequires
tags. This defines dependency on the same python major version as is used during build. See openSUSE:Packaging_Python, “Python Modules” for an example.
%py_sitedir
This macro is substituted by the path where all extra Python modules all installed, such as /usr/lib/python2.3/site-packages
. See “Python Modules” for an example.
%py_ver
This macro is substituted by the Python major version, such as 2.3
. See openSUSE:Packaging_Python, “Python Modules” for an example.
%remove_and_set
This macro is used to remove obsolete sysconfig variables.
Synopsis:
%remove_and_set [-ny
] [sysconfig_filename
] variable
...
The macro %remove_and_set removes variables from /etc/rc.config
and /etc/sysconfig/sysconfig_filename
and sets them in the actual environment for further handling. If a variable is not found, it is set to "no"
by default or it is set to “yes”
if the option -y
is used.
Options:
-
-n
defines that the parametersysconfig_filename
is used (see below). -
-y
sets the default value to“yes”.
Parameters:
-
sysconfig_filename
creates a pair with the option-n
and defines the syconfig filename. The package name (%name) is used as the sysconfig filename otherwise. -
variable
defines the name of a variable to remove. Multiple variables can be defined.
Examples:
- This example is taken from the package
postfix
:
%{fillup_and_insserv -y postfix} if [ -f etc/sysconfig/mail ]; then . etc/sysconfig/mail if [ -n "$NULLCLIENT" ]; then RCTMP="etc/sysconfig/postfix.$$" sed "s/^POSTFIX_NULLCLIENT.*/POSTFIX_NULLCLIENT=\"$ \"/" \ etc/sysconfig/postfix >"$RCTMP" mv "$RCTMP" etc/sysconfig/postfix fi fi %{remove_and_set -n mail NULLCLIENT}
This code sets the variable POSTFIX_NULLCLIENT
from etc/sysconfig/postfix
to the value of the obsolete variable NULLCLIENT
from etc/sysconfig/mail
. Then the obsolete variable is removed.
- This example is taken from the package
autofs
:
%post %{fillup_and_insserv autofs} # needed for update from 7.3 and before %{remove_and_set USE_NIS_FOR_AUTOFS USE_NISPLUS_FOR_AUTOFS} if [ $USE_NIS_FOR_AUTOFS == "yes" ] ; then if `grep "^automount:" etc/nsswitch.conf | \ grep -vqw nis` ; then sed "s/^automount:.*/& nis/" < etc/nsswitch.conf \ >etc/nsswitch.conf.new mv etc/nsswitch.conf.new etc/nsswitch.conf fi fi if [ $USE_NISPLUS_FOR_AUTOFS == "yes" ] ; then if `grep "^automount:" etc/nsswitch.conf | \ grep -vqw nisplus` ; then sed "s/^automount:.*/& nisplus/" < etc/nsswitch.conf \ > etc/nsswitch.conf mv etc/nsswitch.conf.new etc/nsswitch.conf fi fi
The obsolete variables USE_NIS_FOR_AUTOFS
, USE_NISPLUS_FOR_AUTOFS
are removed from /etc/rc_config
and /etc/sysconfig/autofs
and the removed values are used to modify an actual configuration.
The detected values cannot be used in the previous example because the macro %remove_and_set is able to set only values “yes”
or “no”
in the environment.
%restart_on_update
This macro restarts a service after an update.
Synopsis:
%restart_on_update service
...
The macro %restart_on_update runs /etc/init.d/service try-restart if not running under YaST in the instsys
mode. Multiple services can be defined.
This macro is usually used in the %postun
script of packages providing a service. However, it cannot be used if it cannot be guaranteed that the service will work after an update.
Examples:
- This example is taken from the package
rsync
:
%postun %restart_on_update rsyncd %insserv_cleanup
- This example is taken from the package
samba
(restarts two services):
%postun %restart_on_update nmb smb %insserv_cleanup
%run_ldconfig (deprecated)
This macro runs ldconfig if not running from YaST. YaST runs ldconfig itself after all selected packages are installed.
It was used in both %post
and %postun
scripts of packages providing a library. The macro is deprecated and should not be used anymore. Instead, /sbin/ldconfig should be called directly both scripts, even from YaST, to keep from breaking other %post
scripts. It could be done the following way:
%post -p /sbin/ldconfig %postun -p /sbin/ldconfig
If ldconfig is not the only command, the -p
option is not usable. For example, the %post
script could look like:
%post /sbin/ldconfig [...]
%run_permissions
This macro runs SuSEconfig --module permissions to adjust file permissions according to the system's security setting.
Note: Running SuSEconfig has the disadvantage that permissions of all installed files are adjusted, not just the ones that belong to the package. Therefore this macro is deprecated since openSUSE 11.4, use %set_permissions instead.
%run_permissions needs to be called in the %post script of packages that install files handled by /etc/permissions.*. The permissions package needs to be in PreReq so SuSEconfig.permissions is guaranteed to be available at install time.
In addition the macro %verify_permissions needs to be called as %verifyscript
Example:
PreReq: permissions [...] %post %run_permissions
%set_permissions
This macro adjusts permissions of the specified files according to the system's security setting.
Available since openSUSE 11.4
%set_permissions needs to be called in the %post script of packages that install files handled by /etc/permissions.*. The permissions package needs to be in PreReq so chkstat is guaranteed to be available at install time.
In addition the macro %verify_permissions needs to be called as %verifyscript
Example:
PreReq: permissions [...] %post %set_permissions /usr/bin/foo /bin/bar
%sles_version
This macro expands to the version of SLES where the package is built. It is ”7”
for SLES7, ”8”
for SLES8, etc. It is ”0”
when not building on SLES.
See also %suse_version
and %ul_version
.
And openSUSE:Build Service cross distribution howto#Detect_a_distribution_flavor_for_special_code
This example is taken from the package pam-modules
:
%install [...] # On UL or SLES, we have other defaults %if %sles_version >= 8 cp $RPM_SOURCE_DIR/pam_pwcheck.conf.sles \ $RPM_BUILD_ROOT/etc/security/pam_pwcheck.conf %endif
%stop_on_removal
This macro stops a service after a package is removed.
Synopsis:
%stop_on_removal service
...
The macro %stop_on_removal runs /etc/init.d/service stop if not running from YaST in the instsys mode. Multiple services can be defined.
Each package providing a service that can be stopped should call this macro on all services in the %preun
script.
Examples:
- This example is taken from the package
rsync
:
%preun %stop_on_removal rsyncd
- This example is taken from the package
samba
(stops two services):
%preun %stop_on_removal smb nmb
%suse_update_config
This macro updates some auto-stuff related files.
Usage:
%suse_update_config [-fcl
] [dir
...]
This macro takes the following actions for the current directory and all directories given as parameters:
-
config.guess
andconfig.sub
are overwritten by their most current versions from/usr/share/automake*/
. -
depcomp
andmissing
are added if not present in the processed directory but present in/usr/share/automake*/
. -
ltconfig
andltmain.sh
are patched to accept bothlinux-gnu
andlinux
. -
/lib
is replaced by/%_lib
in some occurrences in bothltconfig
andltmain.sh
.
This macro should be called in all packages using the problematic files. However, it is not needed when autoreconf or aclocal, libtoolize, automake, and autoconf is used, because they are able to update the needed things.
This macro should be tested for existence when used in the section %prep
. This allows running this section on other distributions where the macro is not available. See the examples below.
Options:
-
-c
— do not updateconfig.guess
,config.sub
,depcomp
andmissing
-
-f
— force, ignore time stamps -
-l
— do not updateltconfig
andltmain.sh
Parameters:
-
dir
defines an additional directory where the files should be updated. Multiple directories can be defined.
Examples:
- This example is taken from the package
libunicode
:
%prep %setup %patch1 %{?suse_update_config:%{suse_update_config -f}} %build CFLAGS="$RPM_OPT_FLAGS" \ ./configure --prefix=%prefix \ --libdir=%prefix/%_lib \ --sysconfdir=%sysconfdir make
- This example is taken from the package
xosview
(updates files in both./
and./config
directories):
%prep %setup -q %patch1 -p0 -b ".serial" [...] %{?suse_update_config:%{suse_update_config -f config}} %build %ifarch ppc export SYSTEM=powerpc-suse-linux %else export SYSTEM=%_target_cpu-suse-linux %endif (cd config/; autoconf; cp configure ../) ./configure $SYSTEM \ --with-x \ --enable-auto-depend \ --enable-linux-syscalls \ --prefix=/usr/X11R6 \ --disable-linux-memstat make clean
%suse_update_desktop_file
This macro updates .desktop files.
Synopsis:
%suse_update_desktop_file -c
filename
name
comment
exec
icon
[category
]...
%suse_update_desktop_file [-inru
] [-D
docpath
] [-N
name
] [-G
genericname
] filename
[category
]...
The macro %suse_update_desktop_file updates translations, adds categories (needed to sort menus), and does some sanity checks in the given .desktop file. It requires the package update-desktop-files
.
Each package providing a .desktop file should call this macro for all basenames of .desktop files (without .desktop suffix) in the section %install
after the desktop-files have been installed under /usr/share/applications
or /etc/xdg/autostart
. Do not forget to mention the package update-desktop-files
in the BuildRequires tag. It is included in the meta packages:
-
gnome2-devel-packages
-
gtk2-devel-packages
-
kde3-devel-packages
-
qt3-devel-packages
-
yast2-core-devel-packages
-
yast2-devel-packages
The package update-desktop-files
need not be explicitly mentioned in the BuildRequires tag
if any of these meta packages is already there.
Options:
-
-c
filename
name
comment
exec
icon
[category
] — Create a new .desktop file initialized by the parametersfilename
,name
,comment
,exec
,icon
, andcategory
the following way:
[Desktop Entry] Name=name GenericName=comment Type=Application Exec=exec Icon=icon Categories=category;....
and install it as $RPM_BUILD_ROOT/usr/share/applications/filename.desktop
.
-
-i
— Search$RPM_SOURCE_DIR
and/usr/share/update-desktop-files/templates
for the templatefilename.desktop
and install it as$RPM_BUILD_ROOT/usr/share/applications/filename.desktop
. -
-n
— Do not update translations. It is useful if the linesName=
andGenericName=
contain a string that cannot be translated. -
-r
— Replace categories defined in the .desktop file with the new one defined by the parameter category. By default, the new categories are only added after the already included categories. -
-u
— Add the lineX-SuSE-Unimportant=true
to the .desktop file. -
-D
docpath
Sets the .desktop file DocPath entry. -
-N
name
Sets the .desktop file Name entry. -
-G
genericname
Sets the .desktop file GenericName entry.
Parameters:
-
filename
defines a filename of the .desktop file. The value is the filename without the suffix.desktop
. -
category
is used to add or modify the lineCategories=
in the .desktop file. This line is used to sort entries into submenus.
Examples:
- This example is taken from the package
kvim
(also shows the related parts ofBuildRequires
tag and%files
section):
BuildRequires: ... update-desktop-files ... %install [...] %suse_update_desktop_file KVim TextEditor %files [...] /opt/kde3/share/applnk/*/*.desktop
This code updates translations in the already installed /opt/kde3/share/applnk/Editors/KVim.desktop
. As the original .desktop file does not contain the line Categories=
, it is initialized to Categories=TextEditor;
.
- This example is from the package
crack-atack
: (also shows the related parts ofBuildRequires
tag,Source
tags and%files
section):
BuildRequires: ... update-desktop-files ... Source1: %name.desktop Source2: %name-xtreme.desktop [...] %install [...] %suse_update_desktop_file -i %name Game ArcadeGame %suse_update_desktop_file -i %name-xtreme Game ArcadeGame %files [...] /usr/share/applications/%name.desktop /usr/share/applications/%name-xtreme.desktop
This code finds the two templates in $RPM_SOURCE_DIR
and installs them into /usr/share/applications
. See the section %files
for the final path. It also updates translations. As the templates do not contain the line Categories=
, it is initialized to Categories=Game;ArcadeGame;
.
- This example is taken from the package
koffice
:
%install [...] %suse_update_desktop_file kugar Office Viewer %suse_update_desktop_file -r karbon Graphics VectorGraphics %suse_update_desktop_file kivio Office FlowChart %suse_update_desktop_file kpresenter Office Presentation %suse_update_desktop_file kchart Office FlowChart %suse_update_desktop_file kspread Office Spreadsheet %suse_update_desktop_file -u KThesaurus Office %suse_update_desktop_file -u kformula Office %suse_update_desktop_file kword Office WordProcessor %suse_update_desktop_file -u koshell Office Core-Office
This code updates translations in the already installed desktop files. In addition, for example, Kthesaurus.desktop
is marked as unimportant and the obsolete line Categories=
is replaced with Categories=VectorGraphics;
in karbon.dekstop
.
- This example is taken from the package
qbrew
:
%suse_update_desktop_file -c qbrew QBrew \ "A homebrewer's recipe calculator" \ qbrew "" Science
- This code creates a .desktop file:
[Desktop Entry] Name=QBrew GenericName=A homebrewer's recipe calculator Type=Application Exec=qbrew Icon= Categories=Science;
Then it adds available translations and installs it as /usr/share/applications/qbrew.desktop
.
Know issues
- The setting
Categories=Application;Office;
is typical for Fedora packages, but yields to build failures in SUSE. The error message says No sufficient Category definition. You need to use the '-r' flag to remove the offending category 'Application' abd replace it by only allowed categories. The -r option must come before the name to be effective.
%suse_update_desktop_file -u -r -G 'OCR Suite' %{name} Office Graphics Scanning OCR
If this command leads to an error message /var/tmp/rpm-tmp.mkeCpx: line 54: fg: no job control please try adding
BuildRequires: update-desktop-files
- The setting
Version=0.5
is typical for Fedora packages, but yields a warning with SUSE. Manual patching is required to resolve this warning.
%suse_version
This macro expands to the version of SUSE Linux / openSUSE where the package is built. It is "1000" for SUSE Linux 10.0, "1020" for openSUSE 10.2 and so on.
See also %sles_version
and %ul_version
.
And openSUSE:Build Service cross distribution howto#Detect_a_distribution_flavor_for_special_code
It can be used to used for version check
.. %if 0%{?suse_version} > 1100 BuildRequires: new-package-introduced-in-11.0 %endif ..
Or to check if the package was build for openSUSE
.. %if 0%{?suse_version} BuildRequires: libqt4-devel %else BuildRequires: qt4-devel %endif ...
%tcl_version
This macro expands to the version of Tcl used on the product where the package is built. It is "8.3"
for tcl-8.3, “8.4”
for tcl-8.4, etc.
This example is taken from the package vkeybd
:
%build make PREFIX=%_prefix \ TCL_VERSION=%tcl_version \ XLIB="-L/usr/X11R6/lib64 -L/usr/X11R6/lib -lX11" \ USE_LADCCA=1
%ul_version
This macro expands to a version of United Linux where the package is built. It is “1”
for UL 1.0 and “0”
when not building on UL.
See also %sles_version
and %suse_version
.
This example is taken from the package installation-images
:
%build [...] %ifarch %ix86 themes="SuSE Home" %else themes=SuSE %endif %if %ul_version > 0 themes=UnitedLinux %else %if %sles_version > 0 themes="SuSE-SLES" %endif
%verify_permissions
This macro verifies permissions of files handled via /etc/permissions.* according to the system's security settings.
Permissions attributes in the package should reflect the setting of the secure level (/etc/permissions.secure).
To prevent rpm from complaining about the packaged permission settings affected files need to be tagged accordingly with e.g. %verify(not mode).
Usage:
%verify_permissions [-f
filelist
] [-e
file
] ...
%verify_permissions needs to be used together with %run_permissions or %set_permissions
Options:
-
-e
file — specifies which file to check -
-f
filelist — specifies a file with a list of files to check (useful if there are many).
Both options can be repeated.
Example 1, files with variable mode:
%verifyscript %verify_permissions -e /usr/bin/foo -e /bin/bar [...] %files %defattr(-, root, root) %verify(not mode) %attr(0755,root,root) /usr/bin/foo %verify(not mode) %attr(0755,root,root) /bin/bar
Example 2, file with variable mode and user:
%verifyscript %verify_permissions -e /etc/foo [...] %files %defattr(-,root,root) %verify(not mode user) %attr(0600,joe,root) /etc/foo
Example 3, file with support for fscaps or setuid
%verifyscript %verify_permissions -e /bin/foo [...] %files %defattr(-,root,root) %verify(not mode caps) %attr(4755,root,root) /bin/foo