openSUSE:Packaging Conventions RPM Macros

Jump to: navigation, search

Syntax

Icon-warning.png
Warning: The validity of the claims in this subsection are uncertain. It is actually possible to mix options with parameters, as is commonly done in, for example, %kernel_module_package -p preamble -x xen xenpae.

This section describes predefined RPM macros used in the SUSE packages. Some of them are generic RPM macros. Some are SUSE-specific macros. For other existing generic macros, other documentation should be consulted, such as Maximum RPM or Macro syntax.

If you are interested in specific set of macros, please see the following links:

If you wish to perform advanced rpm macro programming, rpm has built in support for the Lua programming language

You can find all the predefined macros in the /usr/lib/rpm/macros and suse_macros files with some explanation. Additional package specific macros are added by files in /usr/lib/rpm/macros.d, the directory /etc/rpm is for per-system adjustements done by the system administrator. If you place the macro %dump in your spec file and use `rpmbuild -bp specfile`, it will cause a dump of all the macros available on your system. It is however easier to just execute `rpm --showrc`.

One important difference between RPM macros and normal Linux commands is how the options and parameters are defined. RPM provides only a simple support for processing options. One limitation is that all options must be defined before parameters and it is not possible to simply use pairs created from an option and a related value. For example, the Linux command top uses the following synopsis:

top [-bcisS] [-ddelay] [-niterations] [-ppid] [, pid ...]

The used pairs -ddelay, -niterations, -ppid and all the parameters are optional. The option before a parameter defines which parameter is really used on the command line. This makes it possible to call:

Example 1: top -n 20 -p 10345

Example 2: top -d 1 -p 10345

and the command knows that 20 is a number of iterations, 1 is a delay and 10345 is a PID.

Due to the limitation in RPM, the synopsis of a related RPM macro would look like:

%top [-bcisSdnp] [delay] [iterations] [pid] [,pid ...]

All the options must be defined before parameters and the option again defines which parameter is really used. This means that the related call of the potential RPM macro of the examples above would be:

Example 1: %top -n -p 5 10345

Example 2: %top -d -p 1 460

%_docdir

This macro is substituted with the default directory for documentation, /usr/share/doc/packages. It may be redefined by the Docdir tag. Usually, it is used to install a documentation in the %install section if it is not sufficient to do it in the %files with the %doc tag. Furthermore, the %doc tag need not be used together with %_docdir in the %files section. It is done automatically for this directory.

This example is taken from the aeolus package:

%install
[...]
mkdir -p "%buildroot/%_docdir/%name"
cp -a .aeolusrc "%buildroot/%_docdir/%name/aeolusrc"
cp -Ra stops-* "%buildroot/%_docdir/%name"
[...]
%files
[...]
%_docdir/%name

%_infodir

This macro is substituted with the default directory for info pages, /usr/share/info. It is often used with `./configure --infodir="%_infodir"`, with the the %install_info macro, and in the file list. As with %_docdir, the tag %doc need not be used together with %_infodir in the %files section. It is done automatically for this directory.

%_lib

This macro substitutes with either lib or lib64, as appropriate. The second variant appears on 64-bit architectures which support running both 64-bit and 32-bit programs in parallel (biarch systems). On such systems, two variants of the same libraries must coexist. Therefore, the 64-bit libraries are installed in lib64 directories and 32-bit libraries in the traditional lib directories.

%_lib itself is used when the macro %_libdir is not sufficient, for example, when libraries are supposed to go into /usr/X11R6/%_lib. It is often used with `./configure -–libdir="/usr/X11R6/%_lib"` and in the file list.

%_libdir

This macro is substituted with %_prefix/%_lib. It has the same function as %_lib and is used even more often than it, because the libraries usually are installed into /usr/lib(64). Used with `./configure --libdir="%_libdir"` and in the file list.

%_libexecdir

Unlike %_libdir, this macro always returns the path %_prefix/libexec.

openSUSE follows Filesystem Hierarchy Standard. FHS 3.0 and later versions includes a provision for libexecdir being /usr/libexec

However, older versions of the Filesystem Hierarchy Standard before 3.0 do not include any provision for libexecdir, so versions of openSUSE (Tumbleweed before 2020-08-25, Leap before 16.0) still expand %_libexecdir to /usr/lib

%_mandir

This macro is substituted with the default directory for manual pages, /usr/share/man. It is often used with `./configure --mandir="%_mandir"` and in the %files section, such as in

%files
%_mandir/*/*

As with %_docdir, the %doc tag need not be used together with %_mandir in the %files section. It is done automatically for this directory.

%_rundir

This macro is substituted with the default directory for volatile runtime data which is by default /run. The macro was introduced April 2014. For older distribution you may want to add the following snippet:

 %if ! %{defined _rundir}
 %define _rundir %{_localstatedir}/run
 %endif

%_fillupdir

This macro is substituted with the default directory for the templates used by %fillup_only and %fillup_and_insserv macros. The macro was introduced in November 2017 as part of the migration of this data from /var/adm/fillup-templates to /usr/share/fillup-templates. For older distributions you may want to add the following snippet to continue to use the old path:

 %if ! %{defined _fillupdir}
 %define _fillupdir /var/adm/fillup-templates
 %endif

%desktop_database_post / %desktop_database_postun (deprecated)

These macros need to be called for every application which installs a .desktop file. This will update the system media type cache by calling update-desktop-database.

Icon-warning.png
Warning: Most packagers forget to do this! This can lead to hard-to-debug bugs, for example after installing your application, GNOME Shell/GDM missing all its panel icons. So normally these macros need to run after you install .desktop files in the package.
These macros are relevant for openSUSE Leap 42.3 and older. They are not necessary for newer releases, including Tumbleweed, as they use RPM's file triggers to handle such updates.

It requires desktop-file-utils package both at build time as well as run time. Example from meld package:

...
BuildRequires:  update-desktop-files
Requires(post): update-desktop-files
Requires(postun): update-desktop-files

...

%if 0%{?suse_version} < 1330
%post
%desktop_database_post
%endif

%if 0%{?suse_version} < 1330
%postun
%desktop_database_postun
%endif
BuildRequires: desktop-file-utils is not needed if BuildRequires: update-desktop-files is already added to the specfile preamble, as the latter already requires desktop-file-utils package.

%define

This macro is used to define custom macros inside a specific spec file. Use this as a placeholder for recurring words like a custom name for the package

 %define custom_version 12.6_64
 ..
 %setup -qn %name-%custom_version

%fdupes

Duplicate files waste space in the installed system. The %fdupes macro can be used to replace duplicate files by hard links or soft links. There is a RPMLint check that will give a warning for the package if it is wasting a considerable amount of space with duplicate files. In that case, you should use %fdupes.

To use %fdupes, you must include BuildRequires: fdupes in the spec file. Failing to do so can elicit a "no job control" error, because the "%fdupes" stays unexpanded and the shell treats '%' for job control, resulting in the error.

fdupes does not apply to files to relative paths in the %files section (e.g. %doc README.md), because the processing of %doc-with-relative-paths happens after the %install scriptlet has already completed.

Please be careful that these duplicated files do not end up in different subpackages; we have not tried yet what rpm does in the hardlink case. If in doubt, you can use %fdupes -s, which will create symlinks that are easier to grasp for rpm and rpmlint will give a "dangling symlink" error if the file and link ended up in different packages.

Here is an example, combining both symbolic and hard links:

 ..
 # define %fdupes
 BuildRequires:  fdupes
 ..
 %install
 ..
 # create symlinks for man pages
 %fdupes -s %{buildroot}/%{_mandir}
 # create hardlinks for the rest
 %fdupes %{buildroot}/%{_prefix}

fdupes must NOT be used on (%buildroot)/etc and /var when creating hardlinks. All files in /etc are meant to be readily editable, and the presence of hardlinks leads to unexpected behavior, as some editing programs may modify files in-place, and others may recreate the file.

%fdupes is generally safe for use on /bin, /lib*, /usr (= %_prefix) and /sbin. Do note however that files with same content but different ownership, when hardlinked, will get the ownership of any of its content siblings.

%fillup_and_insserv

This macro can be used to fill up sysconfig files and insserv init scripts.

Synopsis:

%fillup_and_insserv [-finyY] [sysconfig_filename] [init_script_name] ...

The %fillup_and_insserv macro combines two functions in one command. It is used to insert (fill up) config files in /etc/sysconfig and to enable (insserv) services in runlevels. The fillup part assumes a template stored in /usr/share/fillup-templates/sysconfig_filename.%name (before Nov 2017 this was /var/adm/fillup-templates)

The macro is used in the %post section of packages that install an init script and want to enable it by default. See “Installation” for more details. Do not forget to mention the used utilities used in the PreReq. The %insserv_prereq and %fillup_prereq serve this purpose.

(Actually, since insserv/fillup is only called in %post, should Requires(post) not be more appropriate than PreReq?)

Options:

  • -f skips the fillup part.
  • -i skips the insserv part.
  • -n defines that the parameter sysconfig_filename is used (see below).
  • -y causes enabling the init-script by default if the package is installed for the first time (not during an update). It is ignored if X-UnitedLinux-Default-Enabled is specified in the init script.
  • -Y forcefully enables the service. This means the service is always activated regardless of the setting before an update.

Parameters:

  • 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 /usr/share/fillup-templates/sysconfig.sysconfig_filename.%name if it is available. Otherwise, it searches for /usr/share/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 /usr/share/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:

Requires(post): %insserv_prereq  %fillup_prereq ...

%post
%{fillup_and_insserv mailman}

It fills the configuration file /etc/sysconfig/mailman from the template /usr/share/fillup-templates/sysconfig.mailman.

Example taken from the hwinfo package:

Requires(post): %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 /usr/share/fillup-templates/sysconfig.ssh.openssh or from /usr/share/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 /usr/share/fillup-templates/sysconfig.openldap.openldap2 or from /usr/share/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 /usr/share/fillup-templates/sysconfig.sysconfig_filename[-suffix] into a config file /etc/sysconfig/sysconfig_filename. (before Nov 2017 the template location was /var/adm/fillup-templates)

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 parameter sysconf_subdir is used (see below).
  • -n defines that the parameter sysconfig_filename is used (see below).
  • -s defines that the parameter suffix 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 /usr/share/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:

Requires(post): %fillup_prereq

%post
%fillup_only

It fills up the config file /etc/sysconfig/tetex from the template /usr/share/fillup-templates/sysconfig.tetex.

Example from the man package:

%{fillup_only -an cron}

It fills the config file /etc/sysconfig/cron from the template /usr/share/fillup-templates/sysconfig.cron-man.

Example from the dhcp package:

%{fillup_only -ans syslog dhcpd}

It fills the config file /etc/sysconfig/syslog from the template /usr/share/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 /usr/share/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 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. The use of BuildRoot tag is deprecated.

%find_lang should be used in the %install section.

Example usage

%install
# installation
%find_lang %{name}
 
%files
# list of files
 
%files -f %{name}.lang
 
%changelog

If the translations size is meaningful, install them under a %{name}-lang subpackage, with the help of %{lang_package} (for more information, visit Locale files):

%description
...

%lang_package

%prep
%autosetup -p1

%install
# installation
%find_lang %{name} %{?no_lang_C}
 
%files
# list of files
 
%files lang -f %{name}.lang
 
%changelog

Options

--without-C
do not find English translation files.
--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_install

# %find_lang %{name}: Generate a special file list
# (the macro can be used for different file names again).
#
# %{?no_lang_C}: Passes --without-C (should ensure Posix C
# localization doesn't end up in the lang subpackage's filelist).

%find_lang %{name} %{?no_lang_C}

%fdupes %{buildroot}/%{_prefix}

%files
%license COPYING COPYING-DOCS
%doc AUTHORS NEWS README.org
%doc %{_datadir}/help/C/%{name}/
%{_mandir}/man?/pan.?%{ext_man}
%{_bindir}/%{name}
[…]

# -f %{name}.lang: Use the special file list
# (add more "-f" for each special file list).
%files lang -f %{name}.lang

%changelog

%gtk3_immodule_requires / %gtk3_immodule_post / %gtk3_immodule_post (deprecated)

Icon-warning.png
Warning: These macros have been deprecated in favor of RPM's file triggers.

These macros used to provide easy Gtk3's Input Method module cache update. They were meant to be called in %post and %postun directives, and required the gtk3-tools package as Requires(post/postun).

%icon_theme_cache_post / %icon_theme_cache_postun (deprecated)

Icon-warning.png
Warning: These macros have been deprecated in favor of RPM's file triggers.

This macro was used to update the icon theme cache for packages which installed icons into Hicolor or other icon themes. It was meant to be called in %post and %postun sections and it would take an option argument which was the name of the updated icon theme where Hicolor was the default.

It required the hicolor-icon-theme package as BuildRequires and gtk3-tools as Requires(post/postun). Example: see %desktop_database_post / %desktop_database_postun.

%lang_package

This macro is used to create a template for a lang subpackage.

It accepts two optional parameters:

  • name (-n): Alternative name for lang subpackage.
  • requires (-r): Additional lang subpackage dependencies.

Example from the k3b package:

...
%package devel
...
%description devel
This package contain files needed for development with k3b.

%lang_package

%prep
%autosetup -p1
...

This will create a k3b-lang subpackage. No need to add a Recommends tag to the main package, the macro contains a Supplements tag with the same effect.

%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

Icon-warning.png
Warning: SysV-style Initscripts are either deprecated or not supported in all currently maintained openSUSE releases. This section is left as reference documentation for use on old releases.

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 (deprecated)

Icon-warning.png
Warning: deprecated since 11/2019 boo#1152105

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:

Requires(post): %install_info_prereq
Requires(preun): %install_info_prereq
%post
%install_info --info-dir=%_infodir %_infodir/%name.info.gz

Example from the rplay package (a package with multiple info pages):

Requires(post): %install_info_prereq
Requires(preun): %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 (deprecated)

Icon-warning.png
Warning: deprecated since 11/2019 boo#1152105

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 %preun 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:

  1. This example is taken from the package zsh (also shows the related PreReq tag):
Requires(post): %install_info_prereq
Requires(preun): %install_info_prereq
[...]
%preun
%install_info_delete --info-dir=%_infodir %_infodir/%name.info.gz
  1. This example is taken from the package rplay (a package with multiple info pages). The example also shows the related PreReq tag):
Requires(post): %install_info_prereq
Requires(preun): %install_info_prereq
[...]
%preun
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:

%install
%perl_make_install
%perl_process_packlist
%perl_gen_filelist

%files -f %{name}.files
%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="%buildroot/%_prefix" \
INSTALLMAN1DIR="%buildroot/%_mandir/man1" \
INSTALLMAN3DIR="%buildroot/%_mandir/man3" \
install

For 9.0 and later versions:

make DESTDIR="%buildroot" 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} >= 1140

  • Searches for the installed .packlist files and removes them from %buildroot/%perl_vendorarch/auto.

If %_target_cpu == noarch then empty directories are removed from %buildroot/%perl_vendorarch/auto.

  • Removes the %buildroot/%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 %buildroot 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 %buildroot 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

Python 2 macros (obsolete)

The following macros are only valid for Python 2, which has been removed in Tumbleweed. See openSUSE:Packaging_Python for macros working with newer Python versions.

%py_incdir

This macro is substituted by the path where Python headers are installed, such as /usr/include/python2.7.

%py_libdir

This macro is substituted by the path where Python modules are installed, such as /usr/lib/python2.7.

%py_sitedir

This macro is substituted by the path where all extra Python modules all installed, such as /usr/lib/python2.7/site-packages.

%py_ver

This macro is substituted by the Python major.minor version, such as 2.7.

%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 parameter sysconfig_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:

  1. 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.

  1. 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 systemctl 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:

  1. This example is taken from the package rsync:
%postun
%restart_on_update rsyncd
%insserv_cleanup
  1. 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
[...]

(Keep in mind that RPM will interpret "[...]" to include any comments, which might be a surprise if they were intended for the next section of the spec file!)

%run_permissions (deprecated)

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

%service_add_pre

Needs to be called in %pre section of packages that install systemd service. Pass the list of service files as parameters. See also Systemd Macros

 BuildRequires: systemd-rpm-macros
 %pre
 %service_add_pre demo.service demo1.service

%service_add_post

Needs to be called in %post section of packages that install systemd service. Pass the list of service files as parameters. See also Systemd Macros

 BuildRequires: systemd-rpm-macros
 %post
 %service_add_post demo.service demo1.service

%service_del_preun

Needs to be called in %preun section of packages that install systemd service. Pass the list of service files as parameters. See also Systemd Macros

 BuildRequires: systemd-rpm-macros
 %preun
 %service_del_preun demo.service

%service_del_postun

Needs to be called in %postun section of packages that install systemd service. Pass the list of service files as parameters. See also Systemd Macros

 BuildRequires: systemd-rpm-macros
 %postun
 %service_del_postun demo.service

%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. The parameter is the name of the permissions config file of the package (usually identical to the package name).

In addition the macro %verify_permissions needs to be called as %verifyscript

Example:

PreReq:       permissions
[...]
%post
%set_permissions /bin/ping

%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 %_sourcedir/pam_pwcheck.conf.sles \
    %buildroot/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:

  1. This example is taken from the package rsync:
%preun
%stop_on_removal rsyncd
  1. This example is taken from the package samba (stops two services):
%preun
%stop_on_removal smb nmb

%{?suse_build_hwcaps_libs}

This macro enables on supported distributions and architectures the automatic build of a glibc hwcaps optimized shared library. For that the package needs to be following Shared Library Policy and carry a `baselibs.conf` that identifies the shared libraries that should be built as an optimized overlay. the existing baselibs.conf mechanics will automatically repackage the optimized library and debuginfo packages into a baselibs package that can be installed optionally on systems to utilize the speedups.


Usage:

%{?suse_build_hwcaps_libs}

The definition of this macro needs to come from the underlying distribution. It typically expands to something like this on x86_64:

%suse_build_hwcaps_libs \
#!BuildTarget: x86_64_v3-linux,x86_64-linux \
#!BuildConstraint: hardware:cpu:flag x86-64-v3 \
%{nil}

Which is adding extra comments into the .spec file. these comments are respected by the Open Build Service to automatically set specific build targets and schedule the job on workers which match the intended buildconstraint.

When a baselibs.conf exists, the resulting baselibs will be repackaged into the main architecture and provided as an additional build result. any other package results from the additional build targets will get discarded.

%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 and config.sub are overwritten by their most current versions from /usr/share/automake*/.
  • depcomp and missing are added if not present in the processed directory but present in /usr/share/automake*/.
  • ltconfig and ltmain.sh are patched to accept both linux-gnu and linux.
  • /lib is replaced by /%_lib in some occurrences in both ltconfig and ltmain.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 update config.guess, config.sub, depcomp and missing
  • -f — force, ignore time stamps
  • -l — do not update ltconfig and ltmain.sh

Parameters:

  • dir defines an additional directory where the files should be updated. Multiple directories can be defined.

Examples:

  1. This example is taken from the package libunicode:
%prep
%setup
%patch -P 1 -p1

%build
%{?suse_update_config:%{suse_update_config -f}}
%configure
make %{?_smp_mflags}
  1. This example is taken from the package xosview (updates files in both ./ and ./config directories):
%prep
%setup -q
%patch -P 1 -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 -cfilenamenamegeneric-nameexecicon [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

Options:

  • -cfilenamenamecommentexecicon [category] — Create a new .desktop file initialized by the parameters filename, name, comment, exec, icon, and category the following way:
[Desktop Entry]
Name=name
GenericName=comment
Type=Application
Exec=exec
Icon=icon
Categories=category;....

and install it as %buildroot/usr/share/applications/filename.desktop.

  • -i — Search %_sourcedir and /usr/share/update-desktop-files/templates for the template filename.desktop and install it as %buildroot/usr/share/applications/filename.desktop.
  • -n — Do not update translations. It is useful if the lines Name= and GenericName= 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 line X-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 line Categories= in the .desktop file. This line is used to sort entries into submenus.

Examples:

  1. This example is taken from the package kvim (also shows the related parts of BuildRequires 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;.

  1. This example is from the package crack-atack: (also shows the related parts of BuildRequires 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 %_sourcedir 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;.

  1. 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.

  1. This example is taken from the package qbrew:
%suse_update_desktop_file -c qbrew QBrew \
"A homebrewer's recipe calculator" \
qbrew "" Science
  1. 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.

Known issues

  1. 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' and 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
  1. 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} >= 1110
 BuildRequires: new-package-introduced-in-11.0
 %endif
 ..

Or to check if the package is being built 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 [-ffilelist] [-efile] ...

%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
%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
%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
%verify(not mode caps) %attr(4755,root,root) /bin/foo

%create_subdir_filelist / %create_exclude_filelist

%create_subdir_filelist macro helps to create sub-packages by looking at what's installed from a specified sub-directory (and a matching doc/ directory) of the source. It requires a parameter -d <directory> and creates a file list called filelists/<directory> unless a parameter -f <filelistname> is given which then let it appends to filelists/<filelistname>. If a -v <develfilelistname> parameter is given, development files like headers, cmake definitions and .so symlinks will be written to filelists/<develfilelistname> instead.

%create_exclude_filelist creates an exclude file list from all file lists that were created by %create_subdir_filelist. It is intended to be used for the main package, to ensure that files that were moved into a subpackage are not packaged twice.

Usage in koffice2.spec (shortened):

..
%install
cd build
%make_install
%create_subdir_filelist -d kplato -v devel
%create_subdir_filelist -d kword -v devel
%create_subdir_filelist -d filters/kword -f kword -v devel
..
cd ..
sed -ri s,.*/usr/share/doc/kde/HTML/en/.*,, filelists/*
%create_exclude_filelist
rm -rf $RPM_BUILD_ROOT/usr/share/doc/kde/HTML/en
..
%files devel -f filelists/devel
..
%files kplato -f filelists/kplato
..
%files kword -f filelists/kword
..
%files -f filelists/exclude

This example also shows how it's optionally possible to merge/change the automatically created file lists.

%make_jobs (deprecated)

This macro has been deprecated, please use %cmake_build instead.

%glib2_gsettings_schema (deprecated)

Macros described in this paragraph are relevant only for openSUSE Leap 42.3 and older. Newer releases, including Tumbleweed, do not need these macros. They use RPM's file triggers instead.

Some applications might add configuration files to %{_datadir}/glib-2.0/schemas/. You need to not ship them in compiled form, but rather compile after installation and uninstallation. If the Makefile has no switch you need to manually remove them: rm %{buildroot}%{_datadir}/glib-2.0/schemas/gschemas.compiled.

Put

%glib2_gsettings_schema_requires

near the BuildRequires: section and

%post
%glib2_gsettings_schema_post

%postun
%glib2_gsettings_schema_postun

below %install