From Fedora Project Wiki

(Added section about epel-rpm-macros magic. Removed a bunch of stuff now provided by epel-rpm-macros.)
(37 intermediate revisions by 8 users not shown)
Line 3: Line 3:
As a reminder, these guidelines only apply to EPEL packages, not to Fedora packages.
As a reminder, these guidelines only apply to EPEL packages, not to Fedora packages.


== Previously required boilerplate ==
The epel-rpm-macros package sets defaults for some items and provides other macros which were previously required to be included or manually defined in EPEL6 and/or EPEL5.  While these macros were tested with all existing EPEL package, some of them are provided through the use of RPM macro trickery and can have side effects in some cases.  The items which are provided:
{|
! Item !! Was required in !! Info
|-
| <code>Buildroot:</code> || EPEL5 || Set to the buildroot Fedora uses if not specified.
|-
| <code>Group:</code> || EPEL5 || Is set to "Unspecified" if not provided.  Works for subpackages, too.
|-
| <code>%license</code> || EPEL5, EPEL6 || Maps to <code>%doc</code>.  Previously required manual definition.  Is '''not''' defined if the SCL macros package is present on the system.
|-
| <code>%install</code> buildroot cleaning || EPEL5 || <code>rm -rf %buildroot</code> will always be inserted at the beginning of %install regardless of whether it is already present.
|-
| <code>%clean</code> || EPEL5 || A <code>%clean</code> section is always provided.  If one is already included in the spec, it will be ignored but it must not be the first section after <code>%description</code> (which is not the normal place for the section in any case).  If it is located there, its contents may be appended to the <code>%description</code> instead.
|}
{{Anchor|LimitedArchPackages}}
== Limited Arch Packages ==
== Limited Arch Packages ==


