#1126 More semantic breaks
Merged 2 years ago by tibbs. Opened 2 years ago by tibbs.
tibbs/packaging-committee sembr  into  master

@@ -3,27 +3,38 @@ 

  :last-reviewed: 2019-04-04

  :toc:

  

- This document describes the current policies for packaging Ada programs and libraries for Fedora.

+ This document describes the current policies for packaging

+ Ada programs and libraries for Fedora.

  These are Ada-specific amendments to the generic Packaging Guidelines.

  Ada packages must also conform to the link:../[Packaging Guidelines]

  and the link:../ReviewGuidelines/[Review Guidelines].

  

  == Compilation

  

- * Ada code in Fedora *MUST* be compiled using GNAT, the default Ada compiler in Fedora.

+ * Ada code in Fedora *MUST* be compiled using GNAT,

+   the default Ada compiler in Fedora.

    All packages that contain Ada code *MUST* have “`+BuildRequires: gcc-gnat+`”

    to ensure that the compiler is available.

- * There are a number of RPM macros that contain Fedora’s standard compiler and linker flags adapted for GNAT.

-   The appropriate macro *MUST* be used in the build stage. The right macro to use depends on what build tools the package uses.

+ * There are a number of RPM macros that contain

+   Fedora’s standard compiler and linker flags adapted for GNAT.

+   The appropriate macro *MUST* be used in the build stage.

+   The right macro to use depends on what build tools the package uses.

  ** For packages that are built with Gnatmake or GPRbuild but without Comfignat

-    there are the macros +++<var>Gnatmake_optflags</var>+++ and +++<var>GPRbuild_optflags</var>+++,

+    there are the macros

+    +++<var>Gnatmake_optflags</var>+++

+    and +++<var>GPRbuild_optflags</var>+++,

     which contain builder, compiler and linker flags.

- ** In case a package’s build system invokes the underlying GNAT tools without using Gnatmake or GPRbuild,

+ ** In case a package’s build system invokes the underlying GNAT tools

+    without using Gnatmake or GPRbuild,

     then the appropriate macro for each tool *MUST* be used.

-    If for example Gnatlink is invoked directly, then the expansion of +++<var>Gnatlink_flags</var>+++ shall be passed to it.

- ** For packages whose build systems use Comfignat there is the macro +++<var>Comfignat_make</var>+++.

-    It expands to a Make command with appropriate values for Comfignat’s configuration variables,

-    including builder, compiler and linker flags, directory variables and the directories project.

+    If for example Gnatlink is invoked directly,

+    then the expansion of +++<var>Gnatlink_flags</var>+++ shall be passed to it.

+ ** For packages whose build systems use Comfignat

+    there is the macro +++<var>Comfignat_make</var>+++.

+    It expands to a Make command with appropriate values

+    for Comfignat’s configuration variables,

+    including builder, compiler and linker flags,

+    directory variables and the directories project.

     Use it alone to build the default target:

  +

  ....
@@ -37,57 +48,94 @@ 

  %{Comfignat_make} demo_programs atomic_doodads=true

  ....

  +

- For the installation stage of Comfignat-using packages, the macro +++<var>make_install</var>+++ (*not* +++<var>makeinstall</var>+++) is recommended.

- * The macro +++<var>GNAT_arches</var>+++ expands to a list of architectures where GNAT packages are available in Fedora.

-   Starting with Fedora 18, when there is a need to prevent attempts to build an Ada package on secondary architectures where GNAT has not been bootstrapped,

-   this *MUST* be done with “`+ExclusiveArch: %{GNAT_arches}+`”.

- * All packages that contain Ada code *MUST* have “`+BuildRequires: fedora-gnat-project-common+`” to ensure that the necessary RPM macros are defined.

+ For the installation stage of Comfignat-using packages,

+ the macro +++<var>make_install</var>+++ (*not* +++<var>makeinstall</var>+++)

+ is recommended.

+ * The macro +++<var>GNAT_arches</var>+++ expands to a list of architectures

+ where GNAT packages are available in Fedora.

+ Starting with Fedora 18, when there is a need to prevent attempts

+ to build an Ada package on secondary architectures

+ where GNAT has not been bootstrapped,

+ this *MUST* be done with “`+ExclusiveArch: %{GNAT_arches}+`”.

+ * All packages that contain Ada code *MUST* have

+ “`+BuildRequires: fedora-gnat-project-common+`”

+ to ensure that the necessary RPM macros are defined.

  * If the upstream source package comes with a build system,

-   for example a GNAT project file or makefiles and a configuration script,

-   then it’s probably best to use that if possible.

-   If not, it is recommended that the packager write a GNAT project file to control the compilation.

+ for example a GNAT project file or makefiles and a configuration script,

+ then it’s probably best to use that if possible.

+ If not, it is recommended that the packager write a GNAT project file

+ to control the compilation.

  

  == Runpaths

  

  Gnatmake and GPRbuild both add a runpath to the built binaries by default.

- Fedora’s builder flags normally include an option to disable the automatic runpath.

+ Fedora’s builder flags normally include an option

+ to disable the automatic runpath.

  There are however cases where it would be advantageous to allow a runpath.

  Libraries can have test suites or auxiliary programs that aren’t installed

  but run during the build and need to link to the library in the build directory,

  and they may rely on an automatic runpath for this.

- In those cases the spec file may define a macro named +++<var>GNAT_add_rpath</var>+++.

- The builders will then be allowed to add a runpath in those parts of the spec file where +++<var>GNAT_add_rpath</var>+++ is defined.

- 

- NOTE: +++<var>GNAT_add_rpath</var>+++ does not exempt a package from the Packaging Guidelines.

+ In those cases the spec file may define a macro named

+ +++<var>GNAT_add_rpath</var>+++.

+ The builders will then be allowed to add a runpath

+ in those parts of the spec file where

+ +++<var>GNAT_add_rpath</var>+++ is defined.

+ 

+ NOTE: +++<var>GNAT_add_rpath</var>+++ does not exempt a package

+ from the Packaging Guidelines.

  link:../#_beware_of_rpath[The policy on runpaths] still applies.

  

  == Devel packages

  

- * Ada library packages *MUST* have a -devel subpackage containing all the files that are necessary for compilation of code that uses the library.

-   This includes +Ada specification files (*.ads),

-   Ada body files (*.adb),

-   Ada library information files (*.ali)

-   and GNAT project files (*.gpr).+

-   (There is no requirement to include all body files.

-   Typically only some body files are needed.)

- * The -devel package *MUST NOT* contain any makefiles or other files that are only used for recompiling the library.

+ * Ada library packages *MUST* have a -devel subpackage

+ containing all the files that are necessary for compilation of code

+ that uses the library.

+ This includes +Ada specification files (*.ads),

+ Ada body files (*.adb),

+ Ada library information files (*.ali)

+ and GNAT project files (*.gpr).+

+ (There is no requirement to include all body files.

+ Typically only some body files are needed.)

+ 

+ * The -devel package *MUST NOT* contain any makefiles

+ or other files that are only used for recompiling the library.

+ 

  * The -devel package *MUST NOT* contain any +*.o+ files.

  

  === GNAT project files

  

- * The -devel package *MUST* contain one or more GNAT project files to be imported by other projects that use the library.

+ * The -devel package *MUST* contain one or more GNAT project files

+ to be imported by other projects that use the library.

+ 

  * Project files *MUST* be architecture-independent.

-   This means that the same project file must point to libraries in /usr/lib or /usr/lib64 depending on what target architecture the compiler is currently compiling for.

-   This *SHOULD* be done by importing the “directories” project

-   (that is, the project file directories.gpr)

-   and using the variable +++<var>Directories.Libdir</var>+++ which is defined there.

-   The value of +++<var>Directories.Libdir</var>+++ is set to either “/usr/lib” or “/usr/lib64” depending on the hardware platform.

- * Project files *MUST NOT* contain hard-coded directory names, neither absolute nor relative; they should get them from some source.

-   The source may be an Autoconf-generated configuration script or other build system.

-   Project files that aren’t pre-processed by such a build system *SHOULD* use the variable +++<var>Directories.Includedir</var>+++ rather than a hard-coded “/usr/include”.

+ This means that the same project file must point to libraries in

+ /usr/lib or /usr/lib64

+ depending on what target architecture the compiler is currently compiling for.

+ This *SHOULD* be done by importing the “directories” project

+ (that is, the project file directories.gpr)

+ and using the variable

+ +++<var>Directories.Libdir</var>+++

+ which is defined there.

+ The value of

+ +++<var>Directories.Libdir</var>+++

+ is set to either “/usr/lib” or “/usr/lib64” depending on the hardware platform.

+ 

+ * Project files *MUST NOT* contain hard-coded directory names,

+ neither absolute nor relative; they should get them from some source.

+ The source may be an Autoconf-generated configuration script

+ or other build system.

+ Project files that aren’t pre-processed by such a build system

+ *SHOULD* use the variable

+ +++<var>Directories.Includedir</var>+++

+ rather than a hard-coded “/usr/include”.

+ 

  * If the “directories” project is used,

-   then the -devel package *MUST* have an explicit “`+Requires: fedora-gnat-project-common+`”.

- * Project files *MUST* have an +++<var>Externally_Built</var>+++ attribute equal to “true”.

+ then the -devel package *MUST* have an explicit

+ “`+Requires: fedora-gnat-project-common+`”.

+ 

+ * Project files *MUST* have an

+ +++<var>Externally_Built</var>+++

+ attribute equal to “true”.

  

  Here’s an example of what a project file installed with a library may look like:

  
@@ -105,16 +153,28 @@ 

  == File placement

  

  * Ada source files in -devel packages (+*.ads and *.adb+)

-   *MUST* be placed in the `+%{_includedir}+` directory or a subdirectory thereof.

-   Placing them directly in `+%{_includedir}+` may be appropriate if there are very few of them in the package and their names include the name of the library.

-   Otherwise they should usually be placed in a subdirectory, for example `+%{_includedir}/%{name}+`.

+ *MUST* be placed in the `+%{_includedir}+` directory

+ or a subdirectory thereof.

+ Placing them directly in `+%{_includedir}+` may be appropriate

+ if there are very few of them in the package

+ and their names include the name of the library.

+ Otherwise they should usually be placed in a subdirectory,

+ for example `+%{_includedir}/%{name}+`.

+ 

  * Ada library information files (+*.ali+)

-   *MUST* be placed in a subdirectory of `+%{_libdir}+`, for example `+%{_libdir}/%{name}+`.

+ *MUST* be placed in a subdirectory of `+%{_libdir}+`,

+ for example `+%{_libdir}/%{name}+`.

+ 

  * GNAT projects files (+*.gpr+)

-   *MUST* be placed in the `+%{_GNAT_project_dir}+` directory or a subdirectory thereof.

-   A subdirectory, for example `+%{_GNAT_project_dir}/%{name}+`, may be a good idea if there are lots of project files in the same package or if they have generic names.

-   Otherwise they should usually be placed directly in `+%{_GNAT_project_dir}+`.

-   The name of the library *MUST* be included either in the name of each project file or in the name of the subdirectory where the project files are placed.

+ *MUST* be placed in the `+%{_GNAT_project_dir}+` directory

+ or a subdirectory thereof.

+ A subdirectory, for example `+%{_GNAT_project_dir}/%{name}+`,

+ may be a good idea if there are lots of project files in the same package

+ or if they have generic names.

+ Otherwise they should usually be placed directly in `+%{_GNAT_project_dir}+`.

+ The name of the library *MUST* be included

+ either in the name of each project file

+ or in the name of the subdirectory where the project files are placed.

  

  == Rpmlint and Ada packages

  
@@ -123,4 +183,5 @@ 

  some of the rpmlint messages, such as “executable-stack”,

  can be disregarded,

  because GNAT uses trampolines for pointers to nested functions.

- (See for example https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24355[this entry in the GCC Bugzilla].)

+ (See for example

+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24355[this entry in the GCC Bugzilla].)

@@ -3,7 +3,9 @@ 

  :last-reviewed: 2019-04-04

  :toc:

  

- Alternatives provide means for parallel installation of packages which provide the same functionality by maintaining sets of symlinks (one per package) pointing to alternativized files like this:

+ Alternatives provide means for parallel installation of packages

+ which provide the same functionality by maintaining sets of symlinks

+ (one per package) pointing to alternativized files like this:

  `+/path/original-file -> /etc/alternatives/packagename-original-file -> /path/original-file.suffix+`

  For more information, see `+update-alternatives(8)+` manpage.

  
@@ -11,40 +13,72 @@ 

  

  Alternatives *MAY* be used to allow parallel installation of software when:

  

- * the software can be used as a drop-in replacement and functions with sufficient similarity that users and other programs would, within reason, not need to know which variant is currently installed

+ * the software can be used as a drop-in replacement

+ and functions with sufficient similarity

+ that users and other programs would, within reason,

+ not need to know which variant is currently installed

  

  *AND*

  

- * the selection of the software is only performed system-wide by the system administrator and end users do not have a need to switch between the variants.

+ * the selection of the software is only performed system-wide

+ by the system administrator

+ and end users do not have a need to switch between the variants.

  

  Inversely, alternatives *MUST NOT* be used when:

  

- * The software is not a drop-in replacement. For instance, if common command line arguments are different between the two variants, alternatives *MUST NOT* be used.

+ * The software is not a drop-in replacement.

+ For instance, if common command line arguments are different

+ between the two variants,

+ alternatives *MUST NOT* be used.

  

  *OR*

  

- * End users will care which variant they are using. If a non-root user would gain value by switching between the variants then alternatives *MUST NOT* be used.

+ * End users will care which variant they are using.

+ If a non-root user would gain value by switching between the variants

+ then alternatives *MUST NOT* be used.

  

- A good example of using alternatives are the various MTAs which all provide `+/usr/sbin/sendmail+` with similar command line arguments.

+ A good example of using alternatives are the various MTAs

+ which all provide `+/usr/sbin/sendmail+` with similar command line arguments.

  

  Bad examples of using alternatives include:

  

- * the various MPI environments where users care both about which MPI environment they compile against and which one they run against

- * choice of editor when the user invokes "vi" where the user will care about feature availability, compatibility with plugins, etc

+ * the various MPI environments where users care

+ both about which MPI environment they compile against

+ and which one they run against

  

- Cases where parallel installation is desirable but alternatives is unsuitable may be scenarios where link:../EnvironmentModules/[Environment Modules] are appropriate. MPI and python-sphinx (until Fedora 31) are example packages using environment-modules for this purpose.

+ * choice of editor when the user invokes "vi"

+ where the user will care about feature availability,

+ compatibility with plugins, etc

+ 

+ Cases where parallel installation is desirable but alternatives is unsuitable

+ may be scenarios where

+ link:../EnvironmentModules/[Environment Modules]

+ are appropriate.

+ MPI and python-sphinx (until Fedora 31)

+ are example packages using environment-modules for this purpose.

  

  == How to use alternatives

  

- If a package is using alternatives, the files which would otherwise conflict MUST be installed with an appropriate suffix (for example: `+%{_sbindir}/sendmail.postfix+` instead of `+%{_sbindir}/sendmail+`), the original locations MUST be touched (for example: `+touch %{_sbindir}/sendmail+`), the links set up by alternatives MUST be listed as %ghost in the file list and proper Requires: MUST be added, like in the examples below.

+ If a package is using alternatives,

+ the files which would otherwise conflict MUST be installed

+ with an appropriate suffix

+ (for example: `+%{_sbindir}/sendmail.postfix+`

+ instead of `+%{_sbindir}/sendmail+`),

+ the original locations MUST be touched

+ (for example: `+touch %{_sbindir}/sendmail+`),

+ the links set up by alternatives MUST be listed as %ghost in the file list

+ and proper Requires: MUST be added, like in the examples below.

  

- Putting the alternativized files in the file list ensures that they are owned by respective packages, which means that commands like:

+ Putting the alternativized files in the file list

+ ensures that they are owned by respective packages,

+ which means that commands like:

  

  * rpm -qf /usr/bin/foo

  * dnf install /usr/bin/foo

  * repoquery --whatprovides /usr/bin/foo

  

- all work properly. Using %ghost for this purpose allows using globs and generated file lists.

+ all work properly.

+ Using %ghost for this purpose allows using globs and generated file lists.

  

  == Examples

  
@@ -73,7 +107,8 @@ 

  %{_bindir}/antlr-java

  ....

  

- And a more complex example of alternatives invocation from sendmail.spec, slightly edited:

+ And a more complex example of alternatives invocation from sendmail.spec,

+ slightly edited:

  

  ....

  Requires(post): %{_sbindir}/update-alternatives

@@ -5,29 +5,58 @@ 

  

  == Summary

  

- The auto requires and provides system contained in RPM is quite useful; however, it sometimes picks up "private" package capabilities that shouldn't be advertised as global, things that are "just wrong", or things prohibited by policy (e.g. deps from inside `+%{_docdir}+`).

+ The auto requires and provides system contained in RPM is quite useful;

+ however, it sometimes picks up "private" package capabilities

+ that shouldn't be advertised as global,

+ things that are "just wrong",

+ or things prohibited by policy (e.g. deps from inside `+%{_docdir}+`).

  

  For example:

  

- * Various "plugin" packages (e.g. Pidgin, Perl, Apache, KDE) are marked as "providing" private shared libraries outside the system path.

- * Files in `+%{_docdir}+` are routinely scanned, and can trigger prov/req when this is explicitly forbidden by policy.

+ * Various "plugin" packages (e.g. Pidgin, Perl, Apache, KDE)

+ are marked as "providing" private shared libraries outside the system path.

+ * Files in `+%{_docdir}+` are routinely scanned,

+ and can trigger prov/req when this is explicitly forbidden by policy.

  

  This Guideline describes how to filter provides and requires on Fedora.

  

- * *MUST:* Packages must not provide RPM dependency information when that information is not global in nature, or are otherwise handled (e.g. through a virtual provides system). e.g. a plugin package containing a binary shared library must not "provide" that library unless it is accessible through the system library paths.

- * *MUST:* When filtering automatically generated RPM dependency information, the filtering system implemented by Fedora must be used, except where there is a compelling reason to deviate from it.

+ * *MUST:* Packages must not provide RPM dependency information

+ when that information is not global in nature,

+ or are otherwise handled (e.g. through a virtual provides system).

+ e.g. a plugin package containing a binary shared library

+ must not "provide" that library

+ unless it is accessible through the system library paths.

+ * *MUST:* When filtering automatically generated RPM dependency information,

+ the filtering system implemented by Fedora must be used,

+ except where there is a compelling reason to deviate from it.

  

  == Usage

  

  === Location of macro invocation

  

- It's strongly recommended that these filtering macros be invoked before `+%description+`, but after any other definitions. This will keep them in a consistent place across packages, and help prevent them from being mixed up with other sections.

+ It's strongly recommended

+ that these filtering macros be invoked before `+%description+`,

+ but after any other definitions.

+ This will keep them in a consistent place across packages,

+ and help prevent them from being mixed up with other sections.

  

  === Regular Expression Variant

  

- These filters use regular expressions. The regular expression variant used for these filters follow the `POSIX.2` regular expression standard (see man regex(7) ). In this variant, the literal characters `+^.[$()|*+?{+` need to be backslash escaped. Because rpm interprets backslashes as part of its parsing of spec files, you will need to use a *double backslash* for any escapes. A literal backslash ("`+\+`") is represented by four backslashes.

- 

- The regex engine is only passed the final string, after rpm macro expansion. So you can't use unescaped data via rpm macros. For instance, if you generate a list of files to match in a macro and that list contains `+libfoo.so+` you'll have to use `+libfoo\\.so+` to escape the ("`+.+`"). Example:

+ These filters use regular expressions.

+ The regular expression variant used for these filters

+ follow.the `POSIX.2` regular expression standard (see man regex(7) ).

+ In this variant,

+ the literal characters `+^.[$()|*+?{+` need to be backslash escaped.

+ Because rpm interprets backslashes as part of its parsing of spec files,

+ you will need to use a *double backslash* for any escapes.

+ A literal backslash ("`+\+`") is represented by four backslashes.

+ 

+ The regex engine is only passed the final string, after rpm macro expansion.

+ So you can't use unescaped data via rpm macros.

+ For instance, if you generate a list of files to match in a macro

+ and that list contains `+libfoo.so+`

+ you'll have to use `+libfoo\\.so+` to escape the ("`+.+`").

+ Example:

  

  ....

  %global to_exclude libfoo\\.so
@@ -36,7 +65,12 @@ 

  

  === Preventing files/directories from being scanned for deps (pre-scan filtering)

  

- The macros `+%__requires_exclude_from+` and `+%__provides_exclude_from+` can be defined in a spec file to keep the dependency generator from scanning specific files or directories for deps. These macros should be defined with a regular expression that matches all of the directories or files. For instance:

+ The macros `+%__requires_exclude_from+` and `+%__provides_exclude_from+`

+ can be defined in a spec file to keep the dependency generator

+ from scanning specific files or directories for deps.

+ These macros should be defined with a regular expression

+ that matches all of the directories or files.

+ For instance:

  

  ....

  # Do not check any files in docdir for requires
@@ -47,15 +81,34 @@ 

  %global __provides_exclude_from ^(%{_libdir}/%{name}/.*\\.so.*|%{_datadir}/myapp/.*)$

  ....

  

- Note that this macro replaces the `+%filter_provides_in+` macro from the old filtering guidelines but it does not do the same thing. In particular:

+ Note that this macro replaces the `+%filter_provides_in+` macro

+ from the old filtering guidelines but it does not do the same thing.

+ In particular:

+ 

+ * The old macro could be invoked multiple times.

+ This one will only use the regex defined last.

  

- * The old macro could be invoked multiple times. This one will only use the regex defined last.

- * The old macro advised against anchoring the beginning of the regex (Using `+^+`). This macro recommends anchoring as it doesn't suffer from the compatibility problems of the old one.

- * With the old macro it was common to specify a directory name to match everything in a directory recursively. With the new macro you may need to specify `+.*+` because you should be anchoring your regular expressions.

+ * The old macro advised against anchoring the beginning of the regex

+ (Using `+^+`).

+ This macro recommends anchoring

+ as it doesn't suffer from the compatibility problems of the old one.

+ * With the old macro it was common to specify a directory name

+ to match everything in a directory recursively.

+ With the new macro you may need to specify `+.*+`

+ because you should be anchoring your regular expressions.

  

  === Filtering provides and requires after scanning

  

- In addition to preventing rpm from scanning files and directories for automatic dependency generation you can also tell rpm to discard a discovered dependency before it records the dependency in the rpm metadata. Use `+__requires_exclude+` and `+__provides_exclude+` for this. These macros should be defined as regular expressions. If an entry that rpm's automatic dependency generator created matches the regular expression then it will be filtered out of the requires or provides. For example:

+ In addition to preventing rpm from scanning

+ files and directories for automatic dependency generation

+ you can also tell rpm to discard a discovered dependency

+ before it records the dependency in the rpm metadata.

+ Use `+__requires_exclude+` and `+__provides_exclude+` for this.

+ These macros should be defined as regular expressions.

+ If an entry that rpm's automatic dependency generator created

+ matches the regular expression

+ then it will be filtered out of the requires or provides.

+ For example:

  

  ....

  # This might be useful if plugins are being picked up by the dependency generator
@@ -66,11 +119,20 @@ 

  %global __requires_exclude ^/usr/bin/python$

  ....

  

- These macros serves a similar purpose to the old `+%filter_from_provides+` macro but it has a different implementation. In particular, that macro took sed expressions whereas this one needs a regular expression.

+ These macros serves a similar purpose to the old

+ `+%filter_from_provides+` macro

+ but it has a different implementation.

+ In particular,

+ that macro took sed expressions whereas this one needs a regular expression.

  

  === Simplified macros for common cases

  

- In some cases, the filtering of extraneous `+Provides:+` is fairly generic to all packages which provide similar things. There are simple macros that setup filters correctly for those cases so that you can do the filtering with one line. If you need to filter a bit more than the simple macro provides, you still have the option to use the macros listed above.

+ In some cases, the filtering of extraneous `+Provides:+`

+ is fairly generic to all packages which provide similar things.

+ There are simple macros that setup filters correctly

+ for those cases so that you can do the filtering with one line.

+ If you need to filter a bit more than the simple macro provides,

+ you still have the option to use the macros listed above.

  

  ==== Perl

  
@@ -80,9 +142,14 @@ 

  %{?perl_default_filter}

  ....

  

- Essentially, this filters dependencies arising from `+%doc+` files, from non-Linux-related modules, and from errors in the automatic dependency generator.

+ Essentially, this filters dependencies arising from `+%doc+` files,

+ from non-Linux-related modules,

+ and from errors in the automatic dependency generator.

  

- If you want to use both custom filters and `+%perl_default_filter+` then define your filters first and call `+%perl_default_filter+` afterwards. The default filter macro will preserve the filters you previously defined. For example:

+ If you want to use both custom filters and `+%perl_default_filter+`

+ then define your filters first and call `+%perl_default_filter+` afterwards.

+ The default filter macro will preserve the filters you previously defined.

+ For example:

  

  ....

  # Filter all provides from some directory
@@ -97,7 +164,12 @@ 

  

  === Pidgin plugin package

  

- On a x86_64 machine, the pidgin-libnotify provides `+pidgin-libnotify.so()(64bit)+` which it shouldn't as this library is not inside the paths searched by the system for libraries. It's a private, not global, "provides" and as such must not be exposed globally by RPM.

+ On a x86_64 machine,

+ the pidgin-libnotify provides `+pidgin-libnotify.so()(64bit)+`

+ which it shouldn't as this library is not inside the paths

+ searched by the system for libraries.

+ It's a private, not global, "provides"

+ and as such must not be exposed globally by RPM.

  

  To filter this out, we could use:

  
@@ -107,20 +179,35 @@ 

  

  === Private Libraries

  

- At this time, filtering of private libraries is non-trivial. This is because the symbols you want to filter from the private libraries are usually required by the public applications that the package ships. In order to filter, you need to find out what symbols rpm is extracting for the private library and then remove those in both `+%__provides_exclude+` and `+%__requires_exclude+`.

- 

- As an example, pretend you are packaging an application foo that creates `+%{_libdir}/foo/libprivate.so+` that you want to filter and `+%{_bindir}/foobar+` that requires that private library. You could:

+ At this time, filtering of private libraries is non-trivial.

+ This is because the symbols you want to filter from the private libraries

+ are usually required by the public applications that the package ships.

+ In order to filter,

+ you need to find out what symbols rpm is extracting for the private library

+ and then remove those in both

+ `+%__provides_exclude+` and `+%__requires_exclude+`.

+ 

+ As an example, pretend you are packaging an application foo that creates

+ `+%{_libdir}/foo/libprivate.so+`

+ that you want to filter and

+ `+%{_bindir}/foobar+`

+ that requires that private library.

+ You could:

  

  * First build the rpm: `+$ rpmbuild -ba foo.spec+`

- * then determine what provides rpm decided for the private library: `+$ rpm -qp foo-1.0-1.x86_64.rpm+`:

+ * then determine what provides rpm decided for the private library:

+ `+$ rpm -qp foo-1.0-1.x86_64.rpm+`:

  

  ....

- libprivate.so()(64bit)  

+ libprivate.so()(64bit)

  foo = 1.0-1.fc19

  foo(x86-64) = 1.0-1.fc19

  ....

  

- * See that `+libprivate.so()(64bit)+` appears to be the only symbol that rpm extracted for this package. Note that on 32bit, the provides will be `+libprivate.so+` so your regex needs to capture both.

+ * See that `+libprivate.so()(64bit)+`

+ appears to be the only symbol that rpm extracted for this package.

+ Note that on 32bit, the provides will be `+libprivate.so+`

+ so your regex needs to capture both.

  +

  * Add the excludes to the spec file for both requires and provides:

  
@@ -132,11 +219,21 @@ 

  [...]

  ....

  

- You can take a look at a https://lists.fedoraproject.org/pipermail/devel/2012-June/169190.html[more complex example] on the mailing list. This can be a pain to maintain if the upstream changes the names of its private libraries but it is the only way to deal with this at present. There may be a better means in https://lists.osuosl.org/pipermail/rpm-maint/2013-January/003349.html[the future] but there are no solid plans on when those might be coded as of yet..

+ You can take a look at a

+ https://lists.fedoraproject.org/pipermail/devel/2012-June/169190.html[more complex example]

+ on the mailing list.

+ This can be a pain to maintain

+ if the upstream changes the names of its private libraries

+ but it is the only way to deal with this at present.

+ There may be a better means in

+ https://lists.osuosl.org/pipermail/rpm-maint/2013-January/003349.html[the future]

+ but there are no solid plans on when those might be coded as of yet..

  

  === Arch-specific extensions to scripting languages

  

- e.g. to ensure an arch-specific `perl-*` package won't provide or require things that it shouldn't, we could use an invocation as such:

+ e.g. to ensure an arch-specific `perl-*` package won't provide

+ or require things that it shouldn't,

+ we could use an invocation as such:

  

  ....

  # we don't want to provide private Perl extension libs
@@ -145,7 +242,10 @@ 

  

  === `+%{_docdir}+` filtering

  

- By policy, nothing under `+%{_docdir}+` is allowed to either "provide" or "require" anything. We can prevent this from happening by preventing anything under `+%{_docdir}+` from being scanned:

+ By policy, nothing under `+%{_docdir}+` is allowed

+ to either "provide" or "require" anything.

+ We can prevent this from happening

+ by preventing anything under `+%{_docdir}+` from being scanned:

  

  ....

  # we don't want to either provide or require anything from _docdir, per policy
@@ -155,4 +255,5 @@ 

  

  == Additional Information

  

- Additional information about RPM's dependency generator can be found here: https://rpm-software-management.github.io/rpm/manual/dependency_generators.html

+ Additional information about RPM's dependency generator can be found here:

+ https://rpm-software-management.github.io/rpm/manual/dependency_generators.html

@@ -3,7 +3,9 @@ 

  = CMake Packaging Guidelines

  :toc:

  

- This document provides best practices for the usage of https://cmake.org/[the CMake build system] in Fedora packages.

+ This document provides best practices for the usage of

+ https://cmake.org/[the CMake build system]

+ in Fedora packages.

  

  == Build Dependencies

  
@@ -18,33 +20,68 @@ 

  You will generally make use of these in your specs:

  

  `+%cmake+`::

-   Defines CFLAGS, LDFLAGS, etc. and calls `+%__cmake+` with appropriate parameters (`+-DCMAKE_INSTALL_PREFIX:PATH=/usr+` and such). You can pass `+-Doption=value+` to this macro in order to set options for the buildsystem.

+ Defines CFLAGS, LDFLAGS, etc. and calls `+%__cmake+`

+ with appropriate parameters

+ (`+-DCMAKE_INSTALL_PREFIX:PATH=/usr+` and such).

+ You can pass `+-Doption=value+` to this macro

+ in order to set options for the buildsystem.

+ 

  `+%cmake_build+`::

-   Builds the project (using `+%__cmake --build+`).

+ Builds the project (using `+%__cmake --build+`).

+ 

  `+%cmake_install+`::

-   Installs the built project (using `+%__cmake --install+`).

+ Installs the built project (using `+%__cmake --install+`).

+ 

  `+%ctest+`::

-   Runs the tests that are defined with `+add_test()+` in project (using `+%__ctest+`).

+ Runs the tests that are defined with `+add_test()+`

+ in project (using `+%__ctest+`).

  

- When packaging KDE software, you most likely would replace `+%cmake+` with `+%cmake_kf5+` that defines multiple KDE-related variables (shipped in `+kf5+` package).

+ When packaging KDE software,

+ you most likely would replace `+%cmake+` with `+%cmake_kf5+`

+ that defines multiple KDE-related variables (shipped in `+kf5+` package).

  

  It is rarely necessary (but permissible) to use or alter these:

- NOTE: All macros starting with double underscore is meant to be private, NOT stable and likely to be removed in the future.

+ NOTE: All macros starting with double underscore is meant to be private,

+ NOT stable and likely to be removed in the future.

  

  `+%__cmake+`::

-   The path to the cmake executable.

+ The path to the cmake executable.

+ 

  `+%__ctest+`::

-   The path to the ctest executable.

+ The path to the ctest executable.

+ 

  `+%__cmake_in_source_build+`::

-   Controls whether builds are done in-source (when defined) or out-of-source (when undefined).

-   See the xref:vpath.adoc[Defining source and build directories] for more information.

+ Controls whether builds are done in-source (when defined)

+ or out-of-source (when undefined).

+ See the xref:vpath.adoc[Defining source and build directories]

+ for more information.

+ 

  `+%__cmake_builddir+`::

-   Holds the location of the actual directory where the build was made.

-   When making https://fedoraproject.org/wiki/Changes/CMake_to_do_out-of-source_builds[out-of-source builds], this macro is the same as %_vpath_builddir, which should be used preferably in such cases.

-   See the xref:vpath.adoc[Defining source and build directories] for more information.

-   When doing in-source builds (that means before Fedora 33 https://fedoraproject.org/wiki/Changes/CMake_to_do_out-of-source_builds[out-of-source builds] change), this macro would differ from %_vpath_builddir and it will hold the actual location that was used for the build.

-   This is useful in cases, when you want to use the same SPECfile for different Fedora releases where on some the build is in-source and on some out-of-source AND you need to know the builddir location - e.g. when using "cmake -B %__cmake_builddir -LH" inbetween of %cmake and "%cmake_build". Whenever possible, using out-of-source builds is advised, as this is the direction both Fedora and CMake upstream bears. 

-   Warning: This macro is suitable only for rare compatibility reasons. Once all active Fedora releases will use https://fedoraproject.org/wiki/Changes/CMake_to_do_out-of-source_builds[out-of-source builds], this macro will be redundant (same as %_vpath_builddir) and removed.

+ Holds the location of the actual directory where the build was made.

+ When making

+ https://fedoraproject.org/wiki/Changes/CMake_to_do_out-of-source_builds[out-of-source builds],

+ this macro is the same as %_vpath_builddir,

+ which should be used preferably in such cases.

+ See the xref:vpath.adoc[Defining source and build directories]

+ for more information.

+ When doing in-source builds (that means before Fedora 33

+ https://fedoraproject.org/wiki/Changes/CMake_to_do_out-of-source_builds[out-of-source builds]

+ change),

+ this macro would differ from %_vpath_builddir

+ and it will hold the actual location that was used for the build.

+ This is useful in cases,

+ when you want to use the same SPECfile for different Fedora releases

+ where on some the build is in-source and on some out-of-source

+ AND you need to know the builddir location -

+ e.g. when using "cmake -B %__cmake_builddir -LH"

+ inbetween of %cmake and "%cmake_build".

+ Whenever possible, using out-of-source builds is advised,

+ as this is the direction both Fedora and CMake upstream bears.

+ 

+ Warning: This macro is suitable only for rare compatibility reasons.

+ Once all active Fedora releases will use

+ https://fedoraproject.org/wiki/Changes/CMake_to_do_out-of-source_builds[out-of-source builds],

+ this macro will be redundant (same as %_vpath_builddir) and removed.

  

  == Example usage in the spec file

  
@@ -62,17 +99,25 @@ 

  

  == Notes

  

- NOTE: Since Fedora 33, `+%__cmake_in_source_build+` is not defined so if you want to have consistent behavior across different releases, make sure to `+%define+` or `+%undefine+` it accordingly.

+ NOTE: Since Fedora 33, `+%__cmake_in_source_build+` is not defined

+ so if you want to have consistent behavior across different releases,

+ make sure to `+%define+` or `+%undefine+` it accordingly.

  

  *NOTE*: `+-DCMAKE_SKIP_RPATH:BOOL=ON+`.

  With recent cmake-2.4, it should not be used.

- This CMake version should handle RPATHs issues correctly (set them in build-dir, remove them during installation).

- Setting `+CMAKE_SKIP_RPATH+` for this version would avoid RPATHs in build-dir too.

- This might link binaries against system-libraries (e.g. when a previous version of the package was installed) instead of the libraries which were created by the build.

+ This CMake version should handle RPATHs issues correctly

+ (set them in build-dir, remove them during installation).

+ Setting `+CMAKE_SKIP_RPATH+` for this version

+ would avoid RPATHs in build-dir too.

+ This might link binaries against system-libraries

+ (e.g. when a previous version of the package was installed)

+ instead of the libraries which were created by the build.

  

  Nevertheless, RPATH issues might arise when CMake was used improperly.

- For example, installing a target with `+INSTALL(FILES ... RENAME ...)+` will *not* strip rpaths;

- in this case `+INSTALL(TARGETS ...)+` must be used in combination with changing the `+OUTPUT_NAME+` property.

+ For example, installing a target with `+INSTALL(FILES ... RENAME ...)+`

+ will *not* strip rpaths;

+ in this case `+INSTALL(TARGETS ...)+` must be used

+ in combination with changing the `+OUTPUT_NAME+` property.

  

  *NOTE*: CMake has good documentation in two places:

  

@@ -4,35 +4,76 @@ 

  

  == Introduction

  

- The C and {cpp} languages and runtimes are one of the most common development frameworks for packages in fedora. As such there is a wide variety of quality, style, and convention in all of those packages. The follow document provides best practice for certain aspects of C and {cpp} packaging.

+ The C and {cpp} languages and runtimes

+ are one of the most common development frameworks for packages in fedora.

+ As such there is a wide variety of quality, style, and convention

+ in all of those packages.

+ The follow document provides best practice

+ for certain aspects of C and {cpp} packaging.

  

  == Packaging

  

  === BuildRequires and Requires

  

- If your application is a C or {cpp} application you must list a `BuildRequires` against `gcc`, `gcc-c{pp}` or `clang`. Those packages will include everything that is required to build a standards conforming C or {cpp} application.

- 

- If your library includes standard C or {cpp} headers, you must list `BuildRequires` against `gcc`, `gcc-c{pp}`, or `clang` to install the needed standards conforming headers.

- 

- If at runtime you use `cpp` to process C or {cpp} language headers then you have no choice but to use `Requires` for `gcc`, `gcc-c{pp}`, or `clang` to install the required headers for a standard conforming C or {cpp} application. In the future this might change if a set of standard C or {cpp} language headers are provided by a special-purpose provides e.g. `c-headers` or `c{pp}-headers`.

- 

- You need not include a `BuildRequires` or `Requires` on `glibc-headers`, or any other core C or {cpp} implementation package unless you have a specific and special need e.g. static compilation requires the `.*-static` library packages e.g. `BuildRequires: glibc-static`. The default use case of a dynamically compiled C or {cpp} application is taken care of by the `gcc`, `gcc-c{pp}`, and `clang` packages.

- 

- Please refer to xref:index.adoc#compiler[Compiler Guidelines] for the list of supported compilers for C and {cpp} compilers.

+ If your application is a C or {cpp} application

+ you must list a `BuildRequires` against `gcc`, `gcc-c{pp}` or `clang`.

+ Those packages will include everything that is required

+ to build a standards conforming C or {cpp} application.

+ 

+ If your library includes standard C or {cpp} headers,

+ you must list `BuildRequires` against `gcc`, `gcc-c{pp}`, or `clang`

+ to install the needed standards conforming headers.

+ 

+ If at runtime you use `cpp` to process C or {cpp} language headers

+ then you have no choice but to use `Requires` for `gcc`, `gcc-c{pp}`, or `clang`

+ to install the required headers

+ for a standard conforming C or {cpp} application.

+ In the future this might change

+ if a set of standard C or {cpp} language headers are provided

+ by a special-purpose provides e.g. `c-headers` or `c{pp}-headers`.

+ 

+ You need not include a `BuildRequires` or `Requires` on `glibc-headers`,

+ or any other core C or {cpp} implementation package

+ unless you have a specific and special need

+ e.g. static compilation requires the `.*-static` library packages

+ e.g. `BuildRequires: glibc-static`.

+ The default use case of a dynamically compiled C or {cpp} application

+ is taken care of by the `gcc`, `gcc-c{pp}`, and `clang` packages.

+ 

+ Please refer to xref:index.adoc#compiler[Compiler Guidelines]

+ for the list of supported compilers for C and {cpp} compilers.

  

  === Packaging Q&A

  

  [qanda]

  Do I need a `Requires: glibc` to ensure I have the C runtime installed for my application?::

-   No. RPM will automatically determine what ELF libraries you need based on the binaries in your package. This is sufficient to cause glibc to be installed.

+ No.

+ RPM will automatically determine what ELF libraries you need

+ based on the binaries in your package.

+ This is sufficient to cause glibc to be installed.

+ 

  Do I need to include a `Requires: libgcc`?::

-   If you are using an API from `libgcc` directly, then yes, you must have a `Requires: libgcc`. In general though `glibc` requires `libgcc`, so it is always installed.

+ If you are using an API from `libgcc` directly,

+ then yes, you must have a `Requires: libgcc`.

+ In general though `glibc` requires `libgcc`, so it is always installed.

  

  == Libraries

  

- Libraries should have unique shared object names (SONAMEs via `-Wl,-soname=libfoo.so`) that do not conflict with other library SONAMEs used in the distribution. For example there should be only one `libfoo.so` in the distribution. The exception is when there are multiple implementations of the same library `libfoo.so` provided by different authors and each conflicts with the other. In this case both `libfoo.so` must provide exactly the same interface, but with a different implementation. Having two `libfoo.so` each with a different API is bad practice and makes it harder to package and distribute those packages.

- 

- Libraries should version all of their symbols using a version script. Versioning allows the library to avoid changing the SONAME when the API changes and instead compatibility functions can be written to provide backwards compatibility for older applications.

+ Libraries should have unique shared object names

+ (SONAMEs via `-Wl,-soname=libfoo.so`)

+ that do not conflict with other library SONAMEs used in the distribution.

+ For example there should be only one `libfoo.so` in the distribution.

+ The exception is when there are multiple implementations of the same library

+ `libfoo.so` provided by different authors and each conflicts with the other.

+ In this case both `libfoo.so` must provide exactly the same interface,

+ but with a different implementation.

+ Having two `libfoo.so` each with a different API is bad practice

+ and makes it harder to package and distribute those packages.

+ 

+ Libraries should version all of their symbols using a version script.

+ Versioning allows the library to avoid changing the SONAME when the API changes

+ and instead compatibility functions can be written

+ to provide backwards compatibility for older applications.

  

  == Applications

  

@@ -7,21 +7,53 @@ 

  

  == Conflicts

  

- Users should always be able to install the latest packages from Fedora's repos regardless of what other Fedora packages are installed. Therefore, whenever possible, the latest Fedora packages of a release should avoid conflicting with each other. Conflicts result in a transaction set where the user has to decipher the error message and make some sort of decision. The transaction set doesn't provide information to the user about why two packages conflict to help them make an informed decision.

- 

- As Fedora packagers, we try to make it so that any subset of latest Fedora's packages will install and run. Unfortunately, this is not always possible but we can usually make it so that conflicting packages can be installed and the user can decide which package to enable afterwards. In the few remaining cases, we have to use `+Conflicts:+` tags. These guidelines illustrate how conflicts should be handled in Fedora, specifically concerning when and when not to use the `+Conflicts:+` field.

+ Users should always be able to install the latest packages from Fedora's repos

+ regardless of what other Fedora packages are installed.

+ Therefore, whenever possible,

+ the latest Fedora packages of a release

+ should avoid conflicting with each other.

+ Conflicts result in a transaction set

+ where the user has to decipher the error message

+ and make some sort of decision.

+ The transaction set doesn't provide information to the user

+ about why two packages conflict to help them make an informed decision.

+ 

+ As Fedora packagers,

+ we try to make it so that any subset of latest Fedora's packages

+ will install and run.

+ Unfortunately, this is not always possible

+ but we can usually make it so that conflicting packages can be installed

+ and the user can decide which package to enable afterwards.

+ In the few remaining cases, we have to use `+Conflicts:+` tags.

+ These guidelines illustrate how conflicts should be handled in Fedora,

+ specifically concerning when and when not to use the `+Conflicts:+` field.

  

  == Acceptable Uses of Conflicts:

  

- As a general rule, Fedora packages must NOT contain any usage of the `+Conflicts:+` field. This field is commonly misused, when a `+Requires:+` would usually be more appropriate. It confuses depsolvers and end-users for no good reason. However, there are some cases in which using the `+Conflicts:+` field is appropriate and acceptable.

+ As a general rule,

+ Fedora packages must NOT contain any usage of the `+Conflicts:+` field.

+ This field is commonly misused,

+ when a `+Requires:+` would usually be more appropriate.

+ It confuses depsolvers and end-users for no good reason.

+ However, there are some cases in which using the `+Conflicts:+` field

+ is appropriate and acceptable.

  

  === Implicit Conflicts

  

- Keep in mind that implicit conflicts are NEVER acceptable. If your package conflicts with another package, then you must either resolve the conflict, or mark it with `+Conflicts:+`.

+ Keep in mind that implicit conflicts are NEVER acceptable.

+ If your package conflicts with another package,

+ then you must either resolve the conflict, or mark it with `+Conflicts:+`.

  

  === Optional Functionality

  

- Some software can utilize other optional software applications if present, but do not require them to be installed. If they are not installed, the software will still function properly. However, if those other "optional applications" are too old, then the software won't work. This is an acceptable use of the `+Conflicts:+` field. The packager must document the reason in a comment above the `+Conflicts:+` field:

+ Some software can utilize other optional software applications if present,

+ but do not require them to be installed.

+ If they are not installed, the software will still function properly.

+ However, if those other "optional applications" are too old,

+ then the software won't work.

+ This is an acceptable use of the `+Conflicts:+` field.

+ The packager must document the reason in a comment

+ above the `+Conflicts:+` field:

  

  *Example:*

  
@@ -29,60 +61,120 @@ 

  Conflicts: unrar < 2.0

  ....

  

- If the software links to the libraries of another package, it must use `+Requires:+` instead of `+Conflicts:+` to mark that dependency. Also, if the software does not function properly without another package being installed, it must use `+Requires:+` instead of `+Conflicts:+`.

+ If the software links to the libraries of another package,

+ it must use `+Requires:+` instead of `+Conflicts:+` to mark that dependency.

+ Also, if the software does not function properly

+ without another package being installed,

+ it must use `+Requires:+` instead of `+Conflicts:+`.

  

  The packager should ask:

  

- _If the package (at the correct version) in Conflicts: is not present, will my package be functional?_

+ _If the package (at the correct version) in Conflicts: is not present,

+ will my package be functional?_

  

- If the answer is yes, then it is probably a valid use of `+Conflicts:+`. If the answer is no, then it is almost certainly a better case for `+Requires:+`.

+ If the answer is yes, then it is probably a valid use of `+Conflicts:+`.

+ If the answer is no,

+ then it is almost certainly a better case for `+Requires:+`.

  

- For example, if foo-game needs libbar to run, but will not work with libbar that is older than 1.2.3:

+ For example, if foo-game needs libbar to run,

+ but will not work with libbar that is older than 1.2.3:

  

  *WRONG:* Conflicts: libbar < 1.2.3 +

  *RIGHT:* Requires: libbar >= 1.2.3 +

- Packagers should keep usage of `+Conflicts:+` to a bare minimum. Only upgrading from two previous release of Fedora is supported, so Conflicts against older packages than that, while technically correct, are unnecessary, and should not be included.

+ Packagers should keep usage of `+Conflicts:+` to a bare minimum.

+ Only upgrading from two previous release of Fedora is supported,

+ so Conflicts against older packages than that, while technically correct,

+ are unnecessary, and should not be included.

  

  === Splitting Packages

  

- If contents from one package are split into a separate package the new package usually contains files that also appear in the original package which might lead to a implicit conflict between the files in the new package and the original package. Where the new package depends on the original package, this can be resolved with a versioned Requires:

+ If contents from one package are split into a separate package

+ the new package usually contains files that also appear in the original package

+ which might lead to a implicit conflict

+ between the files in the new package and the original package.

+ Where the new package depends on the original package,

+ this can be resolved with a versioned Requires:

  

  ....

  # In the new package's spec file:

  Requires: original-package > EVR_BEFORE_SPLIT

  ....

  

- If the new package should be installable independently of whether the original package is installed, a versioned conflict is allowed:

+ If the new package should be installable

+ independently of whether the original package is installed,

+ a versioned conflict is allowed:

  

  ....

  # In the new package's spec file:

  Conflicts: original-package <= EVR_BEFORE_SPLIT

  ....

  

- In both of these cases, the new version of the original package should be updated to not contain the conflicting files and to depend on the new package (at least in all stable Fedora releases). This allows to install the latest releases of both packages without any problem. The Conflicts are only there to resolve the case where the new package is installed and the older version of the original package was already installed.

+ In both of these cases,

+ the new version of the original package should be updated

+ to not contain the conflicting files

+ and to depend on the new package

+ (at least in all stable Fedora releases).

+ This allows to install the latest releases of both packages without any problem.

+ The Conflicts are only there to resolve the case

+ where the new package is installed

+ and the older version of the original package was already installed.

  

  === Compat Package Conflicts

  

- It is acceptable to use `+Conflicts:+` in some cases involving compat packages. These are the cases where it is not feasible to patch applications to look in alternate locations for the -compat files, so the foo-devel and foo-compat-devel packages need to `+Conflict:+`. Whenever possible, this should be avoided.

+ It is acceptable to use `+Conflicts:+` in some cases involving compat packages.

+ These are the cases where it is not feasible to patch applications

+ to look in alternate locations for the -compat files,

+ so the foo-devel and foo-compat-devel packages need to `+Conflict:+`.

+ Whenever possible, this should be avoided.

  

  === Incompatible Binary Files with Conflicting Naming (and stubborn upstreams)

  

- In the specific case where multiple software components generate identically named (but incompatible) binaries, Fedora Packagers should make every effort to convince the upstreams to rename the binaries to resolve the conflict (see: xref:#_binary_name_conflicts[Binary Name Conflicts]). However, if neither upstream is willing to rename the binaries to resolve the conflict, *AND* the binaries are not viable candidates for alternatives or environment modules (incompatible runtimes), as long as there are no clear cases for both packages to be installed simultaneously, explicit Conflicts are permitted at the packager's discretion. Both packages must carry Conflicts in this case.

- 

- Be aware, adding explicit Conflicts means that if any other packages depend on your package, you may be creating a chain-of-conflicts that could cause user pain. Please consider this as a last resort.

+ In the specific case

+ where multiple software components generate identically named

+ (but incompatible) binaries,

+ Fedora Packagers should make every effort to convince the upstreams

+ to rename the binaries to resolve the conflict

+ (see: xref:#_binary_name_conflicts[Binary Name Conflicts]).

+ However, if neither upstream is willing to rename the binaries

+ to resolve the conflict,

+ *AND* the binaries are not viable candidates for alternatives

+ or environment modules (incompatible runtimes),

+ as long as there are no clear cases for both packages

+ to be installed simultaneously,

+ explicit Conflicts are permitted at the packager's discretion.

+ Both packages must carry Conflicts in this case.

+ 

+ Be aware, adding explicit Conflicts means that

+ if any other packages depend on your package,

+ you may be creating a chain-of-conflicts that could cause user pain.

+ Please consider this as a last resort.

  

  == Common Conflicting Files Cases and Solutions

  

- There are many types of files which can conflict between multiple packages. Fedora strongly discourages using `+Conflicts:+` to resolve these cases. Here are some suggestions which can be used to resolve these conflicts (note that not all file conflict cases are listed, nor are all possible solutions):

+ There are many types of files which can conflict between multiple packages.

+ Fedora strongly discourages using `+Conflicts:+` to resolve these cases.

+ Here are some suggestions which can be used to resolve these conflicts

+ (note that not all file conflict cases are listed,

+ nor are all possible solutions):

  

  === Man Page Name Conflicts

  

- * Rename the man pages to slightly alter the suffix of the man page (e.g man1/check.1.gz and man1/check.1foo.gz)

- * Rename the man pages to include a prefix of the providing package (e.g. foo-check.1.gz and bar-check.1.gz)

+ * Rename the man pages to slightly alter the suffix of the man page

+ (e.g man1/check.1.gz and man1/check.1foo.gz)

+ 

+ * Rename the man pages to include a prefix of the providing package

+ (e.g. foo-check.1.gz and bar-check.1.gz)

  

  === Library Name Conflicts

  

- If the library is 100% ABI-compatible, you can use xref:EnvironmentModules.adoc[Environment Modules] to let the user switch between them. If the library is not 100% ABI-compatible get one of the upstreams to rename. See xref:#_approaching_upstream[Approaching Upstream] for ideas on persuasion. If neither upstream will budge open a ticket for FPC to evaluate what sort of hoops both packages would need to implement to not conflict at runtime.

+ If the library is 100% ABI-compatible, you can use

+ xref:EnvironmentModules.adoc[Environment Modules]

+ to let the user switch between them.

+ If the library is not 100% ABI-compatible get one of the upstreams to rename.

+ See xref:#_approaching_upstream[Approaching Upstream] for ideas on persuasion.

+ If neither upstream will budge open a ticket for FPC

+ to evaluate what sort of hoops both packages would need to implement

+ to not conflict at runtime.

  

  === Header Name Conflicts

  
@@ -90,50 +182,111 @@ 

  

  === Binary Name Conflicts

  

- * Convince upstream to rename the binaries to something less generic (or just less conflicting).

- * In the case where the conflicting binaries provide the same functionality, you can then rename the binaries with a prefix, and use xref:Alternatives.adoc[Alternatives] to let the system administrator select which generic name is the default. Note that this is usually not the case.

- * In cases where the binaries provide similar functionality xref:EnvironmentModules.adoc[EnvironmentModules] may be an option. This is more flexible than alternatives and is for things that each individual on a system may want to choose between rather than a system administrator.

- 

- === Approaching Upstream

+ * Convince upstream to rename the binaries to something less generic

+ (or just less conflicting).

+ * In the case where the conflicting binaries provide the same functionality,

+ you can then rename the binaries with a prefix,

+ and use xref:Alternatives.adoc[Alternatives]

+ to let the system administrator select which generic name is the default.

+ Note that this is usually not the case.

  

- When renaming or putting files into subdirectories, it is a good idea to try

- to get upstream to rename their conflicting files (for instance if they both had commands named %\{_bindir}/trash). Doing some research about which has been around longer may be useful in this case but may or may not be persuasive to upstream.

+ * In cases where the binaries provide similar functionality

+ xref:EnvironmentModules.adoc[EnvironmentModules] may be an option.

+ This is more flexible than alternatives

+ and is for things that each individual on a system may want to choose between

+ rather than a system administrator.

  

- If neither upstream renames, we would then approach other distributions (distributions-list[at]freedesktop.org is a good place to discuss this) about renaming that can be done in all distros. That helps end users going from one distro to another to have consistency. Length of time that the projects have been around, how popular each is, and numerous other factors may play a role in this decision. Once a decision is made, we would rename the Fedora packages to match.

  

- == Potential Conflicting Files

- 

- We don't just try to avoid conflicts with existing packages within Fedora but

- also potential conflicts. This is because the first package to enter Fedora is

- not always the one that should take on the name. There are several scenarios

- in which this could come into play:

+ === Approaching Upstream

  

- 1.  There is a conflicting package that is not in Fedora yet (found by doing a web search, for instance)

- 2.  There is no conflict yet but the filename is likely to be used by another project (something like `+/usr/bin/parser+`)

+ When renaming or putting files into subdirectories,

+ it is a good idea to try to get upstream to rename their conflicting files

+ (for instance if they both had commands named %\{_bindir}/trash).

+ Doing some research about which has been around longer may be useful

+ in this case but may or may not be persuasive to upstream.

+ 

+ If neither upstream renames, we would then approach other distributions

+ (distributions-list[at]freedesktop.org is a good place to discuss this)

+ about renaming that can be done in all distros.

+ That helps end users going from one distro to another to have consistency.

+ Length of time that the projects have been around,

+ how popular each is,

+ and numerous other factors may play a role in this decision.

+ Once a decision is made, we would rename the Fedora packages to match.

  

- In the first case, where a conflicting package is known to exist but is not yet in Fedora, we should go through the process of determining which package has a more valid claim to the name and rename the files in the package we're including if it doesn't have the more valid claim. If you think your situation is unique, please send email to fedora-devel-list[at]redhat.com to make your case.

+ == Potential Conflicting Files

  

- In the second case, where there is no known package to conflict with at this time, it is up to the packager to make a decision. Note that it is encouraged that you at least speak to upstream about the potential for conflicts. However, we can hope that any later projects that attempt to use that name can be persuaded to rename based on this project being around longer.

+ We don't just try to avoid conflicts with existing packages within Fedora

+ but also potential conflicts.

+ This is because the first package to enter Fedora

+ is not always the one that should take on the name.

+ There are several scenarios in which this could come into play:

+ 

+ 1.  There is a conflicting package that is not in Fedora yet

+ (found by doing a web search, for instance)

+ 

+ 2.  There is no conflict yet

+ but the filename is likely to be used by another project

+ (something like `+/usr/bin/parser+`)

+ 

+ In the first case, where a conflicting package is known to exist

+ but is not yet in Fedora,

+ we should go through the process of determining

+ which package has a more valid claim to the name

+ and rename the files in the package we're including

+ if it doesn't have the more valid claim.

+ If you think your situation is unique, please send email to

+ fedora-devel-list[at]redhat.com to make your case.

+ 

+ In the second case,

+ where there is no known package to conflict with at this time,

+ it is up to the packager to make a decision.

+ Note that it is encouraged that you at least speak to upstream

+ about the potential for conflicts.

+ However, we can hope that any later projects that attempt to use that name

+ can be persuaded to rename based on this project being around longer.

  

  === Standard Commands

  

- Common names are allowed for standard commands since those will be the

- only commands to implement them. Standard commands include things

- provided for in published and widely implemented standards like POSIX

- and de facto standards such as a program that has traditionally been

- shipped with a certain filename as part of a large number of Unix

- variants. If in doubt, send a message to fedora-devel-list[at]redhat.com

- with details of what standards

- the command appears in, how long it's been available on what Unix

- systems, and whether you've found any conflicting programs that

- implement a substantially different command with the same filename.

+ Common names are allowed for standard commands

+ since those will be the only commands to implement them.

+ Standard commands include

+ things provided for in published and widely implemented standards like POSIX

+ and de facto standards

+ such as a program that has traditionally been shipped

+ with a certain filename

+ as part of a large number of Unix variants.

+ If in doubt, send a message to fedora-devel-list[at]redhat.com

+ with details of what standards the command appears in,

+ how long it's been available on what Unix systems,

+ and whether you've found any conflicting programs

+ that implement a substantially different command with the same filename.

  

  == Conflicting Package Names

  

- Just as files can conflict, package names can as well. Conflicting package names *MUST* be resolved. Package names which differ only in case are still considered to be conflicting. You should follow the same basic steps outlined in xref:#_approaching_upstream[Approaching Upstream].

+ Just as files can conflict, package names can as well.

+ Conflicting package names *MUST* be resolved.

+ Package names which differ only in case are still considered to be conflicting.

+ You should follow the same basic steps outlined in

+ xref:#_approaching_upstream[Approaching Upstream].

  

- Renaming packages and replacing them with others can be difficult if it has to occur at a later time (for instance, upgrade paths can become complex in these situations) so it is even more important to be aware of potential conflicts here than it is with filenames.

+ Renaming packages and replacing them with others can be difficult

+ if it has to occur at a later time

+ (for instance, upgrade paths can become complex in these situations)

+ so it is even more important to be aware of potential conflicts here

+ than it is with filenames.

  

  == Other Uses of Conflicts:

  

- If you find yourself in a situation where you feel that your package has to conflict with another package (either explicitly or implicitly), but does not fit the documented accepted cases above, then you need to make your case to the https://pagure.io/packaging-committee[Fedora Packaging Committee]. If they agree, then, and only then can you use `+Conflicts:+` in a Fedora package. Remember, whenever you use `+Conflicts:+`, you are also required to include the reasoning in a comment next to the `+Conflicts:+` entry, so that it will be abundantly clear why it needed to exist.

+ If you find yourself in a situation

+ where you feel that your package has to conflict with another package

+ (either explicitly or implicitly),

+ but does not fit the documented accepted cases above,

+ then you need to make your case to the

+ https://pagure.io/packaging-committee[Fedora Packaging Committee].

+ If they agree, then, and only then

+ can you use `+Conflicts:+` in a Fedora package.

+ Remember, whenever you use `+Conflicts:+`,

+ you are also required to include the reasoning

+ in a comment next to the `+Conflicts:+` entry,

+ so that it will be abundantly clear why it needed to exist.

@@ -2,16 +2,30 @@ 

  

  This document describes the guidelines for packaging cron job files in Fedora.

  

- For the purposes of these guidelines, a cron job file is defined as a script (e.g., a shell script or a Perl script). These cron job files are scheduled to run on regular intervals by a cron daemon.

+ For the purposes of these guidelines,

+ a cron job file is defined as a script (e.g., a shell script or a Perl script).

+ These cron job files are scheduled to run on regular intervals by a cron daemon.

  

  == Cron Job Files on the filesystem

  

- Packages with cron job files must place those cron job files into one or more of the following directories /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly depending on the intended interval they should run.

+ Packages with cron job files must place those cron job files into

+ one or more of the following directories

+ /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly

+ depending on the intended interval they should run.

  

  There is an exception to this rule:

- If a certain cron job has to be executed at some frequency or at a specific time interval other than the above, then a custom crontab file should be added to /etc/cron.d (with 0640 permissions). In this case, the cron job file (the script) must be placed in an appropriate system location (e.g. %\{_sbindir}, %\{_libexecdir}), and NOT in /etc/cron.d.

- 

- Both cron job files and crontab definition files installed in any of these directories must be treated as configuration files so that they can easily be modified by the local system administrator.

+ If a certain cron job has to be executed at some frequency

+ or at a specific time interval other than the above,

+ then a custom crontab file should be added to /etc/cron.d

+ (with 0640 permissions).

+ In this case, the cron job file (the script)

+ must be placed in an appropriate system location

+ (e.g. %\{_sbindir}, %\{_libexecdir}), and NOT in /etc/cron.d.

+ 

+ Both cron job files and crontab definition files

+ installed in any of these directories

+ must be treated as configuration files

+ so that they can easily be modified by the local system administrator.

  

  == Cron Job file

  
@@ -27,7 +41,8 @@ 

  exit 0

  ....

  

- Example of crontab definition run at ever other hour specified in /etc/cron.d/example

+ Example of crontab definition run at ever other hour

+ specified in /etc/cron.d/example

  

  ....

  # .---------------- minute (0 - 59)
@@ -43,17 +58,28 @@ 

  

  == Cron job file names

  

- The file name of a cron job file should match the name of the package from which it comes.

+ The file name of a cron job file should match

+ the name of the package from which it comes.

  

- If a package supplies multiple cron job files files in the same directory, the file names should all start with the name of the package followed by a hyphen (-) and a suitable suffix.

+ If a package supplies multiple cron job files files in the same directory,

+ the file names should all start with the name of the package

+ followed by a hyphen (-) and a suitable suffix.

  

  == Cron Job Files Packaging

  

- Cron job file(s) in packages must be marked as %config(noreplace), and their filename(s) should match the name of the package.

+ Cron job file(s) in packages must be marked as %config(noreplace),

+ and their filename(s) should match the name of the package.

  

- Helper files used by cron job files should be placed in appropriate system locations (e.g. %\{_bindir} or %\{_libexecdir}) and do not need to be marked as %config.

+ Helper files used by cron job files should be placed

+ in appropriate system locations

+ (e.g. %\{_bindir} or %\{_libexecdir})

+ and do not need to be marked as %config.

  

- Packages with cron job files must have an explicit `+Requires: crontabs+`. Since `+crontabs+` requires `+/etc/cron.d+` and all cron daemon packages create (and own) that directory, `+crontabs+` serves as a virtual requires for cron daemon functionality.

+ Packages with cron job files must have an explicit

+ `+Requires: crontabs+`.

+ Since `+crontabs+` requires `+/etc/cron.d+`

+ and all cron daemon packages create (and own) that directory,

+ `+crontabs+` serves as a virtual requires for cron daemon functionality.

  

  === Example of cron job packaging

  

@@ -99,7 +99,13 @@ 

  [#ordering]

  == Ordering

  

- The scriptlets in %pre and %post are respectively run before and after a package is installed. The scriptlets %preun and %postun are run before and after a package is uninstalled. The scriptlets %pretrans and %posttrans are run at start and end of a transaction. On upgrade, the scripts are run in the following order:

+ The scriptlets in %pre and %post are respectively run

+ before and after a package is installed.

+ The scriptlets %preun and %postun

+ are run before and after a package is uninstalled.

+ The scriptlets %pretrans and %posttrans

+ are run at start and end of a transaction.

+ On upgrade, the scripts are run in the following order:

  

  1.  %pretrans of new package

  2.  %pre of new package
@@ -112,14 +118,26 @@ 

  9.  %preun of old package

  10. (removal of old package)

  11. %postun of old package

- 12. %triggerpostun of old package (if it's set off by uninstalling the old package)

- 13. %triggerpostun of other packages (if they're set off by uninstalling the old package)

+ 

+ 12. %triggerpostun of old package

+ (if it's set off by uninstalling the old package)

+ 

+ 13. %triggerpostun of other packages

+ (if they're set off by uninstalling the old package)

+ 

  14. %posttrans of new package

  

  [#pretrans]

  === The %pretrans Scriptlet

  

- Note that the `+%pretrans+` scriptlet will, in the particular case of system installation, run before anything at all has been installed. This implies that it cannot have any dependencies at all. For this reason, `+%pretrans+` is best avoided, but if used it MUST (by necessity) be written in Lua. See https://rpm-software-management.github.io/rpm/manual/lua.html for more information.

+ Note that the `+%pretrans+` scriptlet will,

+ in the particular case of system installation,

+ run before anything at all has been installed.

+ This implies that it cannot have any dependencies at all.

+ For this reason, `+%pretrans+` is best avoided,

+ but if used it MUST (by necessity) be written in Lua.

+ See https://rpm-software-management.github.io/rpm/manual/lua.html

+ for more information.

  

  == Writing Scriptlets

  
@@ -127,31 +145,74 @@ 

  

  === Saving state between scriptlets

  

- Sometimes a scriptlet needs to save some state from an earlier running scriptlet in order to use it at a later running scriptlet. This is especially common when trying to optimize the scriptlets. Examples:

- 

- * If a `+%posttrans+` needs to de-register some piece of information when upgrading but the file that has that information is removed when the old package is removed the scriptlets need to save that file during `+%pre+` or `+%post+` so that the script in `+%posttrans+` can access it.

- * If we only want the program in `+%posttrans+` to do its work once per-transaction, we may need to write out a flag file so that the `+%posttrans+` knows whether to perform an action.

- 

- To address these issues scriptlets that run earlier need to write out information that is used in `+%posttrans+`. We recommend using a subdirectory of `+%{_localstatedir}/lib/rpm-state/+` for that. For instance, the eclipse plugin scripts touch a file in `+%{_localstatedir}/lib/rpm-state/eclipse/+` when they're installed. The `+%posttrans+` runs a script that checks if that file exists. If it does, it performs its action and then deletes the file. That way the script only performs its action once per transaction.

+ Sometimes a scriptlet needs to save some state from an earlier running scriptlet

+ in order to use it at a later running scriptlet.

+ This is especially common when trying to optimize the scriptlets.

+ Examples:

+ 

+ * If a `+%posttrans+` needs to de-register some piece of information when upgrading

+ but the file that has that information is removed when the old package is removed

+ the scriptlets need to save that file during `+%pre+` or `+%post+`

+ so that the script in `+%posttrans+` can access it.

+ 

+ * If we only want the program in `+%posttrans+` to do its work once per-transaction,

+ we may need to write out a flag file so that the `+%posttrans+`

+ knows whether to perform an action.

+ 

+ To address these issues scriptlets that run earlier need to write out information

+ that is used in `+%posttrans+`.

+ We recommend using a subdirectory of `+%{_localstatedir}/lib/rpm-state/+`

+ for that.

+ For instance, the eclipse plugin scripts touch a file in

+ `+%{_localstatedir}/lib/rpm-state/eclipse/+` when they're installed.

+ The `+%posttrans+` runs a script that checks if that file exists.

+ If it does, it performs its action and then deletes the file.

+ That way the script only performs its action once per transaction.

  

  === Macros

  

- If RPM file triggers are not appropriate, complex scriptlets which are shared between multiple packages MAY be placed in RPM macros. This has two benefits:

+ If RPM file triggers are not appropriate,

+ complex scriptlets which are shared between multiple packages

+ MAY be placed in RPM macros.

+ This has two benefits:

+ 

+ * The standard package authors only have to remember the macros,

+ not the complex stuff that it does

  

- * The standard package authors only have to remember the macros, not the complex stuff that it does

  * The macros' implementations may change without having to update the package

  

- When writing the macros, the FPC will still want to review the macros (and perhaps include the implementation of the macros in the guideline to show packagers what's happening behind the scenes).

+ When writing the macros, the FPC will still want to review the macros

+ (and perhaps include the implementation of the macros in the guideline

+ to show packagers what's happening behind the scenes).

  

- One principle that the FPC follows is that macros generally don't contain the start of scriptlet tags (for instance, `+%pre+`) because this makes it difficult to do additional work in the scriptlet. This also means that a single macro can not be defined to do things in both `+%pre+` and `+%post+`. Instead, write one macro that performs the actions in `+%pre+` and a separate macro that performs the actions in `+%post+`. This principle makes it so that all spec files can use your macros in the same manner even if they already have a `+%pre+` or `+%post+` defined.

+ One principle that the FPC follows

+ is that macros generally don't contain the start of scriptlet tags

+ (for instance, `+%pre+`)

+ because this makes it difficult to do additional work in the scriptlet.

+ This also means that a single macro can not be defined to do things in both

+ `+%pre+` and `+%post+`.

+ Instead, write one macro that performs the actions in `+%pre+`

+ and a separate macro that performs the actions in `+%post+`.

+ This principle makes it so that all spec files can use your macros

+ in the same manner even if they already have a `+%pre+` or `+%post+` defined.

  

- Of course, in the above situation it is better to use RPM file triggers if at all possible.

+ Of course, in the above situation

+ it is better to use RPM file triggers if at all possible.

  

  == Snippets

  

  === Linker Configuration Files

  

- Packages which place linker configuration files in `+/etc/ld.so.conf.d+` MUST call ldconfig in `+%post+` and `+%postun+` (on all Fedora releases) even if they install no actual libraries. They MUST NOT use the `+%ldconfig+`, `+%ldconfig_post+`, `+%ldconfig_postun+` or `+%ldconfig_scriptlets+` macros to do this, since these macros do not have any effect on Fedora. Instead simply call `+/sbin/ldconfig+` directly in both `+%post+` and `+%postun+` as well as adding the necessary dependencies when necessary:

+ Packages which place linker configuration files in `+/etc/ld.so.conf.d+`

+ MUST call ldconfig in `+%post+` and `+%postun+` (on all Fedora releases)

+ even if they install no actual libraries.

+ They MUST NOT use the

+ `+%ldconfig+`, `+%ldconfig_post+`,

+ `+%ldconfig_postun+` or `+%ldconfig_scriptlets+` macros to do this,

+ since these macros do not have any effect on Fedora.

+ Instead simply call `+/sbin/ldconfig+` directly in both

+ `+%post+` and `+%postun+`

+ as well as adding the necessary dependencies when necessary:

  

  ....

  %post -p /sbin/ldconfig
@@ -174,7 +235,13 @@ 

  [...]

  ....

  

- If the configuration file added to `+/etc/ld.so.conf.d+` specifies a directory into which other packages may install files, and that directory is not located in the directory hierarchy beneath one of `+/lib+`, `+/usr/lib+`, `+/lib64+` or `+/usr/lib64+`, then the package adding the configuration file MUST also include the following file triggers which cause ldconfig to be run automatically when necessary:

+ If the configuration file added to `+/etc/ld.so.conf.d+` specifies a directory

+ into which other packages may install files,

+ and that directory is not located in the directory hierarchy beneath one of

+ `+/lib+`, `+/usr/lib+`, `+/lib64+` or `+/usr/lib64+`,

+ then the package adding the configuration file

+ MUST also include the following file triggers

+ which cause ldconfig to be run automatically when necessary:

  

  ....

  %transfiletriggerin -P 2000000 -- DIRECTORIES
@@ -184,7 +251,9 @@ 

  /sbin/ldconfig

  ....

  

- Replace `+DIRECTORIES+` with the space-separated list of directories which the package adds to the library search path via the configuration files in `+/etc/ld.so.conf.d+`.

+ Replace `+DIRECTORIES+` with the space-separated list of directories

+ which the package adds to the library search path

+ via the configuration files in `+/etc/ld.so.conf.d+`.

  

  === Users and groups

  
@@ -192,9 +261,21 @@ 

  

  === GConf

  

- GConf is a configuration scheme currently used by the GNOME desktop. Programs which use it setup default values in a [NAME] .schemas file which is installed under %\{_sysconfdir}/gconf/schemas/[NAME] .schemas. These defaults are then registered with the gconf daemon which monitors the configuration values and alerts applications when values the applications are interested in change. The schema files also provide documentation about what each value in the configuration system means (which gets displayed when you browse the database in the gconf-editor program).

- 

- For packaging purposes, we have to disable schema installation during build, and also register the values in the [NAME] .schemas file with the gconf daemon on installation and unregister them on removal. Due to the ordering of the scriptlets, this is a four step process.

+ GConf is a configuration scheme currently used by the GNOME desktop.

+ Programs which use it setup default values in a [NAME] .schemas file

+ which is installed under %\{_sysconfdir}/gconf/schemas/[NAME] .schemas.

+ These defaults are then registered with the gconf daemon

+ which monitors the configuration values

+ and alerts applications when values the applications are interested in change.

+ The schema files also provide documentation

+ about what each value in the configuration system means

+ (which gets displayed when you browse the database in the gconf-editor program).

+ 

+ For packaging purposes, we have to disable schema installation during build,

+ and also register the values in the [NAME] .schemas file

+ with the gconf daemon on installation

+ and unregister them on removal.

+ Due to the ordering of the scriptlets, this is a four step process.

  

  Disabling the GConf installation during the package creation can be done like so:

  
@@ -205,7 +286,9 @@ 

  ...

  ....

  

- The GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL environment variable suppresses the installation of the schema during the building of the package. An alternative for some packages is to pass a configure flag:

+ The GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL environment variable

+ suppresses the installation of the schema during the building of the package.

+ An alternative for some packages is to pass a configure flag:

  

  ....

  %build
@@ -213,7 +296,11 @@ 

  ...

  ....

  

- Unfortunately, this configure switch only works if the upstream packager has adapted their Makefile.am to handle it. If the Makefile.am is not configured, this switch won't do anything and you'll need to use the environment variable instead.

+ Unfortunately, this configure switch only works

+ if the upstream packager has adapted their Makefile.am to handle it.

+ If the Makefile.am is not configured,

+ this switch won't do anything

+ and you'll need to use the environment variable instead.

  

  Here's the second part:

  
@@ -286,7 +373,8 @@ 

  

  === Systemd

  

- Packages containing systemd unit files need to use scriptlets to ensure proper handling of those services.

+ Packages containing systemd unit files need to use scriptlets

+ to ensure proper handling of those services.

  Services can either be enabled or disabled by default.

  To determine which case your specific service falls into,

  please refer to FESCo's policy xref:DefaultServices.adoc[here].
@@ -297,7 +385,10 @@ 

  

  ==== Scriptlets

  

- The systemd package provides a set of helper macros to handle systemd scriptlet operations. These macros support systemd "presets", as documented in https://www.freedesktop.org/software/systemd/man/systemd.preset.html[systemd.preset(5)].

+ The systemd package provides a set of helper macros

+ to handle systemd scriptlet operations.

+ These macros support systemd "presets", as documented in

+ https://www.freedesktop.org/software/systemd/man/systemd.preset.html[systemd.preset(5)].

  

  ....

  BuildRequires: systemd-rpm-macros
@@ -313,18 +404,28 @@ 

  %systemd_postun_with_restart apache-httpd.service

  ....

  

- Some services do not support being restarted (e.g. D-Bus and various storage daemons). If your service should not be restarted upon upgrade, then use the following `+%postun+` scriptlet instead of the one shown above:

+ Some services do not support being restarted

+ (e.g. D-Bus and various storage daemons).

+ If your service should not be restarted upon upgrade,

+ then use the following `+%postun+` scriptlet instead of the one shown above:

  

  ....

  %postun

  %systemd_postun apache-httpd.service

  ....

  

- If your package includes one or more systemd units that need to be enabled by default on package installation, they MUST be covered by the xref:DefaultServices.adoc[Fedora preset policy].

+ If your package includes one or more systemd units

+ that need to be enabled by default on package installation,

+ they MUST be covered by the xref:DefaultServices.adoc[Fedora preset policy].

  

  ===== User units

  

- There are additional macros for user units (those installed under `+%_userunitdir+`) that should be used similarly to those for system units. These enable and disable user units according to presets, and are `+%systemd_user_post+` (to be used in `+%post+`) and `+%systemd_user_preun+` (to be used in `+%preun+`).

+ There are additional macros for user units

+ (those installed under `+%_userunitdir+`)

+ that should be used similarly to those for system units.

+ These enable and disable user units according to presets,

+ and are `+%systemd_user_post+` (to be used in `+%post+`)

+ and `+%systemd_user_preun+` (to be used in `+%preun+`).

  

  ....

  BuildRequires: systemd-rpm-macros
@@ -339,10 +440,19 @@ 

  

  ===== Dependencies on the systemd package

  

- If package scriptlets call other systemd tools, for example `systemd-tmpfiles`, the package SHOULD declare appropriate dependencies. The `%systemd_requires` macro is a shortcut to require systemd for the `%pre`, `%post`, and `%postun` scriptlets. Note that those dependencies are **not** required for the `%systemd_{post,preun,postun_with_restart,user_post,user_preun}` macros listed above.

+ If package scriptlets call other systemd tools, for example `systemd-tmpfiles`,

+ the package SHOULD declare appropriate dependencies.

+ The `%systemd_requires` macro is a shortcut to require systemd for the

+ `%pre`, `%post`, and `%postun` scriptlets.

+ Note that those dependencies are **not** required for the

+ `%systemd_{post,preun,postun_with_restart,user_post,user_preun}`

+ macros listed above.

  

- If the package wants to use systemd tools if they are available, but does not want to declare a dependency, then the `%systemd_ordering`

- macro MAY be used as a weaker form of `%systemd_requires` that only declares an ordering during an RPM transaction.

+ If the package wants to use systemd tools if they are available,

+ but does not want to declare a dependency,

+ then the `%systemd_ordering` macro MAY be used

+ as a weaker form of `%systemd_requires`

+ that only declares an ordering during an RPM transaction.

  

  ===== Macro details

  
@@ -353,10 +463,21 @@ 

  

  === Shells

  

- `+/etc/shells+` is a text file which controls whether an application can be used as a system login shell of users. It contains the set of valid shells which can be used in the system. If you are packaging a new shell, you need to add entries to this file that reference the added shells. See: `+man 5 SHELLS+` for more information.

- 

- As this file can be edited by sysadmins, we need to first determine if relevant lines are already in the file.

- If they don't already exist then we just need to echo the shell's binary path to the file. Since the UsrMove Feature in Fedora 17 made `+/bin+` a symlink to `+/usr/bin+` we need to place both paths into the `+/etc/shells+` file. Here is an example of the scriptlet to package with shell named "foo":

+ `+/etc/shells+` is a text file

+ which controls whether an application can be used

+ as a system login shell of users.

+ It contains the set of valid shells which can be used in the system.

+ If you are packaging a new shell,

+ you need to add entries to this file that reference the added shells.

+ See: `+man 5 SHELLS+` for more information.

+ 

+ As this file can be edited by sysadmins,

+ we need to first determine if relevant lines are already in the file.

+ If they don't already exist

+ then we just need to echo the shell's binary path to the file.

+ Since the UsrMove Feature in Fedora 17 made `+/bin+` a symlink to `+/usr/bin+`

+ we need to place both paths into the `+/etc/shells+` file.

+ Here is an example of the scriptlet to package with shell named "foo":

  

  ....

  %post