When RHEL ships a package for only a subset of available arches, it's possibly for EPEL to ship that '''same''' package in order to satisfy dependencies in the other arches in EPEL. In order to do this:
Red Hat Enterprise Linux does not ship the same packages for all of its available architectures. For EPEL-7, it is allowed for EPEL to ship a package which was the '''same''' as what was in RHEL but built with changes listed below.  


# Make sure the package is not shipped for all architectures. The valid architectures are:  
# Make sure the package is not shipped for all architectures. The valid architectures are:  
#* EPEL5: i386, ppc, x86_64
#* EPEL7: ppc64le, x86_64.
#* EPEL6: i686, ppc64, x86_64
#* EPEL8: Because we have had problems with these packages causing either build, compose, or user problems, we are not allowing this for EPEL8.
#* EPEL7: ppc64, ppc64le, x86_64.
# Make sure the package meets the Fedora licensing and distribution rules. Nothing non-free or under an unacceptable license.  
# Make sure the package meets the Fedora licensing and distribution rules. Nothing non-free or under an unacceptable license.  
# Notify the epel-devel list of your intention to add this package.  
# Notify the epel-devel list of your intention to add this package.  
# Change the release of the package to have a leading 0. EXAMPLE: RHEL has foobar-1.0-1, you change it to foobar-1.0-0.1 for EPEL.
# Change the release of the package to have a leading 0. EXAMPLE: RHEL has foobar-1.0-1, you change it to foobar-1.0-0.1 for EPEL.
# Add a Changelog entry that the package was added to EPEL and has a 0 leading version to keep it older than RHEL.  
# Add a Changelog entry that the package was added to EPEL and has a 0 leading version to keep it older than RHEL.  
# Submit a [[Package SCM admin requests|Package SCM admin request]] asking for the el5, el6 or epel7 branch you need.  
# Request the branch you need (epel7) using <code>fedpkg request-branch</code>.
# Import and build your package, submit as update.  
# Import and build your package, submit as update.  
# Watch the RHEL version of the package. When it updates, you should update the EPEL version too. You should never update other than that.  
# Watch the RHEL version of the package. When it updates, you should update the EPEL version too. You should never update other than that.  
Line 41: Line 20:
NOTE: Do '''not''' add ExclusiveArch tags, this will break building on the other architectures!
NOTE: Do '''not''' add ExclusiveArch tags, this will break building on the other architectures!


== EPEL 6 and earlier ==
== EPEL 8 ==


=== Provides and Requires Filtering ===
=== Scriptlets ===


{{admon/caution|EPEL ONLY|These filtering mechanisms are considered deprecated in Fedora packages and must not be used there.}}
Fedora has been moving towards the use of file triggers and away from requiring that packagers cut and paste scriptlets into loads of packages.  At the time of this writing, we are trying to backport all of these to EPEL8, so that fedora packages are easily able to build on EPEL8 without any changes.  When EPEL 8 becomes old enough, that these backports are not feasible and/or wanted, we will list them here.


==== Generic Filtering on EPEL6 ====
== EPEL 7 ==


On EPEL6, the version of rpm is too old to support the Fedora methods of filtering Provides and Requires.  Please the older guidelines instead: [[EPEL:Packaging_Autoprovides_and_Requires_Filtering]]
=== Rich Dependencies ===


==== Perl Provides and Requires on EPEL5 and older ====
RHEL 7's rpm and yum versions do not support rich or boolean dependencies, so these are not allowed in EPEL 7.


Unfortunately, the modern macros for Provides and Requires Filtering ([[Packaging:AutoProvidesAndRequiresFiltering]]) do not work for EPEL 5 or older. There are two mechanisms for filtering Perl Provides and Requires in EPEL, either In %prep or via External scripts.
=== Scriptlets ===


==== In %prep (preferred) ====
Fedora has been moving towards the use of file triggers and away from requiring that packagers cut and paste scriptlets into loads of packages.  These scriptlets would still be needed for EPEL, and as scriptlets are no longer needed in any Fedora release, they're moved here.


Filtering can be done entirely in the SPEC file, in the %prep section:
==== Shared Libraries ====
 
On EPEL 7 and older, ldconfig MUST be called properly in order to regenerate the dynamic linker's cache.  If the package or subpackage has no existing <code>%post</code> or <code>%postun</code> scriptlets, simply include the <code>%ldconfig_scriptlets</code> macro on its own line before the %files list.


<pre>
<pre>
%prep
[...]
%setup -q -n Foo-%{version}
%install
# Install the program


cat << \EOF > %{name}-prov
%ldconfig_scriptlets libs
#!/bin/sh
%{__perl_provides} $* |\
sed -e '/perl(unwanted_provide)/d'
EOF


%global __perl_provides %{_builddir}/%{name}-%{version}/%{name}-prov
%files libs
chmod +x %{__perl_provides}
%license GPL
[...]
</pre>


Using the <code>%ldconfig_scriptlets</code> macro will automatically generate a dependency on ldconfig where necessary.  The macro will do nothing at all in Fedora.


cat << \EOF > %{name}-req
If the package or subpackage already has existing <code>%post</code> or <code>%postun</code> scriptlet, then use of <code>%ldconfig_scriptlets</code> will cause an error.  You can use <code>%ldconfig_post</code> or <code>%ldconfig_postun</code> individually to generate a scriptlet which doesn't already conflict.
#!/bin/sh
%{__perl_requires} $* |\
sed -e '/perl(unwanted_require)/d'
EOF


%global __perl_requires %{_builddir}/%{name}-%{version}/%{name}-req
Within an existing <code>%post</code> or <code>%postun</code> scriptlet, use <code>%{?ldconfig}</code> on its own line to call ldconfig on those releases which need it.  This will do nothing when not needed.  When calling ldconfig in this way, you MUST also have the proper dependency on /sbin/ldconfig: <code>Requires(post): /sbin/ldconfig</code> and/or <code>Requires(postun): /sbin/ldconfig</code> as appropriate.  (This will generate an unnecessary dependency on releases which do not strictly need it, but this does no harm.)
chmod +x %{__perl_requires}
</pre>


==== External filtering ====
==== GSettings Schema ====
GSettings is the configuration system used by the GNOME 3 desktop. It replaces the older GConf
system, which was used in GNOME 2. GSettings has pluggable backends, the 'native' one for GNOME is using DConf to store settings. The GSettings API and utilities are part of the glib2 package.


Or the script can be placed in an external file and referenced from the specfile. This is worse than the above because the full path of the to-be-overridden script needs to be hardcoded into the file, ignoring the system rpmbuild config.  It is, however, the method used by a significant number of existing packages.
Programs which use GSettings install schema information including default values in the directory %{_datadir}/glib-2.0/schemas. Schema files are xml files with the extension .gschema.xml. At runtime, GSettings uses the schemas in a compiled binary (but arch-neutral) form, which is created by running the glib-compile-schemas utility. /usr/bin/glib-compile-schemas must be run whenever the set of installed schemas changes.


<pre>
<pre>
Source98: filter-provides.sh
%postun
Source99: filter-requires.sh
if [ $1 -eq 0 ] ; then
    /usr/bin/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
fi


%global __perl_provides %{SOURCE98}
%posttrans
%global __perl_requires %{SOURCE99}
    /usr/bin/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
</pre>
</pre>
where filter-provides.sh contains:
 
==== gdk-pixbuf loaders ====
gdk-pixbuf is a library that is part of the gdk-pixbuf2 package. It is for loading images in various formats in GNOME. gdk-pixbuf can be extended by implementing loaders for image formats in loadable modules. These loadable modules have to be installed in %{_libdir}/gdk-pixbuf-2.0/2.10.0/loaders. To avoid opening all modules in that directory unnecessarily, gdk-pixbuf maintains a cache with information about the available modules in the text file %{_libdir}/gdk-pixbuf-2.0/2.10.0/loaders.cache. This cache file needs to be updated when the set of installed modules changes, by calling the /usr/bin/gdk-pixbuf-query-loaders binary. Multilib considerations force us to install the binary in -32 and -64 variants.
 
The scriptlets to maintain the cache file are:
<pre>
<pre>
#!/bin/sh
%postun
/usr/lib/rpm/perl.prov $* |
    /usr/bin/gdk-pixbuf-query-loaders-%{__isa_bits} --update-cache &> /dev/null || :
sed -e '/perl(unwanted_provide)/d'
</pre>
and filter-requires.sh contains:
<pre>
#!/bin/sh
/usr/lib/rpm/perl.req $* |
sed -e '/perl(unwanted_require)/d'
</pre>


=== PHP PEAR Macros ===
%post
On EPEL (EL-5/EL-6), the "%{pear_macrodir}" macro is not defined. The simplest fix is to add this line to your spec file:
if [ $1 -eq 1 ] ; then
<pre>
    # For upgrades, the cache will be regenerated by the new package's %postun
%{!?pear_metadir: %global pear_metadir %{pear_phpdir}}
    /usr/bin/gdk-pixbuf-query-loaders-%{__isa_bits} --update-cache &> /dev/null || :
</pre>
fi
</pre>  


Alternately, simply use %{pear_phpdir} instead.
Note the use of %{__isa_bits}, which is an rpm macro that expands to either 32 or 64,
depending on the architecture of the package.


=== Python ===
==== GTK+ modules ====
Multiple macros are being used in recent python packages that are not available in EL5 and EL6.
The GTK+ toolkit (in the gtk3 package) can be extended by loadable modules which can provide theme engines, input methods, print backends or other functionality. These modules have to be installed in subdirectories of %{_libdir}/gtk-3.0 or %{_libdir}/gtk-3.0/3.0.0. For the input methods, GTK+ maintains a cache in the text file %{_libdir}/gtk-3.0/3.0.0/immodules.cache. This cache file needs to be updated when the set of installed input methods changes, by calling the gtk-query-immodules-3.0 binary. Multilib considerations force us to install the binary in -32 and -64 variants.
{| class="mw-collapsible wikitable" style="width:100%"
! Macro name
! Line to fix it
! Possible alternative
|-
| %{__python2}
| %{!?__python2: %global __python2 /usr/bin/python2}
| %{__python}
|-
| %{python2_sitelib}
| %{!?python2_sitelib: %global python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
| %{python_sitelib}
|-
| %{python2_sitearch}
| %{!?python2_sitearch: %global python2_sitearch %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
| %{python_sitearch}
|-
| %py2_build
| %{!?py2_build: %global py2_build %{expand: CFLAGS="%{optflags}" %{__python2} setup.py %{?py_setup_args} build --executable="%{__python2} -s"}}
| CFLAGS="%{optflags}" %{__python} setup.py %{?py_setup_args} build --executable="%{__python2} -s"
|-
| %py2_install
| %{!?py2_install: %global py2_install %{expand: CFLAGS="%{optflags}" %{__python2} setup.py %{?py_setup_args} install -O1 --skip-build --root %{buildroot}}}
| CFLAGS="%{optflags}" %{__python} setup.py %{?py_setup_args} install -O1 --skip-build --root %{buildroot}
|}


== EPEL 5 and earlier ==
The scriptlets to maintain the cache file are:
<pre>
%postun
/usr/bin/gtk-query-immodules-3.0-%{__isa_bits} --update-cache &> /dev/null || :


=== Building packages for EPEL 5 on non EL5 machines ===
%post
if [ $1 -eq 1 ] ; then
    # For upgrades, the cache will be regenerated by the new package's %postun
    /usr/bin/gtk-query-immodules-3.0-%{__isa_bits} --update-cache &> /dev/null || :
fi
</pre>


If you are receiving md5sum errors when building on non EL5 machines please try the following steps:
The 3.0 in the binary name is there because gtk2 has its own utility for the same purpose, called gtk-query-immodules-2.0. Note the use of %{__isa_bits}, which is an rpm macro that expands to either 32 or 64, depending on the architecture of the package.


<pre>
==== GIO modules ====
1) fedpkg clone <package>
GIO is a library that is part of the glib2 package. It is a low-level part of the GNOME stack.  GIO can be extended by implementing [http://library.gnome.org/devel/gio/2.26/extending-gio.html extension points] in loadable modules. These loadable modules have to be installed in %{_libdir}/gio/modules. To avoid opening all modules in that directory
2) fedpkg switch-branch el5
unnecessarily, GIO maintains a cache with information about the available modules in the
3) <make changes>
text file giomodule.cache in the same directory. This cache file needs to be updated when the set of installed modules changes, by calling the gio-querymodules binary. Multilib considerations force us to install the binary in -32 and -64 variants.
4) fedpkg srpm
5) koji build --scratch dist-5E-epel file.el5.src.rpm
6) Verify build completes
7) fedpkg commit
8) fedpkg push
9) fedpkg build
</pre>


=== PHP ABI Check Handling ===
The scriptlets to maintain the cache file are:
For Fedora '''EPEL 5''':  
<pre>
<pre>
%global php_apiver  %((echo 0; php -i 2>/dev/null | sed -n 's/^PHP API => //p') | tail -1)
%postun
/usr/bin/gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules &> /dev/null || :


BuildRequires: php-devel
%post
Requires:      php-api = %{php_apiver}
# We run this after every install or upgrade because of a cornercase
</pre>
# when installing the second architecture of a multilib package
There is no way of checking the ABI with packages for Fedora EPEL 5.
/usr/bin/gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules || :
</pre>  


For a spec file which is compatible with both Fedora and EPEL 5:
Note the use of %{__isa_bits}, which is an rpm macro that expands to either 32 or 64,
<pre>
depending on the architecture of the package.
%global php_apiver  %((echo 0; php -i 2>/dev/null | sed -n 's/^PHP API => //p') | tail -1)


%if 0%{?php_zend_api}
==== mimeinfo ====
Requires:    php(zend-abi) = %{php_zend_api}
Use this when a package drops an XML file in %{_datadir}/mime/packages.
Requires:    php(api) = %{php_core_api}
%else
Requires:    php-api = %{php_apiver}
%endif
</pre>
 
=== PHP PECL Module Scriptlets ===
On EPEL5, the Fedora scriptlets for properly registering and unregistering the module have to be wrapped with conditionals checking for the existence of %{pecl_install} and %{pecl_uninstall}:
<pre>
<pre>
%if 0%{?pecl_install:1}
%post
%post
%{pecl_install} %{pecl_xmldir}/%{name}.xml >/dev/null || :
/bin/touch --no-create %{_datadir}/mime/packages &>/dev/null || :
%endif


%if 0%{?pecl_uninstall:1}
%postun
%postun
if [ $1 -eq 0 ] ; then
if [ $1 -eq 0 ] ; then
%{pecl_uninstall} %{pecl_name} >/dev/null || :
  /usr/bin/update-mime-database %{_datadir}/mime &> /dev/null || :
fi
fi
%endif
</pre>
=== pkgconfig ===
rpm in EPEL5 does not automatically create dependencies for pkgconfig files.  Packages containing pkgconfig(.pc) files must <code>Requires: pkgconfig</code> (for directory ownership and usability).
=== python byte compilation ===
In EPEL5 the automatic byte compilation of python files that is performed by brp-python-bytecompile byte compiles all files that match *.py  This is undesirable for program files in %{_bindir} and %{_sbindir} because the user will probably never invoke these files, only the main program file and python won't use these files.  There are two workarounds:
<ol>
<li>Rename scripts in %{_bindir} to not have a .py extension:  For instance, from /usr/bin/orient.py to /usr/bin/orient.</li>
<li>Use %exclude to exclude the scripts from the file listing:
<pre>
%files
%{_bindir}/orient.py
%exclude %{_bindir}/orient.pyc
%exclude %{_bindir}/orient.pyo
</pre></li>
</ol>
=== noarch subpackages ===
EL 5 and earlier do not support noarch subpackages.  If your build fails due to unpackaged debuginfo files ensure that the <code>BuildArch: noarch</code> is wrapped in an if to make sure its not used on EL-5 and earlier.


=== xz compression ===
%posttrans
Tar in EL 5 and earlier does not support extracting xz-compressed
/usr/bin/update-mime-database %{?fedora:-n} %{_datadir}/mime &> /dev/null || :
tarballs.  To extract such tarballs, use the following %prep section:
<pre>
%prep
xzcat %{SOURCE0} | tar -xf -
%setup -qDT
</pre>
</pre>


=== Scrollkeeper ===
Note that similarly to the gtk-update-icon-cache code, these scriptlets should be run only if the user has update-mime-info installed and without a specific Requires: shared-mime-infoIf shared-mime-info is not installed, update-mime-database won't be run when this package is installedThis does not matter because it will be run when the shared-mime-info package is installed.
For EL-5, Gnome and KDE use the scrollkeeper cataloging system to keep track of documentation installed on the systemScrollkeeper allows the help system to sort and search documentation metadata stored in .omf filesWhen you add documentation in these systems you need to make scrollkeeper aware that the documentation has been changed.


Note that we BuildRequires scrollkeeper as most Makefile's are setup to install the necessary scrollkeeper files only if scrollkeeper is present at install time.
==== desktop-database ====
Use this when a desktop entry has a '''MimeType''' key.
<pre>
<pre>
BuildRequires:  scrollkeeper
Requires(post): scrollkeeper
Requires(postun): scrollkeeper
...
%post
%post
scrollkeeper-update -q -o %{_datadir}/omf/%{name} || :
/usr/bin/update-desktop-database &> /dev/null || :


%postun
%postun
scrollkeeper-update -q || :
/usr/bin/update-desktop-database &> /dev/null || :
</pre>
Note: This scriptlet follows the same convention as mimeinfo files and gtk-icon-cache.  Namely, the spec file should not Require desktop-file-utils for this.  For older releases, one should
<pre>
Requires(post): desktop-file-utils
Requires(postun): desktop-file-utils
</pre>
</pre>
These two scriptlets tell scrollkeeper to update its indexes to account for the new scrollkeeper files.
(See http://bugzilla.redhat.com/180898 and http://bugzilla.redhat.com/180899)


=== GConf Scriptlets ===
==== Icon Cache ====
In Fedora, we now use macros for our GConf2 scriptlets, but for EL-5, this is not an option. For those targets, please use the old manual scriptlets, as documented below:
If an application installs icons into one of the subdirectories in <code>%{_datadir}/icons/</code> (such as <code>hicolor</code> in the following examples), icon caches must be updated so that the installed icons show up in menus right after package installation.  This consists of updating the timestamp of the top-level icon directory where the icons were installed, and running <code>gtk-update-icon-cache</code>.  'touch'ing the top-level dir is done so that environments compatible with the [http://standards.freedesktop.org/icon-theme-spec/latest/ar01s08.html Icon theme specification] can refresh their caches, and <code>gtk-update-icon-cache</code> which is additionally required for GNOME also does its work based on the dir timestamp.


<pre>
Note that no dependencies should be added for this. If gtk-update-icon-cache is not available, there's nothing that would be needing the cache update, ditto if "touch" is not available, there's nothing that would benefit from icon cache updates installed yet either. Not adding the dependency on gtk-update-icon-cache (ie. gtk2 >= 2.6.0) or "touch" makes it easier to use the package (or the same specfile) on systems where it's not available nor needed, such as older distro versions or (very) trimmed down installations, and generally results in less entries in specfiles, rpmdb, and repo metadatas.
Requires(pre): GConf2
Requires(post): GConf2
Requires(preun): GConf2
...
%pre
if [ "$1" -gt 1 ] ; then
export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
gconftool-2 --makefile-uninstall-rule \
%{_sysconfdir}/gconf/schemas/[NAME] .schemas >/dev/null || :
fi
</pre>
In this section we uninstall the old schemas when we upgrade.  The way we do this is first to get information about where gconf stores its values via the gconftool-2 --get-default-source line. Then we uninstall the schema from that source. If the package could be upgrading a package which had another name for the schema at one time, then we uncomment the lines to uninstall those as well.


The next section is for installing the new schema:
<pre>
<pre>
%post
%post
export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
/bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null || :
gconftool-2 --makefile-install-rule \
%{_sysconfdir}/gconf/schemas/[NAME] .schemas > /dev/null || :
</pre>
Here we do the same things as in the %pre section for upgrading except the gconftool-2 switch used is --makefile-install-rule to install the new schemas instead of the uninstall-rule to remove the old schemas.


The last section deals with deleting the schemas on package removal:
%postun
<pre>
if [ $1 -eq 0 ] ; then
%preun
    /bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null
if [ "$1" -eq 0 ] ; then
    /usr/bin/gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
gconftool-2 --makefile-uninstall-rule \
%{_sysconfdir}/gconf/schemas/[NAME] .schemas > /dev/null || :
fi
fi
</pre>
This snippet is nearly the same as the one for upgrading.  Why can't we just combine this portion with the  %pre portion?  The answer is that we want to delete any old versions of the schema during an upgrade.  But this has to happen before we install the new version (in the %post script) otherwise we end up removing the schema that the upgrading package installs.  However, if it really is a removal that will leave no other instances of this package on the system, we have to clean up the schema before deleting it.


=== Scriptlets requirements ===
%posttrans
Do not use the <code>Requires(pre,post)</code> style notation for scriptlet dependencies, because of two bugs in RPM. Instead, they should be split like this:
/usr/bin/gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
<pre>
Requires(pre): ...
Requires(post): ...
</pre>
</pre>
For more information, see [http://www.redhat.com/archives/fedora-devel-list/2004-April/msg00674.html this mailing list post] .


[[Category:EPEL]]
[[Category:EPEL]]
[[Category:Policy]]
[[Category:Policy]]

Revision as of 01:57, 10 June 2021

This page contains guidelines which are no longer relevant to Fedora, but still apply to EPEL packages. These guidelines are designed to avoid conflict with the larger Fedora Packaging Guidelines, but should any conflicts occur, these guidelines should take precedence (on EPEL packages).

As a reminder, these guidelines only apply to EPEL packages, not to Fedora packages.

Limited Arch Packages

Red Hat Enterprise Linux does not ship the same packages for all of its available architectures. For EPEL-7, it is allowed for EPEL to ship a package which was the same as what was in RHEL but built with changes listed below.

  1. Make sure the package is not shipped for all architectures. The valid architectures are:
    • EPEL7: ppc64le, x86_64.
    • EPEL8: Because we have had problems with these packages causing either build, compose, or user problems, we are not allowing this for EPEL8.
  2. Make sure the package meets the Fedora licensing and distribution rules. Nothing non-free or under an unacceptable license.
  3. Notify the epel-devel list of your intention to add this package.
  4. Change the release of the package to have a leading 0. EXAMPLE: RHEL has foobar-1.0-1, you change it to foobar-1.0-0.1 for EPEL.
  5. Add a Changelog entry that the package was added to EPEL and has a 0 leading version to keep it older than RHEL.
  6. Request the branch you need (epel7) using fedpkg request-branch.
  7. Import and build your package, submit as update.
  8. Watch the RHEL version of the package. When it updates, you should update the EPEL version too. You should never update other than that.

NOTE: Do not add ExclusiveArch tags, this will break building on the other architectures!

EPEL 8

Scriptlets

Fedora has been moving towards the use of file triggers and away from requiring that packagers cut and paste scriptlets into loads of packages. At the time of this writing, we are trying to backport all of these to EPEL8, so that fedora packages are easily able to build on EPEL8 without any changes. When EPEL 8 becomes old enough, that these backports are not feasible and/or wanted, we will list them here.

EPEL 7

Rich Dependencies

RHEL 7's rpm and yum versions do not support rich or boolean dependencies, so these are not allowed in EPEL 7.

Scriptlets

Fedora has been moving towards the use of file triggers and away from requiring that packagers cut and paste scriptlets into loads of packages. These scriptlets would still be needed for EPEL, and as scriptlets are no longer needed in any Fedora release, they're moved here.

Shared Libraries

On EPEL 7 and older, ldconfig MUST be called properly in order to regenerate the dynamic linker's cache. If the package or subpackage has no existing %post or %postun scriptlets, simply include the %ldconfig_scriptlets macro on its own line before the %files list.

[...]
%install
# Install the program

%ldconfig_scriptlets libs

%files libs
%license GPL
[...]

Using the %ldconfig_scriptlets macro will automatically generate a dependency on ldconfig where necessary. The macro will do nothing at all in Fedora.

If the package or subpackage already has existing %post or %postun scriptlet, then use of %ldconfig_scriptlets will cause an error. You can use %ldconfig_post or %ldconfig_postun individually to generate a scriptlet which doesn't already conflict.

Within an existing %post or %postun scriptlet, use %{?ldconfig} on its own line to call ldconfig on those releases which need it. This will do nothing when not needed. When calling ldconfig in this way, you MUST also have the proper dependency on /sbin/ldconfig: Requires(post): /sbin/ldconfig and/or Requires(postun): /sbin/ldconfig as appropriate. (This will generate an unnecessary dependency on releases which do not strictly need it, but this does no harm.)

GSettings Schema

GSettings is the configuration system used by the GNOME 3 desktop. It replaces the older GConf system, which was used in GNOME 2. GSettings has pluggable backends, the 'native' one for GNOME is using DConf to store settings. The GSettings API and utilities are part of the glib2 package.

Programs which use GSettings install schema information including default values in the directory %{_datadir}/glib-2.0/schemas. Schema files are xml files with the extension .gschema.xml. At runtime, GSettings uses the schemas in a compiled binary (but arch-neutral) form, which is created by running the glib-compile-schemas utility. /usr/bin/glib-compile-schemas must be run whenever the set of installed schemas changes.

%postun
if [ $1 -eq 0 ] ; then
    /usr/bin/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
fi

%posttrans
    /usr/bin/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :

gdk-pixbuf loaders

gdk-pixbuf is a library that is part of the gdk-pixbuf2 package. It is for loading images in various formats in GNOME. gdk-pixbuf can be extended by implementing loaders for image formats in loadable modules. These loadable modules have to be installed in %{_libdir}/gdk-pixbuf-2.0/2.10.0/loaders. To avoid opening all modules in that directory unnecessarily, gdk-pixbuf maintains a cache with information about the available modules in the text file %{_libdir}/gdk-pixbuf-2.0/2.10.0/loaders.cache. This cache file needs to be updated when the set of installed modules changes, by calling the /usr/bin/gdk-pixbuf-query-loaders binary. Multilib considerations force us to install the binary in -32 and -64 variants.

The scriptlets to maintain the cache file are:

%postun
    /usr/bin/gdk-pixbuf-query-loaders-%{__isa_bits} --update-cache &> /dev/null || :

%post
if [ $1 -eq 1 ] ; then
    # For upgrades, the cache will be regenerated by the new package's %postun
    /usr/bin/gdk-pixbuf-query-loaders-%{__isa_bits} --update-cache &> /dev/null || :
fi

Note the use of %{__isa_bits}, which is an rpm macro that expands to either 32 or 64, depending on the architecture of the package.

GTK+ modules

The GTK+ toolkit (in the gtk3 package) can be extended by loadable modules which can provide theme engines, input methods, print backends or other functionality. These modules have to be installed in subdirectories of %{_libdir}/gtk-3.0 or %{_libdir}/gtk-3.0/3.0.0. For the input methods, GTK+ maintains a cache in the text file %{_libdir}/gtk-3.0/3.0.0/immodules.cache. This cache file needs to be updated when the set of installed input methods changes, by calling the gtk-query-immodules-3.0 binary. Multilib considerations force us to install the binary in -32 and -64 variants.

The scriptlets to maintain the cache file are:

%postun
/usr/bin/gtk-query-immodules-3.0-%{__isa_bits} --update-cache &> /dev/null || :

%post
if [ $1 -eq 1 ] ; then
    # For upgrades, the cache will be regenerated by the new package's %postun
    /usr/bin/gtk-query-immodules-3.0-%{__isa_bits} --update-cache &> /dev/null || :
fi

The 3.0 in the binary name is there because gtk2 has its own utility for the same purpose, called gtk-query-immodules-2.0. Note the use of %{__isa_bits}, which is an rpm macro that expands to either 32 or 64, depending on the architecture of the package.

GIO modules

GIO is a library that is part of the glib2 package. It is a low-level part of the GNOME stack. GIO can be extended by implementing extension points in loadable modules. These loadable modules have to be installed in %{_libdir}/gio/modules. To avoid opening all modules in that directory unnecessarily, GIO maintains a cache with information about the available modules in the text file giomodule.cache in the same directory. This cache file needs to be updated when the set of installed modules changes, by calling the gio-querymodules binary. Multilib considerations force us to install the binary in -32 and -64 variants.

The scriptlets to maintain the cache file are:

%postun
/usr/bin/gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules &> /dev/null || :

%post
# We run this after every install or upgrade because of a cornercase
# when installing the second architecture of a multilib package 
/usr/bin/gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules || :

Note the use of %{__isa_bits}, which is an rpm macro that expands to either 32 or 64, depending on the architecture of the package.

mimeinfo

Use this when a package drops an XML file in %{_datadir}/mime/packages.

%post
/bin/touch --no-create %{_datadir}/mime/packages &>/dev/null || :

%postun
if [ $1 -eq 0 ] ; then
  /usr/bin/update-mime-database %{_datadir}/mime &> /dev/null || :
fi

%posttrans
/usr/bin/update-mime-database %{?fedora:-n} %{_datadir}/mime &> /dev/null || :

Note that similarly to the gtk-update-icon-cache code, these scriptlets should be run only if the user has update-mime-info installed and without a specific Requires: shared-mime-info. If shared-mime-info is not installed, update-mime-database won't be run when this package is installed. This does not matter because it will be run when the shared-mime-info package is installed.

desktop-database

Use this when a desktop entry has a MimeType key.

%post
/usr/bin/update-desktop-database &> /dev/null || :

%postun
/usr/bin/update-desktop-database &> /dev/null || :

Note: This scriptlet follows the same convention as mimeinfo files and gtk-icon-cache. Namely, the spec file should not Require desktop-file-utils for this. For older releases, one should

Requires(post): desktop-file-utils
Requires(postun): desktop-file-utils

(See http://bugzilla.redhat.com/180898 and http://bugzilla.redhat.com/180899)

Icon Cache

If an application installs icons into one of the subdirectories in %{_datadir}/icons/ (such as hicolor in the following examples), icon caches must be updated so that the installed icons show up in menus right after package installation. This consists of updating the timestamp of the top-level icon directory where the icons were installed, and running gtk-update-icon-cache. 'touch'ing the top-level dir is done so that environments compatible with the Icon theme specification can refresh their caches, and gtk-update-icon-cache which is additionally required for GNOME also does its work based on the dir timestamp.

Note that no dependencies should be added for this. If gtk-update-icon-cache is not available, there's nothing that would be needing the cache update, ditto if "touch" is not available, there's nothing that would benefit from icon cache updates installed yet either. Not adding the dependency on gtk-update-icon-cache (ie. gtk2 >= 2.6.0) or "touch" makes it easier to use the package (or the same specfile) on systems where it's not available nor needed, such as older distro versions or (very) trimmed down installations, and generally results in less entries in specfiles, rpmdb, and repo metadatas.

%post
/bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null || :

%postun
if [ $1 -eq 0 ] ; then
    /bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null
    /usr/bin/gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
fi

%posttrans
/usr/bin/gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :