trivial: make all inline text literal
Signed-off-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
This commit is contained in:
parent
0327e7c8dc
commit
1d0bff1b20
66 changed files with 1387 additions and 1369 deletions
|
|
@ -4,11 +4,11 @@ This document describes the current policies for packaging Ada programs and libr
|
|||
|
||||
== Compilation
|
||||
|
||||
* 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.
|
||||
* 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.
|
||||
** For packages that are built with `Gnatmake` or `GPRbuild` but without `Comfignat` there are the macros `%Gnatmake_optflags` and `%GPRbuild_optflags`, which contain builder, compiler and linker flags.
|
||||
** 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 Gnatlink_flags shall be passed to it.
|
||||
** For packages whose build systems use `Comfignat` there is the macro `%Comfignat_make`. 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:
|
||||
** For packages that are built with `+Gnatmake+` or `+GPRbuild+` but without `+Comfignat+` there are the macros `+%Gnatmake_optflags+` and `+%GPRbuild_optflags+`, which contain builder, compiler and linker flags.
|
||||
** 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 Gnatlink_flags shall be passed to it.
|
||||
** For packages whose build systems use `+Comfignat+` there is the macro `+%Comfignat_make+`. 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:
|
||||
+
|
||||
....
|
||||
%build
|
||||
|
|
@ -17,16 +17,16 @@ This document describes the current policies for packaging Ada programs and libr
|
|||
%{Comfignat_make} demo_programs atomic_doodads=true
|
||||
....
|
||||
+
|
||||
For the installation stage of Comfignat-using packages, the macro `%make_install` (*not* `%makeinstall`) is recommended.
|
||||
* The macro GNAT_arches 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 `+%make_install+` (*not* `+%makeinstall+`) is recommended.
|
||||
* The macro GNAT_arches 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.
|
||||
|
||||
== 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. 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 GNAT_add_rpath. The builders will then be allowed to add a runpath in those parts of the spec file where GNAT_add_rpath is defined.
|
||||
|
||||
Packages that contain Ada code *SHOULD* run `%{_rpmconfigdir}/check-rpaths` as the last thing in the `%check` section. This is a precaution against packaging bugs and toolchain bugs that would cause binaries with runpaths to end up in packages. All packages that use GNAT_add_rpath *MUST* do this (and must therefore have a `%check` section).
|
||||
Packages that contain Ada code *SHOULD* run `+%{_rpmconfigdir}/check-rpaths+` as the last thing in the `+%check+` section. This is a precaution against packaging bugs and toolchain bugs that would cause binaries with runpaths to end up in packages. All packages that use GNAT_add_rpath *MUST* do this (and must therefore have a `+%check+` section).
|
||||
|
||||
== Devel packages
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ Packages that contain Ada code *SHOULD* run `%{_rpmconfigdir}/check-rpaths` as t
|
|||
* 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 Directories.Libdir which is defined there. The value of Directories.Libdir 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 Directories.Includedir 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`".
|
||||
* If the "directories" project is used, then the -devel package *MUST* have an explicit "`+Requires: fedora-gnat-project-common+`".
|
||||
* Project files *MUST* have an Externally_Built attribute equal to "true".
|
||||
|
||||
Here's an example of what a project file installed with a library may look like:
|
||||
|
|
@ -57,9 +57,9 @@ end Example;
|
|||
|
||||
== 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}`.
|
||||
* Ada library information files (*.ali) *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.
|
||||
* 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}+`.
|
||||
* Ada library information files (*.ali) *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.
|
||||
|
||||
== Rpmlint and Ada packages
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
__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:
|
||||
`/path/original-file -> /etc/alternatives/packagename-original-file -> /path/original-file.suffix`
|
||||
For more information, see `update-alternatives(8)` manpage.
|
||||
`+/path/original-file -> /etc/alternatives/packagename-original-file -> /path/original-file.suffix+`
|
||||
For more information, see `+update-alternatives(8)+` manpage.
|
||||
|
||||
== Usage within Fedora
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ Inversely, alternatives *MUST NOT* be used when:
|
|||
|
||||
* 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:
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ Cases where parallel installation is desirable but alternatives is unsuitable ma
|
|||
|
||||
== 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:
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ touch %{buildroot}%{_mandir}/man8/sendmail.8
|
|||
|
||||
%postun
|
||||
if [ "$1" -ge "1" ]; then
|
||||
if [ "`readlink %{_sysconfdir}/alternatives/mta`" == "%{_sbindir}/sendmail.sendmail" ]; then
|
||||
if [ "`+readlink %{_sysconfdir}/alternatives/mta+`" == "%{_sbindir}/sendmail.sendmail" ]; then
|
||||
%{_sbindir}/alternatives --set mta %{_sbindir}/sendmail.sendmail
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
__TOC__
|
||||
|
||||
If a package contains a GUI application, then it SHOULD also install a `.appdata.xml` file into `%{_metainfodir}`. Installed `.appdata.xml` files MUST follow the http://people.freedesktop.org/~hughsient/appdata/[AppData specification page].
|
||||
If a package contains a GUI application, then it SHOULD also install a `+.appdata.xml+` file into `+%{_metainfodir}+`. Installed `+.appdata.xml+` files MUST follow the http://people.freedesktop.org/~hughsient/appdata/[AppData specification page].
|
||||
|
||||
If a package contains an add-on for GUI application, then it SHOULD also install a `.metainfo.xml` file into `%{_metainfodir}`. Installed `.metainfo.xml` files MUST follow the http://www.freedesktop.org/software/appstream/docs/sect-Quickstart-Addons.html[AppStream add-ons specification page].
|
||||
If a package contains an add-on for GUI application, then it SHOULD also install a `+.metainfo.xml+` file into `+%{_metainfodir}+`. Installed `+.metainfo.xml+` files MUST follow the http://www.freedesktop.org/software/appstream/docs/sect-Quickstart-Addons.html[AppStream add-ons specification page].
|
||||
|
||||
The AppData files MUST correctly validate using `appstream-util validate-relax`.
|
||||
The AppData files MUST correctly validate using `+appstream-util validate-relax+`.
|
||||
|
||||
== .appdata.xml file creation
|
||||
|
||||
If the package doesn't already include and install its own `.appdata.xml` file, you can make your own and sending it upstream. Benefits of sending the file upstream is that upstream can translate the file using the existing translation resources and can also modify the screenshots and descriptions as the application changes over time. You can do this by including a `.appdata.xml` file you create as a Source: (e.g. Source3: %\{name}.appdata.xml) or generating it in the spec file. Here is the contents of a sample `.appdata.xml` file (comical.appdata.xml):
|
||||
If the package doesn't already include and install its own `+.appdata.xml+` file, you can make your own and sending it upstream. Benefits of sending the file upstream is that upstream can translate the file using the existing translation resources and can also modify the screenshots and descriptions as the application changes over time. You can do this by including a `+.appdata.xml+` file you create as a Source: (e.g. Source3: %\{name}.appdata.xml) or generating it in the spec file. Here is the contents of a sample `+.appdata.xml+` file (comical.appdata.xml):
|
||||
|
||||
....
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
|
@ -51,11 +51,11 @@ If the package doesn't already include and install its own `.appdata.xml` file,
|
|||
</component>
|
||||
....
|
||||
|
||||
The AppData file MUST be named with the same root as the .desktop file, so if the .desktop file is named `org.gnome.SomeApp.desktop` then the AppData file MUST be called `org.gnome.SomeApp.appdata.xml`.
|
||||
The AppData file MUST be named with the same root as the .desktop file, so if the .desktop file is named `+org.gnome.SomeApp.desktop+` then the AppData file MUST be called `+org.gnome.SomeApp.appdata.xml+`.
|
||||
|
||||
== .metainfo.xml file creation
|
||||
|
||||
If the add-on package doesn't already include and install its own `.metainfo.xml` file, you can make your own and sending it upstream. You can do this by including a `.metainfo.xml` file you create as a Source: (e.g. Source4: %\{name}.metainfo.xml) or generating it in the spec file. Here is the contents of a sample `.metainfo.xml` file (gedit-bookmarks.metainfo.xml):
|
||||
If the add-on package doesn't already include and install its own `+.metainfo.xml+` file, you can make your own and sending it upstream. You can do this by including a `+.metainfo.xml+` file you create as a Source: (e.g. Source4: %\{name}.metainfo.xml) or generating it in the spec file. Here is the contents of a sample `+.metainfo.xml+` file (gedit-bookmarks.metainfo.xml):
|
||||
|
||||
....
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
|
@ -71,11 +71,11 @@ If the add-on package doesn't already include and install its own `.metainfo.xml
|
|||
</component>
|
||||
....
|
||||
|
||||
You can use anything as the but it needs to be unique and sensible and also match the `.metainfo.xml` filename prefix.
|
||||
You can use anything as the but it needs to be unique and sensible and also match the `+.metainfo.xml+` filename prefix.
|
||||
|
||||
== app-data-validate usage
|
||||
|
||||
Although you can just include the .appdata.xml or .metainfo.xml files in the package, you MUST run `appstream-util validate-relax` (in `%check` or `%install`) and have `BuildRequires: libappstream-glib`, to help ensure the validity and safety of the appdata files you're installing. An example:
|
||||
Although you can just include the .appdata.xml or .metainfo.xml files in the package, you MUST run `+appstream-util validate-relax+` (in `+%check+` or `+%install+`) and have `+BuildRequires: libappstream-glib+`, to help ensure the validity and safety of the appdata files you're installing. An example:
|
||||
|
||||
....
|
||||
appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/*.appdata.xml
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
== 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.
|
||||
* 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.
|
||||
|
||||
|
|
@ -20,9 +20,9 @@ It's strongly recommended that these filtering macros be invoked before %descrip
|
|||
|
||||
=== 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.
|
||||
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:
|
||||
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
|
||||
|
|
@ -31,7 +31,7 @@ The regex engine is only passed the final string, after rpm macro expansion. So
|
|||
|
||||
=== 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
|
||||
|
|
@ -42,15 +42,15 @@ The macros `%__requires_exclude_from` and `%__provides_exclude_from` can be defi
|
|||
%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 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.
|
||||
* 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
|
||||
|
|
@ -61,11 +61,11 @@ In addition to preventing rpm from scanning files and directories for automatic
|
|||
%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
|
||||
|
||||
|
|
@ -75,9 +75,9 @@ Perl extension modules can be filtered using this macro:
|
|||
%{?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
|
||||
|
|
@ -92,7 +92,7 @@ If you want to use both custom filters and `%perl_default_filter` then define yo
|
|||
|
||||
=== 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:
|
||||
|
||||
|
|
@ -102,12 +102,12 @@ To filter this out, we could use:
|
|||
|
||||
=== 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`.
|
||||
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:
|
||||
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`:
|
||||
* 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+`:
|
||||
|
||||
....
|
||||
libprivate.so()(64bit)
|
||||
|
|
@ -115,7 +115,7 @@ 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 32 bit, 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 32 bit, 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:
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ e.g. to ensure an arch-specific perl-* package won't provide or require things t
|
|||
|
||||
=== %_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
|
||||
|
|
|
|||
|
|
@ -6,29 +6,29 @@ The C and C++ languages and runtimes are one of the most common development fram
|
|||
|
||||
=== BuildRequires and Requires
|
||||
|
||||
If your application is a C or C++ application you must list a `BuildRequires` against `gcc`, `gcc-c++` or `clang`. Those packages will include everything that is required to build a standards conforming C or C++ application.
|
||||
If your application is a C or C++ application you must list a `+BuildRequires+` against `+gcc+`, `+gcc-c+++` or `+clang+`. Those packages will include everything that is required to build a standards conforming C or C++ application.
|
||||
|
||||
If your library includes standard C or C++ headers, you must list `BuildRequires` against `gcc`, `gcc-c++`, or `clang` to install the needed standards conforming headers.
|
||||
If your library includes standard C or C++ headers, you must list `+BuildRequires+` against `+gcc+`, `+gcc-c+++`, or `+clang+` to install the needed standards conforming headers.
|
||||
|
||||
If at runtime you use `cpp` to process C or C++ language headers then you have no choice but to use `Requires` for `gcc`, `gcc-c++`, or `clang` to install the required headers for a standard conforming C or C++ application. In the future this might change if a set of standard C or C++ language headers are provided by a special-purpose provides e.g. `c-headers` or `c++-headers`.
|
||||
If at runtime you use `+cpp+` to process C or C++ language headers then you have no choice but to use `+Requires+` for `+gcc+`, `+gcc-c+++`, or `+clang+` to install the required headers for a standard conforming C or C++ application. In the future this might change if a set of standard C or C++ language headers are provided by a special-purpose provides e.g. `+c-headers+` or `+c++-headers+`.
|
||||
|
||||
You need not include a `BuildRequires` or `Requires` on `glibc-headers`, or any other core C or C++ 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 C++ application is taken care of by the `gcc`, `gcc-c++`, and `clang` packages.
|
||||
You need not include a `+BuildRequires+` or `+Requires+` on `+glibc-headers+`, or any other core C or C++ 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 C++ application is taken care of by the `+gcc+`, `+gcc-c+++`, and `+clang+` packages.
|
||||
|
||||
Please refer to https://fedoraproject.org/wiki/Packaging:Guidelines#Compiler[Packaging:Guidelines Compiler] for the list of supported compilers for C and C++ compilers.
|
||||
|
||||
=== Packaging Q&A
|
||||
|
||||
Q: Do I need a `Requires: glibc` to ensure I have the C runtime installed for my application?
|
||||
Q: Do I need a `+Requires: glibc+` to ensure I have the C runtime installed for my application?
|
||||
|
||||
A: 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.
|
||||
|
||||
Q: Do I need to include a `Requires: libgcc`?
|
||||
Q: Do I need to include a `+Requires: libgcc+`?
|
||||
|
||||
A: 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.
|
||||
A: 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 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.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ ctest -V %{?_smp_mflags}
|
|||
|
||||
== Notes
|
||||
|
||||
*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.
|
||||
*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.
|
||||
|
||||
Nevertheless, RPATH issues might arise when cmake was used improperly. E.g. 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.
|
||||
Nevertheless, RPATH issues might arise when cmake was used improperly. E.g. 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:
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
|
||||
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.
|
||||
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
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ Keep in mind that implicit conflicts are NEVER acceptable. If your package confl
|
|||
|
||||
=== 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,13 +29,13 @@ Some software can utilize other optional software applications if present, but d
|
|||
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 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:
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ In both of these cases, the new version of the original package should be update
|
|||
|
||||
=== 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)
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ Be aware, adding explicit Conflicts means that if any other packages depend on y
|
|||
|
||||
== 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
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ 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`)
|
||||
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.
|
||||
|
||||
|
|
@ -136,6 +136,6 @@ Renaming packages and replacing them with others can be difficult if it has to o
|
|||
|
||||
== 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 link: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 link: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.
|
||||
|
||||
Category:_Packaging_guidelines[Category: Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Cron job file(s) in packages must be marked as %config(noreplace), and their fil
|
|||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ All D packages depend on ldc to build, so every package must have ldc as BuildRe
|
|||
|
||||
=== Compiler options
|
||||
|
||||
`%{_d_optflags}` must be used with ldc (normal `%{optflags}` do not apply to ldc, only to gcc).
|
||||
`+%{_d_optflags}+` must be used with ldc (normal `+%{optflags}+` do not apply to ldc, only to gcc).
|
||||
|
||||
`%{_d_optflags}` is defined as:
|
||||
`+%{_d_optflags}+` is defined as:
|
||||
|
||||
....
|
||||
-release -w -g -O2
|
||||
|
|
@ -17,13 +17,13 @@ All D packages depend on ldc to build, so every package must have ldc as BuildRe
|
|||
-g _generates debug information_ +
|
||||
-O2 _is the optimisation level_
|
||||
|
||||
Some D packages use Makefiles, which usually use the $DFLAGS variable in the same way that C packages with Makefiles use $CFLAGS. In this case, `export DFLAGS="%{_d_optflags}"` is usually appropriate. In other cases, the build script in the D package has an option to pass in `%{_d_optflags}`. It is the responsibility of the packager to ensure that `%{_d_optflags}` are used with ldc when the package is built.
|
||||
Some D packages use Makefiles, which usually use the $DFLAGS variable in the same way that C packages with Makefiles use $CFLAGS. In this case, `+export DFLAGS="%{_d_optflags}"+` is usually appropriate. In other cases, the build script in the D package has an option to pass in `+%{_d_optflags}+`. It is the responsibility of the packager to ensure that `+%{_d_optflags}+` are used with ldc when the package is built.
|
||||
|
||||
=== Header Files
|
||||
|
||||
D packages contain header files, which end with .d or .di. These header files must be installed into `%{_d_includedir}/%{name}`.
|
||||
D packages contain header files, which end with .d or .di. These header files must be installed into `+%{_d_includedir}/%{name}+`.
|
||||
|
||||
`%{_d_includedir}` is defined as:
|
||||
`+%{_d_includedir}+` is defined as:
|
||||
|
||||
....
|
||||
/usr/include/d/
|
||||
|
|
@ -45,7 +45,7 @@ If your D package contains static libraries, you must disable debuginfo generati
|
|||
Otherwise, it would generate an empty debuginfo package.
|
||||
|
||||
All static libraries must be placed in the *-devel subpackage. When doing this, you must also have
|
||||
`Provides: %{name}-static = %{version}-%{release}` in the devel package definition.
|
||||
`+Provides: %{name}-static = %{version}-%{release}+` in the devel package definition.
|
||||
|
||||
It is possible that this will leave the root package empty, if this is the case, do not list a %files section for the root package, only for the -devel package. This is illustrated in the example template below.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,31 +4,31 @@ This page contains information about debuginfo packages and common pitfalls abou
|
|||
|
||||
== Checking your debuginfo package for usefulness
|
||||
|
||||
A useful debuginfo package contains stripped symbols from ELF binaries (`*.debug` in `/usr/lib/debug`) as well as the source code related to them (in `/usr/src/debug`). The script that generates the packages is `/usr/lib/rpm/find-debuginfo.sh`, read it through to get a basic understanding of how they're generated. If your debuginfo package doesn't contain any files, or is missing the sources or the size of the `*.debug` files in it is unexpectedly small (typically `*.debug` are larger than the corresponding binary it was stripped from), it's likely that there's a flaw in your package. That's not always the case though, read on.
|
||||
A useful debuginfo package contains stripped symbols from ELF binaries (`+*.debug+` in `+/usr/lib/debug+`) as well as the source code related to them (in `+/usr/src/debug+`). The script that generates the packages is `+/usr/lib/rpm/find-debuginfo.sh+`, read it through to get a basic understanding of how they're generated. If your debuginfo package doesn't contain any files, or is missing the sources or the size of the `+*.debug+` files in it is unexpectedly small (typically `+*.debug+` are larger than the corresponding binary it was stripped from), it's likely that there's a flaw in your package. That's not always the case though, read on.
|
||||
|
||||
=== Useless or incomplete debuginfo packages due to packaging issues
|
||||
|
||||
Useless or incomplete debuginfo packages are often a result of packaging flaws. Typical flaws that often manifest themselves as debuginfo packages containing no files:
|
||||
|
||||
* The specfile or the package's build routines explicitly strip symbols out of the binaries. Look for invocations of `strip`, `install -s`, `ld -s`, or `gcc -s` etc and get rid of them (or the `-s` flags). The method how to do that varies, some examples cases include patching, using `%configure` or a `make` target that prevents the strip from happening, and/or overriding a strip command like for example `make install STRIP=/bin/true`
|
||||
* The package is not marked as `noarch`, but does not contain any architecture dependent things (native binaries, architecture dependent paths etc). True `noarch` packages contain nothing rpmbuild could strip from them, so it's expected that they're empty if `BuildArch: noarch` is missing. If that's the case, make the package `noarch`.
|
||||
* `find-debuginfo.sh` processes only files that are executable when it's run; for practical purposes one can assume that happens under the hood after the `%install` section. Make sure that all ELF binaries (executables, shared libraries, DSO's) are executable at end of `%install`.
|
||||
* `find-debuginfo.sh` does not process setuid or setgid binaries. There's a https://bugzilla.redhat.com/117858[bug filed against rpmbuild] about that, but until it is fixed in the distros your package is targeted at, make sure that all your binaries do _not_ have the setuid/setgid bits at end of `%install`, and restore them in the `%files` section using `%attr(...) /path/to/file`
|
||||
* The specfile or the package's build routines explicitly strip symbols out of the binaries. Look for invocations of `+strip+`, `+install -s+`, `+ld -s+`, or `+gcc -s+` etc and get rid of them (or the `+-s+` flags). The method how to do that varies, some examples cases include patching, using `+%configure+` or a `+make+` target that prevents the strip from happening, and/or overriding a strip command like for example `+make install STRIP=/bin/true+`
|
||||
* The package is not marked as `+noarch+`, but does not contain any architecture dependent things (native binaries, architecture dependent paths etc). True `+noarch+` packages contain nothing rpmbuild could strip from them, so it's expected that they're empty if `+BuildArch: noarch+` is missing. If that's the case, make the package `+noarch+`.
|
||||
* `+find-debuginfo.sh+` processes only files that are executable when it's run; for practical purposes one can assume that happens under the hood after the `+%install+` section. Make sure that all ELF binaries (executables, shared libraries, DSO's) are executable at end of `+%install+`.
|
||||
* `+find-debuginfo.sh+` does not process setuid or setgid binaries. There's a https://bugzilla.redhat.com/117858[bug filed against rpmbuild] about that, but until it is fixed in the distros your package is targeted at, make sure that all your binaries do _not_ have the setuid/setgid bits at end of `+%install+`, and restore them in the `+%files+` section using `+%attr(...) /path/to/file+`
|
||||
|
||||
Flaws that manifest themselves as unexpectedly small `*.debug` in the debuginfo package and/or source files missing:
|
||||
Flaws that manifest themselves as unexpectedly small `+*.debug+` in the debuginfo package and/or source files missing:
|
||||
|
||||
* The package was built without passing `-g` to `gcc` or `g++`. Without `-g`, no or insufficient information for debuginfo packages is generated, make sure that it is being used.
|
||||
* Note that the default `CFLAGS` and `CXXFLAGS` of the distro already contain `-g`, so if those flags are being honored, it should be already in use. If not, suboptimal debuginfo packages are not the only problem; the package is probably also compiled without the security enhancing options of recent compiler versions. Make sure that `$RPM_OPT_FLAGS` is being honored and used.
|
||||
* `strip -g` was used on the binaries; see above for possible remedies.
|
||||
* The package was built without passing `+-g+` to `+gcc+` or `+g+++`. Without `+-g+`, no or insufficient information for debuginfo packages is generated, make sure that it is being used.
|
||||
* Note that the default `+CFLAGS+` and `+CXXFLAGS+` of the distro already contain `+-g+`, so if those flags are being honored, it should be already in use. If not, suboptimal debuginfo packages are not the only problem; the package is probably also compiled without the security enhancing options of recent compiler versions. Make sure that `+$RPM_OPT_FLAGS+` is being honored and used.
|
||||
* `+strip -g+` was used on the binaries; see above for possible remedies.
|
||||
|
||||
=== Useless or incomplete debuginfo packages due to other reasons
|
||||
|
||||
Empty debuginfo packages may also be generated in situations where there are no obvious packaging flaws present. Sometimes these are because of limitations of `find-debuginfo.sh`, sometimes not. Some usual cases:
|
||||
Empty debuginfo packages may also be generated in situations where there are no obvious packaging flaws present. Sometimes these are because of limitations of `+find-debuginfo.sh+`, sometimes not. Some usual cases:
|
||||
|
||||
* Packages whose only architecture dependent binary part is a static library or many of them
|
||||
* R and Mono packages *TODO: people knowledgeable of R and/or Mono, verify these*
|
||||
|
||||
If you wish to disable generation of the useless debuginfo package while waiting for improvements to `find-debuginfo.sh` or if it's unlikely that it could be enhanced to produce a good debuginfo for your package (for example no architecture dependent files, but package is not noarch because of the installation paths it uses), use `%global debug_package %{nil}` in the specfile, and be sure to add a comment next to it explaining why it was done.
|
||||
If you wish to disable generation of the useless debuginfo package while waiting for improvements to `+find-debuginfo.sh+` or if it's unlikely that it could be enhanced to produce a good debuginfo for your package (for example no architecture dependent files, but package is not noarch because of the installation paths it uses), use `+%global debug_package %{nil}+` in the specfile, and be sure to add a comment next to it explaining why it was done.
|
||||
|
||||
== Missing debuginfo packages
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ For the purposes of this document, a "service" is defined as one or more of:
|
|||
* A daemon or process that is invoked by hardware activation (i.e. started via a udev rule).
|
||||
* A http://www.freedesktop.org/software/systemd/man/systemd.timer.html[systemd timer unit] that runs periodically.
|
||||
|
||||
Note that this includes processes which are not persistent. If something started by a systemd service unit runs for a short period of time and then exits, it is still a service. An example would be `iptables`.
|
||||
Note that this includes processes which are not persistent. If something started by a systemd service unit runs for a short period of time and then exits, it is still a service. An example would be `+iptables+`.
|
||||
|
||||
== Enabling Services by Default
|
||||
|
||||
|
|
|
|||
|
|
@ -12,35 +12,35 @@ If a package is a dependency of other packages in the distribution (which are no
|
|||
|
||||
In order to mark a package deprecated, a special virtual provides is added:
|
||||
|
||||
` Provides: deprecated()`
|
||||
`+ Provides: deprecated()+`
|
||||
|
||||
If the package has subpackages and the packager intends to deprecate the package as a whole, packager MUST mark all subpackages as being deprecated.
|
||||
|
||||
`Name: mainpackage` +
|
||||
`...` +
|
||||
`Provides: deprecated()` +
|
||||
`+Name: mainpackage+` +
|
||||
`+...+` +
|
||||
`+Provides: deprecated()+` +
|
||||
+
|
||||
`...` +
|
||||
`+...+` +
|
||||
+
|
||||
`%package subpackage` +
|
||||
`...` +
|
||||
`Provides: deprecated()`
|
||||
`+%package subpackage+` +
|
||||
`+...+` +
|
||||
`+Provides: deprecated()+`
|
||||
|
||||
Alternatively, a packager MAY decide to only deprecate some subpackages.
|
||||
|
||||
A packager SHOULD add a comment in the spec explaining why a package is being deprecated. For example:
|
||||
|
||||
`# net-tools (ifconfig etc.) have been obsoleted for ~20 years upstream.` +
|
||||
`# We want to get rid of it from Fedora in favor of the iproute package,` +
|
||||
`# however many sysadmins still expect ifconfig to be there, so we keep it` +
|
||||
`# around as a deprecated package.` +
|
||||
`Provides: deprecated()`
|
||||
`+# net-tools (ifconfig etc.) have been obsoleted for ~20 years upstream.+` +
|
||||
`+# We want to get rid of it from Fedora in favor of the iproute package,+` +
|
||||
`+# however many sysadmins still expect ifconfig to be there, so we keep it+` +
|
||||
`+# around as a deprecated package.+` +
|
||||
`+Provides: deprecated()+`
|
||||
|
||||
If a date for the final removal of the package from the distribution is known, it MAY be included as follows:
|
||||
|
||||
`Provides: deprecated() == YYYYMMDD`
|
||||
`+Provides: deprecated() == YYYYMMDD+`
|
||||
|
||||
The special `deprecated()` provide MUST NOT be added in any released branch of Fedora. It is acceptable to deprecate packages in rawhide (the master branch), the branch for an upcoming Fedora release (if one exists) up until the time of the link:Schedule[Final Freeze], and to EPEL branches (at any time). Also note that because packages may exist in a deprecated state for some time, those packages can eventually enter release branches. The restriction is on the initial addition of the `deprecated()` tag.
|
||||
The special `+deprecated()+` provide MUST NOT be added in any released branch of Fedora. It is acceptable to deprecate packages in rawhide (the master branch), the branch for an upcoming Fedora release (if one exists) up until the time of the link:Schedule[Final Freeze], and to EPEL branches (at any time). Also note that because packages may exist in a deprecated state for some time, those packages can eventually enter release branches. The restriction is on the initial addition of the `+deprecated()+` tag.
|
||||
|
||||
== Consequences of a package being deprecated
|
||||
|
||||
|
|
|
|||
|
|
@ -10,72 +10,72 @@ We recommend you use the tool https://github.com/devassistant/dap2rpm[dap2rpm],
|
|||
|
||||
== Naming guidelines
|
||||
|
||||
* Every (RPM) package name must start with `devassistant-dap-`, which is followed by the name of the Assistant itself, all lowercase. For example, the DAP named `Openscad` will be named `devassistant-dap-openscad` in the SPEC file. In this document, the second part of the name (i. e. the substring `openscad`) will be referenced as `%{shortname}`.
|
||||
* Every (RPM) package name must start with `+devassistant-dap-+`, which is followed by the name of the Assistant itself, all lowercase. For example, the DAP named `+Openscad+` will be named `+devassistant-dap-openscad+` in the SPEC file. In this document, the second part of the name (i. e. the substring `+openscad+`) will be referenced as `+%{shortname}+`.
|
||||
* There is no difference between packages that provide Assistants, and those that provide only auxiliary files, snippets, metapackages etc.
|
||||
|
||||
== Dependencies
|
||||
|
||||
* All packages must Require `devassistant-ui`. This means that the user has at least one user interface for DevAssistant installed, so they can use the DAP without futher installing anything. No version specification is necessary as DevAssistant 0.10.1 is the first version ever to provide `devassistant-ui`.
|
||||
* `Requires: devassistant` is not allowed, as that would install more packages for DA than the user may intend or need.
|
||||
* All packages must have `BuildRequires: devassistant-devel`. (for macros, installation and checking)
|
||||
* Each package must Require packages that are specified in the file `/meta.yaml` in the section `dependencies`. These names, of course, must contain the `devassistant-dap-` prefix. These Requires are generated automatically by dap2rpm.
|
||||
* All packages must Require `+devassistant-ui+`. This means that the user has at least one user interface for DevAssistant installed, so they can use the DAP without futher installing anything. No version specification is necessary as DevAssistant 0.10.1 is the first version ever to provide `+devassistant-ui+`.
|
||||
* `+Requires: devassistant+` is not allowed, as that would install more packages for DA than the user may intend or need.
|
||||
* All packages must have `+BuildRequires: devassistant-devel+`. (for macros, installation and checking)
|
||||
* Each package must Require packages that are specified in the file `+/meta.yaml+` in the section `+dependencies+`. These names, of course, must contain the `+devassistant-dap-+` prefix. These Requires are generated automatically by dap2rpm.
|
||||
|
||||
== Architecture
|
||||
|
||||
* All daps must be architecture independent, i. e. `BuildArch: noarch`.
|
||||
* All daps must be architecture independent, i. e. `+BuildArch: noarch+`.
|
||||
|
||||
== Macros
|
||||
|
||||
* The macro denoting the parent directory where the package files go is `%{assistant_path}`. This currently expands to `/usr/share/devassistant`.
|
||||
* The macro definitions of `%install_assistant`, `%repack_assistant`, and `%check_assistant` are provided by the package `devassistant-devel`.
|
||||
* The macro denoting the parent directory where the package files go is `+%{assistant_path}+`. This currently expands to `+/usr/share/devassistant+`.
|
||||
* The macro definitions of `+%install_assistant+`, `+%repack_assistant+`, and `+%check_assistant+` are provided by the package `+devassistant-devel+`.
|
||||
|
||||
== Prep section
|
||||
|
||||
* DAP must be unpacked with `setup` like other packages, it is not permissible to install the source DAP directly.
|
||||
* DAP must be unpacked with `+setup+` like other packages, it is not permissible to install the source DAP directly.
|
||||
* If needed, you may patch the source files in this section.
|
||||
|
||||
== Build section
|
||||
|
||||
* You must re-pack the (optionally patched) DAP in the `%build` section using the macro `%repack_assistant`. This is needed for installing and checking.
|
||||
* You must re-pack the (optionally patched) DAP in the `+%build+` section using the macro `+%repack_assistant+`. This is needed for installing and checking.
|
||||
|
||||
== Install section
|
||||
|
||||
* Files are installed via the `%install_assistant` macro
|
||||
* Using the above macro automatically creates a list of files stored in the file `dap-list`, which can then be used in the `%files` section.
|
||||
* If the package contains licensing files, they should be marked as such by running the `%install_assistant` macro with argument(s) `-L LICENSE_FILE1 LICENSE_FILE2...`. The licensing files must be stored only in the `doc` directory of the DAP.
|
||||
* If installed manually, the package files are installed into `%{buildroot}%{assistant_path}` in subdirectories conforming to the DAP layout, i. e. the `assistants/crt/foo` directory is installed into `%{buildroot}%{assistant_path}/assistants/crt/foo`.
|
||||
* Files are installed via the `+%install_assistant+` macro
|
||||
* Using the above macro automatically creates a list of files stored in the file `+dap-list+`, which can then be used in the `+%files+` section.
|
||||
* If the package contains licensing files, they should be marked as such by running the `+%install_assistant+` macro with argument(s) `+-L LICENSE_FILE1 LICENSE_FILE2...+`. The licensing files must be stored only in the `+doc+` directory of the DAP.
|
||||
* If installed manually, the package files are installed into `+%{buildroot}%{assistant_path}+` in subdirectories conforming to the DAP layout, i. e. the `+assistants/crt/foo+` directory is installed into `+%{buildroot}%{assistant_path}/assistants/crt/foo+`.
|
||||
|
||||
== Check section
|
||||
|
||||
* You must run the `%check_assistant` macro in the `%check` section, and it must pass.
|
||||
* If run manually, you must run the command `da pkg lint -w %{shortname}-%{version}.dap` (or similar, if your package's name differs). The run must produce no errors. Warnings are permissible.
|
||||
* You must run the `+%check_assistant+` macro in the `+%check+` section, and it must pass.
|
||||
* If run manually, you must run the command `+da pkg lint -w %{shortname}-%{version}.dap+` (or similar, if your package's name differs). The run must produce no errors. Warnings are permissible.
|
||||
|
||||
== Files section
|
||||
|
||||
* If the macro `%install_assistant` was used in the `%install` section, it is sufficient to provide the list of files to the `%files` section like this: `%files -f dap-files`. This is the default situation when using dap2rpm.
|
||||
* If the macro `+%install_assistant+` was used in the `+%install+` section, it is sufficient to provide the list of files to the `+%files+` section like this: `+%files -f dap-files+`. This is the default situation when using dap2rpm.
|
||||
* If done manually:
|
||||
** Package's files and directories are installed into `%{assistant_path}`.
|
||||
** Do not install everything like `%{assistant_path}/*`, list each folder separately. That includes subdirectories in `%{assistant_path}/assistants`, as shown in these examples:
|
||||
*** Bad: `%{assistant_path}/assistants/*`
|
||||
*** Good: `%{assistant_path}/assistants/crt/%{shortname}`
|
||||
** The `doc` directory in the DAP should be installed via the `%doc` macro, in the same `%{assistant_path}` directory.
|
||||
** The `meta.yaml` file must be installed as `%{assistant_path}/meta/%{shortname}.yaml`.
|
||||
** Package's files and directories are installed into `+%{assistant_path}+`.
|
||||
** Do not install everything like `+%{assistant_path}/*+`, list each folder separately. That includes subdirectories in `+%{assistant_path}/assistants+`, as shown in these examples:
|
||||
*** Bad: `+%{assistant_path}/assistants/*+`
|
||||
*** Good: `+%{assistant_path}/assistants/crt/%{shortname}+`
|
||||
** The `+doc+` directory in the DAP should be installed via the `+%doc+` macro, in the same `+%{assistant_path}+` directory.
|
||||
** The `+meta.yaml+` file must be installed as `+%{assistant_path}/meta/%{shortname}.yaml+`.
|
||||
|
||||
== Directory ownership
|
||||
|
||||
* The package `devassistant-core` owns the directory `%{assistant_path}` itself and the following subdirectories:
|
||||
1. `%{assistant_path}/{assistants,doc,files,icons,meta,snippets}`
|
||||
2. `%{assistant_path}/{assistants}/{crt,twk,prep,extra}`
|
||||
3. `%{assistant_path}/files/{crt,twk,prep,extra,snippets}`
|
||||
4. `%{assistant_path}/icons/{crt,twk,prep,extra}`
|
||||
* The package `+devassistant-core+` owns the directory `+%{assistant_path}+` itself and the following subdirectories:
|
||||
1. `+%{assistant_path}/{assistants,doc,files,icons,meta,snippets}+`
|
||||
2. `+%{assistant_path}/{assistants}/{crt,twk,prep,extra}+`
|
||||
3. `+%{assistant_path}/files/{crt,twk,prep,extra,snippets}+`
|
||||
4. `+%{assistant_path}/icons/{crt,twk,prep,extra}+`
|
||||
* The RPM-packaged DAP must own the following files/directories if and only if they are present in the upstream DAP:
|
||||
** directories named `%{shortname}` in directories listed in point 2 and 3 of the previous bullet.
|
||||
*** Example 1: `%{assistant_path}/assistant/crt/%{shortname}`
|
||||
*** Example 2: `%{assistant_path}/files/snippets/%{shortname}`
|
||||
** files named `%{shortname}.yaml` in the directories listed in point 2.
|
||||
** a directory named `%{shortname}` in the directory `%{assistant_path}/doc/`
|
||||
** a file named `%{shortname}.yaml` in the directory `%{assistant_path}/meta/`
|
||||
** a file named `%{shortname}.$SUFFIX`, where `$SUFFIX` is an image file suffix (preferably PNG or SVG), in the directories listed in point 4.
|
||||
** directories named `+%{shortname}+` in directories listed in point 2 and 3 of the previous bullet.
|
||||
*** Example 1: `+%{assistant_path}/assistant/crt/%{shortname}+`
|
||||
*** Example 2: `+%{assistant_path}/files/snippets/%{shortname}+`
|
||||
** files named `+%{shortname}.yaml+` in the directories listed in point 2.
|
||||
** a directory named `+%{shortname}+` in the directory `+%{assistant_path}/doc/+`
|
||||
** a file named `+%{shortname}.yaml+` in the directory `+%{assistant_path}/meta/+`
|
||||
** a file named `+%{shortname}.$SUFFIX+`, where `+$SUFFIX+` is an image file suffix (preferably PNG or SVG), in the directories listed in point 4.
|
||||
|
||||
== Sample SPEC
|
||||
|
||||
|
|
@ -103,9 +103,9 @@ Requires: devassistant-dap-github
|
|||
This assistants helps you to create new OpenSCAD project for 3D printing.
|
||||
We use it in our 3D printing lab to store our 3D printers on Github.
|
||||
|
||||
Projects created with this assistant have a `Makefile` to build the 3D models form OpenSCAD sources.
|
||||
To do so, run `make`. You can also generate the images by `make images` or print plates with `make arrange`.
|
||||
Observe the generated `Makefile` to see all available options.
|
||||
Projects created with this assistant have a `+Makefile+` to build the 3D models form OpenSCAD sources.
|
||||
To do so, run `+make+`. You can also generate the images by `+make images+` or print plates with `+make arrange+`.
|
||||
Observe the generated `+Makefile+` to see all available options.
|
||||
|
||||
|
||||
%prep
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ While its obviously not possible to foresee all the cases where the need might a
|
|||
|
||||
To work around this problem, you must include a Packaging:Guidelines#The_.25pretrans_scriptlet[%pretrans scriptlet] that manually performs the conversion prior to RPM attempting to install the package.
|
||||
|
||||
%pretrans scriptlets must use `-p ` to survive initial system installation, but since there will never be transitions like these to perform on initial system installation, you can count on a shell being present when it actually performs the conversion. This means that you need to use `-p ` in order to test if the replacement needs to be made (by examining whether the path is a directory or symlink), but you can safely shell out using `os.execute()` to actually perform the replacement.
|
||||
%pretrans scriptlets must use `+-p +` to survive initial system installation, but since there will never be transitions like these to perform on initial system installation, you can count on a shell being present when it actually performs the conversion. This means that you need to use `+-p +` in order to test if the replacement needs to be made (by examining whether the path is a directory or symlink), but you can safely shell out using `+os.execute()+` to actually perform the replacement.
|
||||
|
||||
Please use whichever of the two following snippets is necessary in packages that need this transition, replacing `/path/to/dir` with the path to the directory that is being converted.
|
||||
Please use whichever of the two following snippets is necessary in packages that need this transition, replacing `+/path/to/dir+` with the path to the directory that is being converted.
|
||||
|
||||
==== Scriptlet to replace a directory
|
||||
|
||||
RPM cannot simply remove a directory when it is replaced by a file or symlink, since users may have added or modified files to the directory. To protect against accidental data loss, you must use the following scriptlet which renames the directory with a `.rpmmoved` suffix so that users can find the backed up directory if they need to after the package is upgraded. (It also will append an integer to the suffix in the rare event that directory also exists.)
|
||||
RPM cannot simply remove a directory when it is replaced by a file or symlink, since users may have added or modified files to the directory. To protect against accidental data loss, you must use the following scriptlet which renames the directory with a `+.rpmmoved+` suffix so that users can find the backed up directory if they need to after the package is upgraded. (It also will append an integer to the suffix in the rare event that directory also exists.)
|
||||
|
||||
....
|
||||
%pretrans -p <lua>
|
||||
|
|
@ -37,7 +37,7 @@ if st and st.type == "directory" then
|
|||
end
|
||||
....
|
||||
|
||||
Additionally, you should define the `/path/to/dir.rpmmoved` directory as a `%ghost` entry in the `%files` list in the package's spec file, so that the directory is not entirely orphaned and can be deleted if the package is ever uninstalled and the directory is empty.
|
||||
Additionally, you should define the `+/path/to/dir.rpmmoved+` directory as a `+%ghost+` entry in the `+%files+` list in the package's spec file, so that the directory is not entirely orphaned and can be deleted if the package is ever uninstalled and the directory is empty.
|
||||
|
||||
==== Scriptlet to replace a symlink to a directory with a directory
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
= Dist Tag Guidelines
|
||||
|
||||
Use of the `%{?dist}` tag is mandatory in Fedora.
|
||||
Use of the `+%{?dist}+` tag is mandatory in Fedora.
|
||||
|
||||
You should consider this document as an addendum to the Packaging/NamingGuidelines .
|
||||
|
||||
== Purpose of the Dist Tag
|
||||
|
||||
There are several uses for a `%{?dist}` tag. The original purpose was so that a single spec file could be used for multiple distribution releases. In doing this, there are cases in which BuildRequires: and Requires: will need to be different for different distribution releases. Hence, `%{?dist}` does double duty:
|
||||
There are several uses for a `+%{?dist}+` tag. The original purpose was so that a single spec file could be used for multiple distribution releases. In doing this, there are cases in which BuildRequires: and Requires: will need to be different for different distribution releases. Hence, `+%{?dist}+` does double duty:
|
||||
|
||||
* it differentiates multiple packages which would otherwise have the same `%{name}-%{version}-%{release}`, but very different dependencies.
|
||||
* it differentiates multiple packages which would otherwise have the same `+%{name}-%{version}-%{release}+`, but very different dependencies.
|
||||
|
||||
* it allows for a conditional check in the spec to deal with the differing dependencies.
|
||||
|
||||
|
|
@ -22,9 +22,9 @@ Here is the important information to know:
|
|||
|
||||
=== Possible values for %\{dist}
|
||||
|
||||
When you run fedpkg commands like `fedpkg build`, the values for `%{dist}` and its helper variables are assigned according to the git branch that you are working in. You do NOT need to define these variables in your spec file. fedpkg will magically set `%{?dist}` for you.
|
||||
When you run fedpkg commands like `+fedpkg build+`, the values for `+%{dist}+` and its helper variables are assigned according to the git branch that you are working in. You do NOT need to define these variables in your spec file. fedpkg will magically set `+%{?dist}+` for you.
|
||||
|
||||
For reference purposes only, these are some possible values for `%dist`. Note that if `%{dist}` is undefined, `%{?dist}` simply becomes empty. Also note that Fedora releases use "fc" and not "f" in the tag for historical reasons.
|
||||
For reference purposes only, these are some possible values for `+%dist+`. Note that if `+%{dist}+` is undefined, `+%{?dist}+` simply becomes empty. Also note that Fedora releases use "fc" and not "f" in the tag for historical reasons.
|
||||
|
||||
[cols=",",options="header",]
|
||||
|==================================================================================
|
||||
|
|
@ -41,14 +41,14 @@ Development:
|
|||
|
||||
The development branch takes the disttag of the next major unreleased version of Fedora.
|
||||
|
||||
Note the leading period in the definition of `%{?dist}`. This is present so that it can easily be used in the release field.
|
||||
Note the leading period in the definition of `+%{?dist}+`. This is present so that it can easily be used in the release field.
|
||||
These definitions can be found in common/branches.
|
||||
|
||||
Note that RHEL dist tags are only defined for EPEL packages.
|
||||
|
||||
=== %\{?dist} in the Release: field
|
||||
|
||||
The `%{?dist}` tag is included in the Release field as follows:
|
||||
The `+%{?dist}+` tag is included in the Release field as follows:
|
||||
|
||||
....
|
||||
Release: 1%{?dist}
|
||||
|
|
@ -68,26 +68,26 @@ Version: 1.4
|
|||
Release: 2%{?dist}
|
||||
....
|
||||
|
||||
When this package is built in an i386 FC20 buildroot, it generates an rpm named: `logjam-1.4-2.fc20.i386.rpm`.
|
||||
When this package is built in an i386 FC20 buildroot, it generates an rpm named: `+logjam-1.4-2.fc20.i386.rpm+`.
|
||||
|
||||
Keep in mind that `%{?dist}` should *never* be used in the Name or Version fields, nor in %changelog entries.
|
||||
Keep in mind that `+%{?dist}+` should *never* be used in the Name or Version fields, nor in %changelog entries.
|
||||
|
||||
=== Conditionals
|
||||
|
||||
Along with `%{?dist}`, there are several "helper" variables defined by the buildsystem. These variables are:
|
||||
Along with `+%{?dist}+`, there are several "helper" variables defined by the buildsystem. These variables are:
|
||||
|
||||
`%{rhel}`: This variable is only defined on Red Hat Enterprise Linux builds. If defined, it is set to the release number of Red Hat Enterprise Linux present at build time.
|
||||
`+%{rhel}+`: This variable is only defined on Red Hat Enterprise Linux builds. If defined, it is set to the release number of Red Hat Enterprise Linux present at build time.
|
||||
|
||||
`%{fedora}`: This variable is only defined on Fedora builds. If defined, it is set to the release number of Fedora present at build time.
|
||||
`+%{fedora}+`: This variable is only defined on Fedora builds. If defined, it is set to the release number of Fedora present at build time.
|
||||
|
||||
`%{rhl}`: This variable is only defined on Red Hat Linux builds. If defined, it is set to the release number of Red Hat Linux present at build time.
|
||||
`+%{rhl}+`: This variable is only defined on Red Hat Linux builds. If defined, it is set to the release number of Red Hat Linux present at build time.
|
||||
|
||||
`%{fc#}`: This variable is only defined on Fedora builds. For example, on Fedora 20 builds, `%{fc20}` is defined to 1.
|
||||
`+%{fc#}+`: This variable is only defined on Fedora builds. For example, on Fedora 20 builds, `+%{fc20}+` is defined to 1.
|
||||
|
||||
`%{el#}`: This variable is only defined on Red Hat Enterprise Linux builds. For example, on RHEL 7 builds, `%{el7}` is defined to 1.
|
||||
`+%{el#}+`: This variable is only defined on Red Hat Enterprise Linux builds. For example, on RHEL 7 builds, `+%{el7}+` is defined to 1.
|
||||
|
||||
All of these variables, if defined, will have a purely numeric value.
|
||||
With `%{dist}` and these additional variables, you can create conditionals in a spec file to handle the differences between distributions.
|
||||
With `+%{dist}+` and these additional variables, you can create conditionals in a spec file to handle the differences between distributions.
|
||||
|
||||
Here are some examples of how to use these variables in conditionals:
|
||||
|
||||
|
|
@ -125,21 +125,21 @@ and *NOT*
|
|||
%if %{?rhel}
|
||||
....
|
||||
|
||||
Without the extra 0, if `%{rhel}` is undefined, the `%if` conditional will cease to exist, and the rpm will fail to build.
|
||||
Without the extra 0, if `+%{rhel}+` is undefined, the `+%if+` conditional will cease to exist, and the rpm will fail to build.
|
||||
|
||||
=== Things that you cannot use %\{?dist} for
|
||||
|
||||
* You must not override the variables for `%{dist}` (or any of the related variables).
|
||||
* You must not hardcode a value for `%{dist}` (or any of the related variables) in your spec.
|
||||
* You must not override the variables for `+%{dist}+` (or any of the related variables).
|
||||
* You must not hardcode a value for `+%{dist}+` (or any of the related variables) in your spec.
|
||||
* You must not hardcode a dist tag in the spec: *BAD:* Release: 1.fc20 *GOOD:* Release: 1%\{?dist}
|
||||
* You cannot put any sort of "tagging" in `%{dist}` (or any of the related variables). `%{dist}` (and its related variables) exist ONLY to define the distribution that a package was built against.
|
||||
* `%{?dist}` must never be used in the Name or Version fields, only Release, and only as documented above.
|
||||
* `%{fedora}`, `%{rhel}`, `%{rhl}`, `%{fc#}`, `%{el#}` must never be used in the Name, Version, or Release fields.
|
||||
* You cannot put any sort of "tagging" in `+%{dist}+` (or any of the related variables). `+%{dist}+` (and its related variables) exist ONLY to define the distribution that a package was built against.
|
||||
* `+%{?dist}+` must never be used in the Name or Version fields, only Release, and only as documented above.
|
||||
* `+%{fedora}+`, `+%{rhel}+`, `+%{rhl}+`, `+%{fc#}+`, `+%{el#}+` must never be used in the Name, Version, or Release fields.
|
||||
|
||||
== Common questions
|
||||
|
||||
Q: Why don't you just let the buildsystem (or packager) pass the value for dist to rpm, e.g. `rpm --with dist el7`?
|
||||
A: Actually, we do. The Fedora buildsystem defines the values for dist when you run `fedpkg`.
|
||||
Q: Why don't you just let the buildsystem (or packager) pass the value for dist to rpm, e.g. `+rpm --with dist el7+`?
|
||||
A: Actually, we do. The Fedora buildsystem defines the values for dist when you run `+fedpkg+`.
|
||||
|
||||
Q: Why is use of %\{?dist} mandatory?
|
||||
A: There are very few packages which didn't use it, the primary very old reason for not using it (sharing large data packages across Fedora releases) is no longer relevant because all Fedora releases are signed with a different key, and having consistent Release: tags simplifies the automated tools which may need to increment them.
|
||||
|
|
|
|||
|
|
@ -5,28 +5,28 @@
|
|||
|
||||
== Naming Scheme
|
||||
|
||||
Every package *MUST* be named `drupal7-`__`<drupal_machine_name`__`>`. Drupal itself enforces unique machine names for each of its' projects and there is a single namespace for all modules, themes, and distributions/profiles. The __`<drupal_machine_name`__`>` *MUST* match the drupal.org project name (i.e. drupal.org/project/__`<drupal_machine_name`__`>`).
|
||||
Every package *MUST* be named `+drupal7-+`__`+<drupal_machine_name+`__`+>+`. Drupal itself enforces unique machine names for each of its' projects and there is a single namespace for all modules, themes, and distributions/profiles. The __`+<drupal_machine_name+`__`+>+` *MUST* match the drupal.org project name (i.e. drupal.org/project/__`+<drupal_machine_name+`__`+>+`).
|
||||
|
||||
== Macros and Scriptlets
|
||||
|
||||
Macros provided by the `drupal7-rpmbuild` package:
|
||||
Macros provided by the `+drupal7-rpmbuild+` package:
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|==========================================================================================
|
||||
|Macro |Value |Description
|
||||
|`%drupal7` |`%{_datadir}/drupal7` |Drupal 7 base directory
|
||||
|`%drupal7_modules` |`%{drupal7}/modules` |Drupal 7 modules directory
|
||||
|`%drupal7_themes` |`%{drupal7}/themes` |Drupal 7 themes directory
|
||||
|`%drupal7_libraries` |`%{_sysconfdir}/drupal7/all/libraries` |Drupal 7 libraries directory
|
||||
|`%drupal7_find_provides_and_requires` |_Fedora:_
|
||||
`%{nil}` +
|
||||
|`+%drupal7+` |`+%{_datadir}/drupal7+` |Drupal 7 base directory
|
||||
|`+%drupal7_modules+` |`+%{drupal7}/modules+` |Drupal 7 modules directory
|
||||
|`+%drupal7_themes+` |`+%{drupal7}/themes+` |Drupal 7 themes directory
|
||||
|`+%drupal7_libraries+` |`+%{_sysconfdir}/drupal7/all/libraries+` |Drupal 7 libraries directory
|
||||
|`+%drupal7_find_provides_and_requires+` |_Fedora:_
|
||||
`+%{nil}+` +
|
||||
+
|
||||
_EPEL 5/6:_ +
|
||||
`%{expand: \` +
|
||||
`%global _use_internal_dependency_generator 0` +
|
||||
`%global __find_provides %{_rpmconfigdir}/drupal7.prov %{version}` +
|
||||
`%global __find_requires %{_rpmconfigdir}/drupal7.req` +
|
||||
`}` |_Fedora_:
|
||||
`+%{expand: \+` +
|
||||
`+%global _use_internal_dependency_generator 0+` +
|
||||
`+%global __find_provides %{_rpmconfigdir}/drupal7.prov %{version}+` +
|
||||
`+%global __find_requires %{_rpmconfigdir}/drupal7.req+` +
|
||||
`+}+` |_Fedora_:
|
||||
No-op macro to allow spec compatibility with RPM < 4.9 (no fileattrs) +
|
||||
+
|
||||
_EPEL 5/6_: +
|
||||
|
|
@ -35,15 +35,15 @@ Macro to allow spec compatibility with RPM < 4.9 (no fileattrs)
|
|||
|
||||
== File Placement
|
||||
|
||||
* *Modules*: A module package *MUST* be placed in the `%drupal7_modules` directory
|
||||
* *Themes*: A theme package *MUST* be placed in the `%drupal7_themes` directory
|
||||
* *Libraries*: A library package *MUST* be placed in the `%drupal7_libraries` directory
|
||||
* *Modules*: A module package *MUST* be placed in the `+%drupal7_modules+` directory
|
||||
* *Themes*: A theme package *MUST* be placed in the `+%drupal7_themes+` directory
|
||||
* *Libraries*: A library package *MUST* be placed in the `+%drupal7_libraries+` directory
|
||||
|
||||
== Requires and Provides
|
||||
|
||||
* Every package *MUST* require "`drupal7(``)`" virtual resources instead of "`drupal7-`" packages.
|
||||
* Every package *MUST* require "`+drupal7(+``+)+`" virtual resources instead of "`+drupal7-+`" packages.
|
||||
* Every package *MUST* include the following in its' spec:
|
||||
** The `drupal7-rpmbuild` package automatically requires `drupal7(core)` and scans files for provides (from *.info files) and automatically adds them to the package during build time as "`drupal7(``)`" virtual resources. https://drupal.org/node/542202#hidden[Hidden projects] are ignored. The use of virtual provides and requires helps alleviate the confusion of sub-modules and which modules actually provide those sub-modules.
|
||||
** The `+drupal7-rpmbuild+` package automatically requires `+drupal7(core)+` and scans files for provides (from *.info files) and automatically adds them to the package during build time as "`+drupal7(+``+)+`" virtual resources. https://drupal.org/node/542202#hidden[Hidden projects] are ignored. The use of virtual provides and requires helps alleviate the confusion of sub-modules and which modules actually provide those sub-modules.
|
||||
+
|
||||
....
|
||||
BuildRequires: drupal7-rpmbuild >= 7.23-3
|
||||
|
|
@ -54,8 +54,8 @@ BuildRequires: drupal7-rpmbuild >= 7.23-3
|
|||
%{?drupal7_find_provides_and_requires}
|
||||
....
|
||||
* Every package *MUST NOT*:
|
||||
** explicitly require "`drupal7`" or "`drupal7(core)`" (*unless* a specific core version is required) because `drupal7-rpmbuild` auro-requires "`drupal7(core)`"
|
||||
** explicitly provide "`drupal7(``)`" virtual resources because `drupal7-rpmbuild` auto-provides these
|
||||
** explicitly require "`+drupal7+`" or "`+drupal7(core)+`" (*unless* a specific core version is required) because `+drupal7-rpmbuild+` auro-requires "`+drupal7(core)+`"
|
||||
** explicitly provide "`+drupal7(+``+)+`" virtual resources because `+drupal7-rpmbuild+` auto-provides these
|
||||
|
||||
=== Other Packages
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ To get a list of required PHP extensions, use http://php5.laurent-laville.org/co
|
|||
phpcompatinfo print --recursive --report=extension unpacked_package_source_directory
|
||||
....
|
||||
|
||||
To install http://php5.laurent-laville.org/compatinfo/[PHP_CompatInfo (phpcompatinfo)], run "`yum install php-bartlett-PHP-CompatInfo`".
|
||||
To install http://php5.laurent-laville.org/compatinfo/[PHP_CompatInfo (phpcompatinfo)], run "`+yum install php-bartlett-PHP-CompatInfo+`".
|
||||
|
||||
=== Requiring a Minimum PHP Version
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ See Packaging:PHP#Requiring_a_Minimum_PHP_version[PHP packaging guidelines] but
|
|||
|
||||
=== Common Issues
|
||||
|
||||
* On RHEL 5/6 there is an issue with the standard auto-requires script (`/usr/lib/rpm/find-requires`). When there is no "`#!`" (she-bang) line at the beginning of an executable PHP file, the script tries to add an invalid "
|
||||
* On RHEL 5/6 there is an issue with the standard auto-requires script (`+/usr/lib/rpm/find-requires+`). When there is no "`+#!+`" (she-bang) line at the beginning of an executable PHP file, the script tries to add an invalid "
|
||||
+
|
||||
+
|
||||
" as a dependency. Rpmbuild then errors out with something similar to the following:
|
||||
|
|
@ -89,7 +89,7 @@ RPM build errors:
|
|||
line 53: Dependency tokens must begin with alpha-numeric, '_' or '/': -
|
||||
....
|
||||
+
|
||||
To fix this issue, find the files that incorrectly have their executable bit set and remove the executable bit in the spec's `%prep` section. If there should be no executable files in the package then the following could be added to the spec's `%prep` section:
|
||||
To fix this issue, find the files that incorrectly have their executable bit set and remove the executable bit in the spec's `+%prep+` section. If there should be no executable files in the package then the following could be added to the spec's `+%prep+` section:
|
||||
+
|
||||
....
|
||||
find . -type f -executable -print0 | xargs -0 chmod -x
|
||||
|
|
@ -105,7 +105,7 @@ find . -type f -executable -print0 | xargs -0 chmod -x
|
|||
* %{module}
|
||||
....
|
||||
+
|
||||
For example, the `drupal7-domain` package contains the following in its' description:
|
||||
For example, the `+drupal7-domain+` package contains the following in its' description:
|
||||
+
|
||||
....
|
||||
This package provides the following Drupal modules:
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@
|
|||
* *Bundle*: An http://en.wikipedia.org/wiki/OSGi#Bundles["OSGi bundle"].
|
||||
* *Plugin*: A functional unit of Eclipse functionality. Post-Eclipse 3.0, the term "plugin" can almost always be interchanged with the term "bundle". Colloquially, among non-Eclipse developers, the term is used to refer to a set of functional Eclipse plugins ex. "CDT".
|
||||
* *Feature*: A collection of plugins.
|
||||
* *Fragment*: A bundle with native elements ex. `org.eclipse.core.filesystem.linux.${arch}`
|
||||
* *Fragment*: A bundle with native elements ex. `+org.eclipse.core.filesystem.linux.${arch}+`
|
||||
|
||||
== Introduction
|
||||
|
||||
Eclipse is a modular platform that can be used for building everything from server-side applications to full-blown graphical applications like the Eclipse IDE and Lotus Notes. Each of the modular blobs is referred to as a plugin or a bundle. In a nutshell, the system itself is a small runtime (Equinox) based on the OSGi specifications [see http://www.eclipse.org/equinox/ for more information] which loads and runs a given list of bundles. Most people think of Eclipse as a programming integrated development environment (IDE). This document details best practices for packaging Eclipse IDE plugins. Examples include adding Subversion functionality (`eclipse-subclipse`) and tools for tracking your tasks (`eclipse-mylyn`).
|
||||
Eclipse is a modular platform that can be used for building everything from server-side applications to full-blown graphical applications like the Eclipse IDE and Lotus Notes. Each of the modular blobs is referred to as a plugin or a bundle. In a nutshell, the system itself is a small runtime (Equinox) based on the OSGi specifications [see http://www.eclipse.org/equinox/ for more information] which loads and runs a given list of bundles. Most people think of Eclipse as a programming integrated development environment (IDE). This document details best practices for packaging Eclipse IDE plugins. Examples include adding Subversion functionality (`+eclipse-subclipse+`) and tools for tracking your tasks (`+eclipse-mylyn+`).
|
||||
|
||||
== Naming
|
||||
|
||||
Eclipse plugin packages *MUST* be named `eclipse-`. For example, a package of the anyedit plugin for Eclipse would by named `eclipse-anyedit`.
|
||||
Eclipse plugin packages *MUST* be named `+eclipse-+`. For example, a package of the anyedit plugin for Eclipse would by named `+eclipse-anyedit+`.
|
||||
|
||||
=== Binary RPM naming
|
||||
|
||||
|
|
@ -27,11 +27,11 @@ Remember that Eclipse plugin packages, like all Fedora software packages, must b
|
|||
|
||||
== Building
|
||||
|
||||
Eclipse plugins *SHOULD* be built with the Eclipse Plugin Development Environment (PDE; PDE Build specifically) because these builds are generally easier to maintain. `ant` builds are acceptable, but are generally more difficult to maintain. Following what upstream does is the best practice.
|
||||
Eclipse plugins *SHOULD* be built with the Eclipse Plugin Development Environment (PDE; PDE Build specifically) because these builds are generally easier to maintain. `+ant+` builds are acceptable, but are generally more difficult to maintain. Following what upstream does is the best practice.
|
||||
|
||||
=== pdebuild
|
||||
|
||||
There is a script that makes invoking PDE Build easy: `/usr/lib{,64}/eclipse/buildscripts/pdebuild`:
|
||||
There is a script that makes invoking PDE Build easy: `+/usr/lib{,64}/eclipse/buildscripts/pdebuild+`:
|
||||
|
||||
....
|
||||
usage: /usr/lib{,64}/eclipse/buildscripts/pdebuild [<options>]
|
||||
|
|
@ -52,7 +52,7 @@ Optional arguments:
|
|||
|
||||
== File Locations
|
||||
|
||||
All platform-independent plugins/features should go into `%{_datadir}/eclipse/dropins/`. JARs should therefore go into `%{_datadir}/eclipse/dropins/``/plugins` and features should go into `%{_datadir}/eclipse/dropins/``/features`. Architecture-specific plugins/features should go into `%{_libdir}/eclipse/dropins/`. JARs should therefore go into `%{_libdir}/eclipse/dropins/``/plugins` and features should go into `%{_datadir}/eclipse/dropins/``/features`. Example:
|
||||
All platform-independent plugins/features should go into `+%{_datadir}/eclipse/dropins/+`. JARs should therefore go into `+%{_datadir}/eclipse/dropins/+``+/plugins+` and features should go into `+%{_datadir}/eclipse/dropins/+``+/features+`. Architecture-specific plugins/features should go into `+%{_libdir}/eclipse/dropins/+`. JARs should therefore go into `+%{_libdir}/eclipse/dropins/+``+/plugins+` and features should go into `+%{_datadir}/eclipse/dropins/+``+/features+`. Example:
|
||||
|
||||
....
|
||||
%install
|
||||
|
|
@ -72,7 +72,7 @@ While many Eclipse plugins will be architecture-independent, there will be some
|
|||
|
||||
If Eclipse plugins depend upon third party libraries (and licensing permits it), developers often include these libraries directly in their source control system. In this case, the libraries must exist as other packages in Fedora and their contents (such as their JARs) be symlinked from within the source and build trees of the Eclipse plugin being packaged. While it may make source archives smaller in size if they are cleansed of these pre-built files, it is not necessary to do so unless the libraries themselves are not redistributable. Binary RPMs *MUST NOT* include pre-built files.
|
||||
|
||||
A simple check which may be run at the end of `%prep` (courtesy David Walluck (I think that's who gave it to Ben Konrath)):
|
||||
A simple check which may be run at the end of `+%prep+` (courtesy David Walluck (I think that's who gave it to Ben Konrath)):
|
||||
|
||||
....
|
||||
JARS=""
|
||||
|
|
@ -163,11 +163,11 @@ build/rpmBuild/org.eclipse.plugin.b_feature.zip
|
|||
|
||||
=== Requires
|
||||
|
||||
Until `rpmstubby` (see below) is released and/or more widespread, `Requires` on bits provided by the Eclipse SDK (RCP, SWT, Platform, JDT, PDE, CVS, etc.) should only be on the binary package providing the required functionality (ex. `eclipse-cvs-client` or `eclipse-rcp`). For IDE features, the most common requirement will be `eclipse-platform`.
|
||||
Until `+rpmstubby+` (see below) is released and/or more widespread, `+Requires+` on bits provided by the Eclipse SDK (RCP, SWT, Platform, JDT, PDE, CVS, etc.) should only be on the binary package providing the required functionality (ex. `+eclipse-cvs-client+` or `+eclipse-rcp+`). For IDE features, the most common requirement will be `+eclipse-platform+`.
|
||||
|
||||
=== Features vs. Plugins
|
||||
|
||||
Eclipse features are groups of plugins. They are preferred, but not required since they provide nice demarcation lines for binary RPMs. We generally try to make binary RPMs mirror upstream features. Eclipse features also work nicely with `rpmstubby` (see below), but not all plugins have features.
|
||||
Eclipse features are groups of plugins. They are preferred, but not required since they provide nice demarcation lines for binary RPMs. We generally try to make binary RPMs mirror upstream features. Eclipse features also work nicely with `+rpmstubby+` (see below), but not all plugins have features.
|
||||
|
||||
=== JAR Expansion
|
||||
|
||||
|
|
@ -199,10 +199,10 @@ about.html lib-httpclient lib-rome lib-xmlrpc META-INF org
|
|||
$ <do symlinking here>
|
||||
....
|
||||
|
||||
However, we end up with the plugin classes themselves being expanded in the `org` directory. https://bugzilla.redhat.com/273881[Bug #273881] causes build failures when building debuginfo packages in this case. The acceptable workaround is to modify the build.properties file in the plugin to JAR the plugin code separately (ex. `mylyn-webcore.jar`) and include it within this expanded plugin directory. An example of this work-around can be seen in http://cvs.fedoraproject.org/viewcvs/devel/eclipse-mylyn/[eclipse-mylyn] (specifically the patches related to `org.eclipse.mylyn.webcore`).
|
||||
However, we end up with the plugin classes themselves being expanded in the `+org+` directory. https://bugzilla.redhat.com/273881[Bug #273881] causes build failures when building debuginfo packages in this case. The acceptable workaround is to modify the build.properties file in the plugin to JAR the plugin code separately (ex. `+mylyn-webcore.jar+`) and include it within this expanded plugin directory. An example of this work-around can be seen in http://cvs.fedoraproject.org/viewcvs/devel/eclipse-mylyn/[eclipse-mylyn] (specifically the patches related to `+org.eclipse.mylyn.webcore+`).
|
||||
|
||||
=== rpmstubby
|
||||
|
||||
`rpmstubby` is a small project that is part of the http://eclipse.org/linuxtools[linuxdistros project] at eclipse.org. Its aim is to make packaging Eclipse plugins as RPMs extremely simple. Specfiles for packages like `eclipse-mylyn` were originally stubbed out using it. Available as eclipse-rpmstubby package.
|
||||
`+rpmstubby+` is a small project that is part of the http://eclipse.org/linuxtools[linuxdistros project] at eclipse.org. Its aim is to make packaging Eclipse plugins as RPMs extremely simple. Specfiles for packages like `+eclipse-mylyn+` were originally stubbed out using it. Available as eclipse-rpmstubby package.
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -40,49 +40,49 @@ The compiled elisp source and the elisp source files should be packaged as part
|
|||
== File locations
|
||||
|
||||
1. File locations for GNU Emacs add-on (sub-)packages:
|
||||
* All elisp and related files for the package should be installed in the directory `%{_emacs_sitelispdir}/foo`.
|
||||
* If the package requires a startup file this should be called foo-init.el and be placed in `%{_emacs_sitestartdir}`.
|
||||
* All elisp and related files for the package should be installed in the directory `+%{_emacs_sitelispdir}/foo+`.
|
||||
* If the package requires a startup file this should be called foo-init.el and be placed in `+%{_emacs_sitestartdir}+`.
|
||||
2. File locations for XEmacs add-on (sub-)packages:
|
||||
* All elisp files for package should be installed in the directory `%{_xemacs_sitelispdir}/foo` (`%{_xemacs_sitelispdir}` translates to `/usr/share/xemacs/site-packages/lisp/`)
|
||||
* All other files for the add-on package should be installed under the relevant sub-directories in `%{_xemacs_sitepkgdir}` eg. `%{_xemacs_sitepkgdir}/etc/foo` (`%{_xemacs_sitepkgdir}` translates to `/usr/share/xemacs/site-packages`).
|
||||
* If the package requires a startup file this should be called `foo-init.el` and be placed in `%{_xemacs_sitestartdir}`.
|
||||
* All elisp files for package should be installed in the directory `+%{_xemacs_sitelispdir}/foo+` (`+%{_xemacs_sitelispdir}+` translates to `+/usr/share/xemacs/site-packages/lisp/+`)
|
||||
* All other files for the add-on package should be installed under the relevant sub-directories in `+%{_xemacs_sitepkgdir}+` eg. `+%{_xemacs_sitepkgdir}/etc/foo+` (`+%{_xemacs_sitepkgdir}+` translates to `+/usr/share/xemacs/site-packages+`).
|
||||
* If the package requires a startup file this should be called `+foo-init.el+` and be placed in `+%{_xemacs_sitestartdir}+`.
|
||||
|
||||
== Package Requires
|
||||
|
||||
=== Case I
|
||||
|
||||
1. Package Requires for GNU Emacs add-on (sub-)packages
|
||||
* Where relevant emacs-foo must have `Requires: emacs-common-foo = %{version}-%{release}`
|
||||
* emacs-foo must have `Requires: emacs(bin) >= %{_emacs_version}`
|
||||
* Where relevant emacs-foo must have `+Requires: emacs-common-foo = %{version}-%{release}+`
|
||||
* emacs-foo must have `+Requires: emacs(bin) >= %{_emacs_version}+`
|
||||
2. Package Requires for XEmacs add-on (sub-)packages
|
||||
* Where relevant xemacs-foo must have `Requires: emacs-common-foo = %{version}-%{release}`
|
||||
* xemacs-foo must have `Requires: xemacs(bin) >= %{_xemacs_version}`
|
||||
* Where relevant xemacs-foo must have `+Requires: emacs-common-foo = %{version}-%{release}+`
|
||||
* xemacs-foo must have `+Requires: xemacs(bin) >= %{_xemacs_version}+`
|
||||
|
||||
=== Case II
|
||||
|
||||
1. If the package has auxillary files for use with GNU Emacs, the package must have `Requires: emacs-filesystem >= %{_emacs_version}`
|
||||
2. If the package has auxillary files for use with XEmacs, the package must have `Requires: xemacs-filesystem >= %{_xemacs_version}`
|
||||
1. If the package has auxillary files for use with GNU Emacs, the package must have `+Requires: emacs-filesystem >= %{_emacs_version}+`
|
||||
2. If the package has auxillary files for use with XEmacs, the package must have `+Requires: xemacs-filesystem >= %{_xemacs_version}+`
|
||||
|
||||
== Package BuildRequires
|
||||
|
||||
1. Package BuildRequires for GNU Emacs add-on packages:
|
||||
* In general it should suffice to have `BuildRequires: emacs`
|
||||
* In general it should suffice to have `+BuildRequires: emacs+`
|
||||
2. Package BuildRequires for XEmacs add-on packages:
|
||||
* In general it should suffice to have `BuildRequires: xemacs`
|
||||
* It may be necessary to also add `BuildRequires: xemacs-devel` in rare circumstances
|
||||
* In general it should suffice to have `+BuildRequires: xemacs+`
|
||||
* It may be necessary to also add `+BuildRequires: xemacs-devel+` in rare circumstances
|
||||
|
||||
== Manual byte compilation
|
||||
|
||||
Usually package Elisp compilation is handled via a make file shipped with the package, but on some occasions it may be necessary to add commands to the %build section of the spec file to byte compile files. The following macros are provided to help with this:
|
||||
|
||||
* For GNU Emacs byte compilation, use `%{_emacs_bytecompile} file.el`
|
||||
* For XEmacs byte compilation, use `%{_xemacs_bytecompile} file.el`
|
||||
* For GNU Emacs byte compilation, use `+%{_emacs_bytecompile} file.el+`
|
||||
* For XEmacs byte compilation, use `+%{_xemacs_bytecompile} file.el+`
|
||||
|
||||
It is a requirement that all Elisp files are byte compiled and packaged, unless there is a good reason not to, in which case this should be documented with a comment in the spec file. If you are packaging for both GNU Emacs and XEmacs, be sure to byte compile for both.
|
||||
|
||||
== Use of BuildArch: noarch
|
||||
|
||||
If an add-on package requires only byte compilation of elisp then `BuildArch: noarch` should be used. This is highly unlikely to ever apply to Case II.
|
||||
If an add-on package requires only byte compilation of elisp then `+BuildArch: noarch+` should be used. This is highly unlikely to ever apply to Case II.
|
||||
|
||||
== Example spec file templates
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
== Introduction
|
||||
|
||||
When one has multiple programs serving the same purpose (for instance SMTP servers such as sendmail, exim and postfix; or print servers such as lprng and cups), it is usual to wrap these using alternatives. Alternatives provides a clean way to have many types of software serving the same purpose installed at the same time and have the commands such as `mail` and `lpr` point to the wanted versions.
|
||||
When one has multiple programs serving the same purpose (for instance SMTP servers such as sendmail, exim and postfix; or print servers such as lprng and cups), it is usual to wrap these using alternatives. Alternatives provides a clean way to have many types of software serving the same purpose installed at the same time and have the commands such as `+mail+` and `+lpr+` point to the wanted versions.
|
||||
|
||||
However, when there are multiple variants that each serve the needs of some user and thus must be available simultaneously by users, the alternatives system simply isn't enough since it is system-wide. This has been reality on supercomputers and clusters for eons, and multiple implementations of a solution has been developed: http://modules.sourceforge.net/[environment modules] and https://www.tacc.utexas.edu/tacc-projects/lmod[Lmod]. Fedora currently makes use of this primarily for handling switching between differen MPI implementations.
|
||||
|
||||
|
|
@ -8,17 +8,17 @@ Environment modules are also useful in situations where a package wants to insta
|
|||
|
||||
== Using environment modules
|
||||
|
||||
To see what modules are available, run `$ module avail`.
|
||||
To load a module run e.g. `$ module load mpi/openmpi-x86_64`.
|
||||
To unload a module, run e.g. `$module unload mpi/openmpi-x86_64`.
|
||||
To see what modules are available, run `+$ module avail+`.
|
||||
To load a module run e.g. `+$ module load mpi/openmpi-x86_64+`.
|
||||
To unload a module, run e.g. `+$module unload mpi/openmpi-x86_64+`.
|
||||
|
||||
The upstream documentation for the module command is available http://modules.sourceforge.net/man/module1.html[here] or with `man module`.
|
||||
The upstream documentation for the module command is available http://modules.sourceforge.net/man/module1.html[here] or with `+man module+`.
|
||||
|
||||
== Creating environment modules
|
||||
|
||||
To install an environment module, place a module file into `%{_modulesdir}`, which should evaluate to `/usr/share/modulefiles`. This macro is available in Fedora 21+ and EPEL 7+. The directory `/usr/share/Modules/modulefiles` is to be used only for internal modules of environment-modules. `/etc/modulefiles` is available to local system administrator use.
|
||||
To install an environment module, place a module file into `+%{_modulesdir}+`, which should evaluate to `+/usr/share/modulefiles+`. This macro is available in Fedora 21+ and EPEL 7+. The directory `+/usr/share/Modules/modulefiles+` is to be used only for internal modules of environment-modules. `+/etc/modulefiles+` is available to local system administrator use.
|
||||
|
||||
The module files are plain text with optional tcl syntax, for instance an environment module for 64-bit OpenMPI `mpi/openmpi-x86_64`:
|
||||
The module files are plain text with optional tcl syntax, for instance an environment module for 64-bit OpenMPI `+mpi/openmpi-x86_64+`:
|
||||
|
||||
....
|
||||
#%Module 1.0
|
||||
|
|
@ -42,13 +42,13 @@ setenv MPI_SUFFIX _openmpi
|
|||
setenv MPI_HOME /usr/lib64/openmpi
|
||||
....
|
||||
|
||||
The module file begins with the magic cookie `#%Module `, where is the version of the module file used. The current version is 1.0.
|
||||
The module file begins with the magic cookie `+#%Module +`, where is the version of the module file used. The current version is 1.0.
|
||||
|
||||
The above commands prepends the path with the bindir of the 64-bit OpenMPI (compiled with GCC) and adds the relevant library path. Then it sets various environment variables.
|
||||
|
||||
It is also possible to set `CFLAGS` and `LDFLAGS` with the above manner, but in the case of MPI compilers it is not necessary since the compilers are invoked with the `mpicc`, `mpicxx`, `mpif77` and `mpif90` wrappers that already contain the necessary include and library paths. Also, in the case of development packages an override of `CFLAGS` and/or `LDFLAGS` is not sane, as it may cause trouble in building RPMs as it overrides `%{optflags}`.
|
||||
It is also possible to set `+CFLAGS+` and `+LDFLAGS+` with the above manner, but in the case of MPI compilers it is not necessary since the compilers are invoked with the `+mpicc+`, `+mpicxx+`, `+mpif77+` and `+mpif90+` wrappers that already contain the necessary include and library paths. Also, in the case of development packages an override of `+CFLAGS+` and/or `+LDFLAGS+` is not sane, as it may cause trouble in building RPMs as it overrides `+%{optflags}+`.
|
||||
|
||||
The upstream documentation for module files is available http://modules.sourceforge.net/man/modulefile4.html[here] or with `man modulefile`.
|
||||
The upstream documentation for module files is available http://modules.sourceforge.net/man/modulefile4.html[here] or with `+man modulefile+`.
|
||||
|
||||
== Switching between module implementations
|
||||
|
||||
|
|
|
|||
|
|
@ -125,9 +125,9 @@ Likewise, installation of stack-specific configuration files is allowed, if they
|
|||
|
||||
=== Licensing Information in Metadata
|
||||
|
||||
The "copyright notice" field (tag #0) of the "name" table of TTF and OTF files *MUST* be populated and contain accurate information. Additionally, if information is provided in the "license description" (#13) or "license info URL" (#14) fields are populated, the information contained therein must also be accurate. You can use User:Patches/ttname[`ttname`] to review the metadata included with the font to check it for accuracy.
|
||||
The "copyright notice" field (tag #0) of the "name" table of TTF and OTF files *MUST* be populated and contain accurate information. Additionally, if information is provided in the "license description" (#13) or "license info URL" (#14) fields are populated, the information contained therein must also be accurate. You can use User:Patches/ttname[`+ttname+`] to review the metadata included with the font to check it for accuracy.
|
||||
|
||||
If the metadata is incorrect, packagers should work with upstream to ensure the metadata is properly populated there, so all users of the font can benefit from the corrections. If upstream is non-responsive or you are waiting on a new release for the corrections, you can also use `ttname` in `%prep` to correct the metadata for the Fedora package.
|
||||
If the metadata is incorrect, packagers should work with upstream to ensure the metadata is properly populated there, so all users of the font can benefit from the corrections. If upstream is non-responsive or you are waiting on a new release for the corrections, you can also use `+ttname+` in `+%prep+` to correct the metadata for the Fedora package.
|
||||
|
||||
==== Checking the metadata with ttname
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ ttname -a font.ttf
|
|||
|
||||
You can also use ttname to set the fields if upstream is nonresponsive to your requests to correct it.
|
||||
|
||||
For example, you could run this in `%prep` to populate all the relevant fields with information contained in the package:
|
||||
For example, you could run this in `+%prep+` to populate all the relevant fields with information contained in the package:
|
||||
|
||||
....
|
||||
ttname -a --copyright="$(head -n1 LICENSE)" --license="$(cat LICENSE)" --license-url="http://scripts.sil.org/OFL" font.ttf
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
== Modules and include files
|
||||
|
||||
The fortran modules files, ending in .mod are files describing a fortran 90 (and above) module API and ABI. These are not like C header files describing an API, they are compiler dependent and arch dependent, and not easily readable by a human being. They are nevertheless searched for in the includes directories by gfortran (in directories specified with `-I`).
|
||||
The fortran modules files, ending in .mod are files describing a fortran 90 (and above) module API and ABI. These are not like C header files describing an API, they are compiler dependent and arch dependent, and not easily readable by a human being. They are nevertheless searched for in the includes directories by gfortran (in directories specified with `+-I+`).
|
||||
|
||||
Due to the ABI specificity, the module directory used must be architecture specific. In addition each gfortran release (e.g. from 4.4 to 4.5) may lead to an incompatible change in the .mod files, therefore mass rebuilds of Fortran packages must take place when gfortran is updated.
|
||||
|
||||
|
|
@ -8,12 +8,12 @@ Fortran can also use include files, similar to C headers. Common used filename s
|
|||
|
||||
== Packaging of Fortran programs
|
||||
|
||||
Fortran programs in Fedora MUST be compiled, if possible, using the default Fortran compiler in Fedora, 'gfortran'. As usual, standard Fedora optimization flags `%{optflags}` MUST be used in the compilation.
|
||||
Fortran programs in Fedora MUST be compiled, if possible, using the default Fortran compiler in Fedora, 'gfortran'. As usual, standard Fedora optimization flags `+%{optflags}+` MUST be used in the compilation.
|
||||
|
||||
Fortran include files MUST be placed in the standard include directory: either directly in `%{_includedir}`, or if headers have general names or upstream recommends having an own directory, in e.g. `%{_includedir}/%{name}`.
|
||||
Fortran include files MUST be placed in the standard include directory: either directly in `+%{_includedir}+`, or if headers have general names or upstream recommends having an own directory, in e.g. `+%{_includedir}/%{name}+`.
|
||||
|
||||
As Fortran modules are architecture and GCC version specific, they MUST be placed into `%{_fmoddir}` (or its package-specific subfolder in case the modules have generic names), which is owned by 'gcc-gfortran'. For directory ownership any packages containing Fortran modules MUST `Requires: gcc-gfortran%{_isa}`.
|
||||
As Fortran modules are architecture and GCC version specific, they MUST be placed into `+%{_fmoddir}+` (or its package-specific subfolder in case the modules have generic names), which is owned by 'gcc-gfortran'. For directory ownership any packages containing Fortran modules MUST `+Requires: gcc-gfortran%{_isa}+`.
|
||||
|
||||
To use the modules in the Fortran module directory, one needs to add `-I%{_fmoddir}` to the compiler flags (this is already included in `FFLAGS` used by `%configure`).
|
||||
To use the modules in the Fortran module directory, one needs to add `+-I%{_fmoddir}+` to the compiler flags (this is already included in `+FFLAGS+` used by `+%configure+`).
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -8,43 +8,43 @@ The main GAP package and its attendant libraries and help system are in packages
|
|||
|
||||
== Add-on Location
|
||||
|
||||
GAP add-ons are written to be installed simply by unpacking them in an existing GAP directory tree. For most add-ons, the only build action necessary is building the documentation. However, since the add-on authors assumed this would happen within the GAP tree, add-ons freely use relative paths to access GAP files. For example, packages that use TTH to build documentation (see below) commonly invoke `../../../convert.pl`. The RPM spec file MUST account for this, either by altering the add-on to point to paths under `%{_gap_dir}`, or by creating symbolic links to create the appearance that the build is taking place inside the GAP tree. If the add-on is altered for the build, the spec file SHOULD arrange for the original (unaltered) files to be installed, so that paths are correct after installation.
|
||||
GAP add-ons are written to be installed simply by unpacking them in an existing GAP directory tree. For most add-ons, the only build action necessary is building the documentation. However, since the add-on authors assumed this would happen within the GAP tree, add-ons freely use relative paths to access GAP files. For example, packages that use TTH to build documentation (see below) commonly invoke `+../../../convert.pl+`. The RPM spec file MUST account for this, either by altering the add-on to point to paths under `+%{_gap_dir}+`, or by creating symbolic links to create the appearance that the build is taking place inside the GAP tree. If the add-on is altered for the build, the spec file SHOULD arrange for the original (unaltered) files to be installed, so that paths are correct after installation.
|
||||
|
||||
== BuildRequires
|
||||
|
||||
All add-ons MUST include `BuildRequires: gap-devel`, as that package contains essential tools needed for compiling binary modules and building documentation, as well as a set of RPM macros for use in spec files. Each add-on also MUST contain a `BuildRequires` that is dependent on the documentation style used by the GAP add-on.
|
||||
All add-ons MUST include `+BuildRequires: gap-devel+`, as that package contains essential tools needed for compiling binary modules and building documentation, as well as a set of RPM macros for use in spec files. Each add-on also MUST contain a `+BuildRequires+` that is dependent on the documentation style used by the GAP add-on.
|
||||
|
||||
=== TTH
|
||||
|
||||
Add-ons that use a `buildman.pe` or `convert.pl` script to build documentation also need `BuildRequires: tth` in order to build HTML documentation pages from TeX input. Some add-ons bundle these scripts, as well as a few auxiliary files. Add-ons containing any of the following files should be modified to link to the version of the file contained in the gap or gap-devel packages.
|
||||
Add-ons that use a `+buildman.pe+` or `+convert.pl+` script to build documentation also need `+BuildRequires: tth+` in order to build HTML documentation pages from TeX input. Some add-ons bundle these scripts, as well as a few auxiliary files. Add-ons containing any of the following files should be modified to link to the version of the file contained in the gap or gap-devel packages.
|
||||
|
||||
* `gapmacro.tex` → `%{_gap_dir}/doc/gapmacro.tex`
|
||||
* `gapmacrodoc.tex` → `%{_gap_dir}/doc/gapmacrodoc.tex`
|
||||
* `manualbib.xml` → `%{_gap_dir}/doc/manualbib.xml`
|
||||
* `manualbib.xml.bib` → `%{_gap_dir}/doc/manualbib.xml.bib`
|
||||
* `manualindex` → `%{_gap_dir}/doc/manualindex`
|
||||
* `buildman.pe` → `%{_gap_dir}/etc/buildman.pe`
|
||||
* `convert.pl` → `%{_gap_dir}/etc/convert.pl`
|
||||
* `+gapmacro.tex+` → `+%{_gap_dir}/doc/gapmacro.tex+`
|
||||
* `+gapmacrodoc.tex+` → `+%{_gap_dir}/doc/gapmacrodoc.tex+`
|
||||
* `+manualbib.xml+` → `+%{_gap_dir}/doc/manualbib.xml+`
|
||||
* `+manualbib.xml.bib+` → `+%{_gap_dir}/doc/manualbib.xml.bib+`
|
||||
* `+manualindex+` → `+%{_gap_dir}/doc/manualindex+`
|
||||
* `+buildman.pe+` → `+%{_gap_dir}/etc/buildman.pe+`
|
||||
* `+convert.pl+` → `+%{_gap_dir}/etc/convert.pl+`
|
||||
|
||||
=== GAPDoc
|
||||
|
||||
Add-ons that use GAPDoc to build documentation MUST include `BuildRequires: GAPDoc-latex` to pull in the necessary LaTeX packages. These packages do not need `Requires: GAPDoc`, since `gap-core` depends on GAPDoc.
|
||||
Add-ons that use GAPDoc to build documentation MUST include `+BuildRequires: GAPDoc-latex+` to pull in the necessary LaTeX packages. These packages do not need `+Requires: GAPDoc+`, since `+gap-core+` depends on GAPDoc.
|
||||
|
||||
=== Autodoc
|
||||
|
||||
Add-ons that use Autodoc to build documentation MUST include `BuildRequires: gap-pkg-autodoc`. Such packages do not need to include `BuildRequires: GAPDoc-latex`, as the Autodoc package `Requires: GAPDoc-latex`.
|
||||
Add-ons that use Autodoc to build documentation MUST include `+BuildRequires: gap-pkg-autodoc+`. Such packages do not need to include `+BuildRequires: GAPDoc-latex+`, as the Autodoc package `+Requires: GAPDoc-latex+`.
|
||||
|
||||
== Requires, Recommends, and Suggests
|
||||
|
||||
All add-ons MUST include `Requires: gap-core`. In addition, dependencies on other GAP packages, as recorded in `PackageInfo.g`, MUST be specified, with the exception of `GAPDoc`, as noted above. GAP has a 2-level dependency system, specified with `NeededOtherPackages` and `SuggestedOtherPackages` tags in `PackageInfo.g`. How these dependencies map onto the 3-level RPM dependency system of Requires, Recommends, and Suggests is left to the discretion of the Fedora packager.
|
||||
All add-ons MUST include `+Requires: gap-core+`. In addition, dependencies on other GAP packages, as recorded in `+PackageInfo.g+`, MUST be specified, with the exception of `+GAPDoc+`, as noted above. GAP has a 2-level dependency system, specified with `+NeededOtherPackages+` and `+SuggestedOtherPackages+` tags in `+PackageInfo.g+`. How these dependencies map onto the 3-level RPM dependency system of Requires, Recommends, and Suggests is left to the discretion of the Fedora packager.
|
||||
|
||||
== Unnecessary Files
|
||||
|
||||
GAP add-ons are intended to be unpacked in place within a GAP directory tree. Ordinarily, the entire distribution directory is copied into `%{_gap_dir}/pkg`. This includes the documentation directories, which are consumed by the tools contained in gap-online-help. However, some files are not needed in the final install directory. Files that should not appear there include:
|
||||
GAP add-ons are intended to be unpacked in place within a GAP directory tree. Ordinarily, the entire distribution directory is copied into `+%{_gap_dir}/pkg+`. This includes the documentation directories, which are consumed by the tools contained in gap-online-help. However, some files are not needed in the final install directory. Files that should not appear there include:
|
||||
|
||||
* Textual descriptions of the add-on, such as a README
|
||||
* License files (COPYING, COPYRIGHT, LICENSE, etc.)
|
||||
* Files for building documentation, often called `make_doc`
|
||||
* Files for building documentation, often called `+make_doc+`
|
||||
* Files generated by LaTeX, including files with these suffixes:
|
||||
** .aux
|
||||
** .bbl
|
||||
|
|
@ -59,10 +59,10 @@ Note that License files MUST still be included in the package with the %license
|
|||
|
||||
== Documentation
|
||||
|
||||
Since GAP documentation must be installed under `%{_gap_dir}/pkg` for the builtin documentation browser to find it, such documentation SHOULD NOT be duplicated with `%doc`. However, the documentation SHOULD still be marked as such so that documentation-free installs work as expected. Most add-ons SHOULD include `%docdir` declarations in the `%files` section of the spec file; e.g., `%docdir %{_gap_dir}/pkg/%{pkgname}/doc` and `%docdir %{_gap_dir}/pkg/%{pkgname}/htm`.
|
||||
Since GAP documentation must be installed under `+%{_gap_dir}/pkg+` for the builtin documentation browser to find it, such documentation SHOULD NOT be duplicated with `+%doc+`. However, the documentation SHOULD still be marked as such so that documentation-free installs work as expected. Most add-ons SHOULD include `+%docdir+` declarations in the `+%files+` section of the spec file; e.g., `+%docdir %{_gap_dir}/pkg/%{pkgname}/doc+` and `+%docdir %{_gap_dir}/pkg/%{pkgname}/htm+`.
|
||||
|
||||
== Testing
|
||||
|
||||
Some add-ons have not yet updated their test suites for GAP 4.8. If a GAP add-on's test suite invokes `ReadTest(foo)`, modify it to invoke `Test(foo, rec( compareFunction := "uptowhitespace" ) )` instead for Fedora 24 and later.
|
||||
Some add-ons have not yet updated their test suites for GAP 4.8. If a GAP add-on's test suite invokes `+ReadTest(foo)+`, modify it to invoke `+Test(foo, rec( compareFunction := "uptowhitespace" ) )+` instead for Fedora 24 and later.
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
= GCJ Guidelines
|
||||
|
||||
GCJ AOT bits *SHOULD* be built and included in packages. If GCJ-specific issues prevent you from building the package, it is permissible to simply omit GCJ support and build using OpenJDK. However, please file a bug against the `gcc` component in Red Hat bugzilla. Compilation into native code must be optional and enabled by default, if present.
|
||||
GCJ AOT bits *SHOULD* be built and included in packages. If GCJ-specific issues prevent you from building the package, it is permissible to simply omit GCJ support and build using OpenJDK. However, please file a bug against the `+gcc+` component in Red Hat bugzilla. Compilation into native code must be optional and enabled by default, if present.
|
||||
|
||||
In some rare cases Java packages might not contain any executable code whatsoever so AOT-compiling for gcj would not be required. An example of such a package would be one that contained only annotation definitions.
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ BuildArch: noarch
|
|||
%endif
|
||||
....
|
||||
|
||||
\1. Add the following to the end of `%install` section:
|
||||
\1. Add the following to the end of `+%install+` section:
|
||||
|
||||
....
|
||||
%if %{with_gcj}
|
||||
|
|
@ -43,7 +43,7 @@ BuildArch: noarch
|
|||
%endif
|
||||
....
|
||||
|
||||
\1. Add the following to the package's `%post` and `%postun` sections, creating the sections if necessary:
|
||||
\1. Add the following to the package's `+%post+` and `+%postun+` sections, creating the sections if necessary:
|
||||
|
||||
....
|
||||
%if %{with_gcj}
|
||||
|
|
@ -54,7 +54,7 @@ BuildArch: noarch
|
|||
%endif
|
||||
....
|
||||
|
||||
\1. Add the following to the `%files` section:
|
||||
\1. Add the following to the `+%files+` section:
|
||||
|
||||
....
|
||||
%if %{with_gcj}
|
||||
|
|
@ -62,9 +62,9 @@ BuildArch: noarch
|
|||
%endif
|
||||
....
|
||||
|
||||
* For packages in which all JAR files are in one subpackage, the `Requires()`, `%post`, `%postun` and `%files` lines should refer to that subpackage.
|
||||
* For packages in which all JAR files are in one subpackage, the `+Requires()+`, `+%post+`, `+%postun+` and `+%files+` lines should refer to that subpackage.
|
||||
|
||||
* For packages in which more than one subpackage (including the main package) contains JAR files, then each subpackage should have its own `Requires()`, `%post` and `%postun` lines, and the `%files` lists should be split such that the subpackage that contains `/path/to/foo-x.y.z.jar` should have the following `%files` line:
|
||||
* For packages in which more than one subpackage (including the main package) contains JAR files, then each subpackage should have its own `+Requires()+`, `+%post+` and `+%postun+` lines, and the `+%files+` lists should be split such that the subpackage that contains `+/path/to/foo-x.y.z.jar+` should have the following `+%files+` line:
|
||||
|
||||
....
|
||||
%if %{with_gcj}
|
||||
|
|
@ -72,6 +72,6 @@ BuildArch: noarch
|
|||
%endif
|
||||
....
|
||||
|
||||
Note that the path has been stripped and `.*` has been appended.
|
||||
Note that the path has been stripped and `+.*+` has been appended.
|
||||
|
||||
Category:_Packaging_guidelines[Category: Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -101,15 +101,15 @@ Some of the GPT packages in the huge Globus Toolkit installer tarball contain co
|
|||
|
||||
== Autogenerating specfiles (informational)
|
||||
|
||||
It is possible to autogenerate an initial version of the specfile from the information in the GPT source package description file by running the `globus-spec-creator` script, which is installed as part of the *globus-core* package. Using this script is optional, but provides increased maintainability of the package and reduces the risk of cut and paste errors. The following examples shows the autogenerated specfiles generated by the script in a few cases.
|
||||
It is possible to autogenerate an initial version of the specfile from the information in the GPT source package description file by running the `+globus-spec-creator+` script, which is installed as part of the *globus-core* package. Using this script is optional, but provides increased maintainability of the package and reduces the risk of cut and paste errors. The following examples shows the autogenerated specfiles generated by the script in a few cases.
|
||||
|
||||
=== Globus package that provides a library
|
||||
|
||||
`globus-spec-creator -g globus_gsi_openssl_error-0.14/pkgdata/pkg_data_src.gpt.in -d gsi/openssl_error/source`
|
||||
`+globus-spec-creator -g globus_gsi_openssl_error-0.14/pkgdata/pkg_data_src.gpt.in -d gsi/openssl_error/source+`
|
||||
|
||||
* The `-g` option specifies the GPT source package description file
|
||||
* The `-d` option specifies the directory in the installer from where the code was extracted
|
||||
* The `-e` option can be used to specify the packager's e-mail address (defaults to username@host)
|
||||
* The `+-g+` option specifies the GPT source package description file
|
||||
* The `+-d+` option specifies the directory in the installer from where the code was extracted
|
||||
* The `+-e+` option can be used to specify the packager's e-mail address (defaults to username@host)
|
||||
|
||||
....
|
||||
%ifarch alpha ia64 ppc64 s390x sparc64 x86_64
|
||||
|
|
@ -221,7 +221,7 @@ rm -f globus_automake*
|
|||
rm -rf autom4te.cache
|
||||
|
||||
# Remove flavor tags
|
||||
for f in `find . -name Makefile.am` ; do
|
||||
for f in `+find . -name Makefile.am+` ; do
|
||||
sed -e 's!^flavorinclude_HEADERS!include_HEADERS!' \
|
||||
-e 's!\(lib[a-zA-Z_]*\)_$(GLOBUS_FLAVOR_NAME)\.la!\1.la!g' \
|
||||
-e 's!^\(lib[a-zA-Z_]*\)___GLOBUS_FLAVOR_NAME__la_!\1_la_!' -i $f
|
||||
|
|
@ -306,7 +306,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||
|
||||
=== Globus package that only provides programs
|
||||
|
||||
`globus-spec-creator -g globus_proxy_utils-2.5/pkgdata/pkg_data_src.gpt.in -d gsi/proxy/proxy_utils/source`
|
||||
`+globus-spec-creator -g globus_proxy_utils-2.5/pkgdata/pkg_data_src.gpt.in -d gsi/proxy/proxy_utils/source+`
|
||||
|
||||
....
|
||||
%ifarch alpha ia64 ppc64 s390x sparc64 x86_64
|
||||
|
|
@ -403,10 +403,10 @@ rm -rf $RPM_BUILD_ROOT
|
|||
|
||||
=== Globus package containing a plugin
|
||||
|
||||
`globus-spec-creator -g globus_xio_popen_driver-0.2/pkgdata/pkg_data_src.gpt.in -d xio/drivers/popen/source -r 2 -n %{name}-wrong-dep.patch %{name}-wrong-desc.patch`
|
||||
`+globus-spec-creator -g globus_xio_popen_driver-0.2/pkgdata/pkg_data_src.gpt.in -d xio/drivers/popen/source -r 2 -n %{name}-wrong-dep.patch %{name}-wrong-desc.patch+`
|
||||
|
||||
* The `-r` option is used to set the release version of the specfile to 2 (default is 1, as in the previous examples)
|
||||
* The `-n` option can be used to disable the generation of a doc package for Globus packages that don't have any doxygen markup in the sources.
|
||||
* The `+-r+` option is used to set the release version of the specfile to 2 (default is 1, as in the previous examples)
|
||||
* The `+-n+` option can be used to disable the generation of a doc package for Globus packages that don't have any doxygen markup in the sources.
|
||||
|
||||
In this case the autogenerated specfile will instead of the commands for deleting the .la files contain a comment explaining why the .la files can not be removed.
|
||||
|
||||
|
|
@ -485,7 +485,7 @@ rm -f globus_automake*
|
|||
rm -rf autom4te.cache
|
||||
|
||||
# Remove flavor tags
|
||||
for f in `find . -name Makefile.am` ; do
|
||||
for f in `+find . -name Makefile.am+` ; do
|
||||
sed -e 's!^flavorinclude_HEADERS!include_HEADERS!' \
|
||||
-e 's!\(lib[a-zA-Z_]*\)_$(GLOBUS_FLAVOR_NAME)\.la!\1.la!g' \
|
||||
-e 's!^\(lib[a-zA-Z_]*\)___GLOBUS_FLAVOR_NAME__la_!\1_la_!' -i $f
|
||||
|
|
@ -507,7 +507,7 @@ GLOBUSPACKAGEDIR=$RPM_BUILD_ROOT%{_datadir}/globus/packages
|
|||
|
||||
# This library is opened using lt_dlopenext, so the libtool archives
|
||||
# (.la files) can not be removed - fix the libdir...
|
||||
for lib in `find $RPM_BUILD_ROOT%{_libdir} -name 'lib*.la'` ; do
|
||||
for lib in `+find $RPM_BUILD_ROOT%{_libdir} -name 'lib*.la'+` ; do
|
||||
sed "s!^libdir=.*!libdir=\'%{_libdir}\'!" -i $lib
|
||||
done
|
||||
|
||||
|
|
@ -552,9 +552,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||
|
||||
=== Globus package that provides both a library and programs and that has a corresponding setup package
|
||||
|
||||
`globus-spec-creator -g globus_common-10.2/pkgdata/pkg_data_src.gpt.in -s globus_common_setup-2.6/pkgdata/pkg_data_src.gpt.in -r 3 -d common/source`
|
||||
`+globus-spec-creator -g globus_common-10.2/pkgdata/pkg_data_src.gpt.in -s globus_common_setup-2.6/pkgdata/pkg_data_src.gpt.in -r 3 -d common/source+`
|
||||
|
||||
* The `-s` option is used to indicate the GPT source package description file for the setup package
|
||||
* The `+-s+` option is used to indicate the GPT source package description file for the setup package
|
||||
|
||||
The patches have been excluded from this example to keep it short. For this package some additional editing is needed. Compare the autogenerated file below with the http://cvs.fedoraproject.org/viewvc/devel/globus-common/globus-common.spec?view=markup[specfile in the actual package] to see the differences.
|
||||
|
||||
|
|
@ -694,7 +694,7 @@ rm -f globus_automake*
|
|||
rm -rf autom4te.cache
|
||||
|
||||
# Remove flavor tags
|
||||
for f in `find . -name Makefile.am` ; do
|
||||
for f in `+find . -name Makefile.am+` ; do
|
||||
sed -e 's!^flavorinclude_HEADERS!include_HEADERS!' \
|
||||
-e 's!\(lib[a-zA-Z_]*\)_$(GLOBUS_FLAVOR_NAME)\.la!\1.la!g' \
|
||||
-e 's!^\(lib[a-zA-Z_]*\)___GLOBUS_FLAVOR_NAME__la_!\1_la_!' -i $f
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Most Haskell packages are released on http://hackage.haskell.org[Hackage] and us
|
|||
== Spec file templates
|
||||
|
||||
Spec files in line with these templates are generated automatically by the https://apps.fedoraproject.org/packages/cabal-rpm[cabal-rpm] packaging tool
|
||||
which also adds dependencies listed in the package's `.cabal` configuration file.
|
||||
which also adds dependencies listed in the package's `+.cabal+` configuration file.
|
||||
Most packages should then build, though for some packages it may be necessary to specify some additional BuildRequires and/or Requires, and to check non-Haskell devel dependencies.
|
||||
|
||||
Standardizing the packaging helps to lower the maintenance burden across Fedora's Haskell packages.
|
||||
|
|
@ -197,44 +197,44 @@ This package provides the Haskell %{pkg_name} library development files.
|
|||
|
||||
== Package Naming
|
||||
|
||||
Haskell Bin and BinLib packages should follow the usual Fedora Package Naming Guidelines for base package naming: ie follow the upstream name. Examples include projects like `darcs` and `xmonad`.
|
||||
Haskell Bin and BinLib packages should follow the usual Fedora Package Naming Guidelines for base package naming: ie follow the upstream name. Examples include projects like `+darcs+` and `+xmonad+`.
|
||||
However there may be cases where a Haskell BinLib package is really a Lib package with a minor or unimportant executable: in this case it is better to treat the package a Lib package, optionally with a executable subpackage if appropriate.
|
||||
|
||||
The names of Haskell Lib packages, packaged for `ghc`, are prefixed by "ghc-". For example the Haskell X11 library package is named `ghc-X11`, and the Haskell mmap library package is named `ghc-mmap`, etc.
|
||||
The names of Haskell Lib packages, packaged for `+ghc+`, are prefixed by "ghc-". For example the Haskell X11 library package is named `+ghc-X11+`, and the Haskell mmap library package is named `+ghc-mmap+`, etc.
|
||||
|
||||
Note that having different Haskell source packages named "ghc-xyz" and "xyz" is not allowed since they would both correspond to the same upstream package named "xyz" on Hackage.
|
||||
|
||||
BinLib packages should subpackage their libraries with naming following Lib packages.
|
||||
For example the `xmonad` BinLib package has library subpackages
|
||||
For example the `+xmonad+` BinLib package has library subpackages
|
||||
|
||||
* `ghc-xmonad` for the shared library, and
|
||||
* `ghc-xmonad-devel` for devel files and the static library.
|
||||
* `+ghc-xmonad+` for the shared library, and
|
||||
* `+ghc-xmonad-devel+` for devel files and the static library.
|
||||
|
||||
If a library is packaged for more than one Haskell compiler or interpreter, the base name should instead be prefixed with `haskell`, e.g. `haskell-X11`. Such a package would then have subpackages for each compiler and/or interpreter it is built for (e.g. `ghc-X11`, `hugs98-X11`, etc).
|
||||
If a library is packaged for more than one Haskell compiler or interpreter, the base name should instead be prefixed with `+haskell+`, e.g. `+haskell-X11+`. Such a package would then have subpackages for each compiler and/or interpreter it is built for (e.g. `+ghc-X11+`, `+hugs98-X11+`, etc).
|
||||
|
||||
Package naming preserves case to follow the upstream naming conventions as closely as possible.
|
||||
|
||||
== Headers
|
||||
|
||||
The macro `pkg_name` is used to carry the name of the upstream library package (i.e. without the Fedora "ghc-" prefix).
|
||||
The macro `+pkg_name+` is used to carry the name of the upstream library package (i.e. without the Fedora "ghc-" prefix).
|
||||
It should be defined at the top of Lib and BinLib packages:
|
||||
|
||||
`%global pkg_name `
|
||||
`+%global pkg_name +`
|
||||
|
||||
== Cabal Flags
|
||||
|
||||
Cabal flags for build options should be set by changing the package's `.cabal` file: this can be done with the `cabal-tweak-flag` script to avoid having to carry and maintain patches for this.
|
||||
`%cabal_configure_options` can be set to pass other options to Cabal.
|
||||
Cabal flags for build options should be set by changing the package's `+.cabal+` file: this can be done with the `+cabal-tweak-flag+` script to avoid having to carry and maintain patches for this.
|
||||
`+%cabal_configure_options+` can be set to pass other options to Cabal.
|
||||
|
||||
Modifying the `.cabal` file flags defaults allows packagers and tools like `cabal-rpm` to track actual package dependencies correctly.
|
||||
Modifying the `+.cabal+` file flags defaults allows packagers and tools like `+cabal-rpm+` to track actual package dependencies correctly.
|
||||
|
||||
== Dependency Generation
|
||||
|
||||
Spec file build dependencies are generated by the `cabal-rpm` packaging tool.
|
||||
Spec file build dependencies are generated by the `+cabal-rpm+` packaging tool.
|
||||
|
||||
RPM dependencies for Haskell libraries are automatically generated at build-time by the `ghc-deps.sh` script.
|
||||
RPM dependencies for Haskell libraries are automatically generated at build-time by the `+ghc-deps.sh+` script.
|
||||
|
||||
The `cabal-tweak-dep-ver` script can be used to bump versions of dependencies in the package .cabal file.
|
||||
The `+cabal-tweak-dep-ver+` script can be used to bump versions of dependencies in the package .cabal file.
|
||||
|
||||
== Shared and static library linking
|
||||
|
||||
|
|
@ -247,7 +247,7 @@ Because GHC still assumes static versions of libraries are installed they need t
|
|||
|
||||
Executables in Bin and BinLib packages should be dynamically linked to shared libraries.
|
||||
|
||||
Note that executables in most BinLib packages are currently staticly linked against the library in their own package (unless the .cabal file explicitly lists it as a dependency), but dynamically linked against other dependent libraries. BinLib executables that do link dynamically against their own library should use `%ghc_fix_dynamic_rpath` to fix its RPATH.
|
||||
Note that executables in most BinLib packages are currently staticly linked against the library in their own package (unless the .cabal file explicitly lists it as a dependency), but dynamically linked against other dependent libraries. BinLib executables that do link dynamically against their own library should use `+%ghc_fix_dynamic_rpath+` to fix its RPATH.
|
||||
|
||||
Some particular packages may do user compilation during runtime in which case they will need Requires as well as BuildRequires for their dependencies: examples include xmonad and yi which require their devel package to be present to allow users to relink their configuration or customization.
|
||||
|
||||
|
|
@ -270,7 +270,7 @@ They are used in the templates and explained in more detail below.
|
|||
|
||||
== Bin packages
|
||||
|
||||
Bin package executables should be dynamically linked to shared Haskell libraries when available, but this can be overridden if necessary by defining the `ghc_without_dynamic` macro.
|
||||
Bin package executables should be dynamically linked to shared Haskell libraries when available, but this can be overridden if necessary by defining the `+ghc_without_dynamic+` macro.
|
||||
|
||||
....
|
||||
%build
|
||||
|
|
@ -281,20 +281,20 @@ Bin package executables should be dynamically linked to shared Haskell libraries
|
|||
%ghc_bin_install
|
||||
....
|
||||
|
||||
`%ghc_bin_build` is used to configure and build bin packages. It runs:
|
||||
`+%ghc_bin_build+` is used to configure and build bin packages. It runs:
|
||||
|
||||
* `%global debug_package %{nil}`: debuginfo is disabled since ghc's output is not in GDB format.
|
||||
* `%cabal_configure`: configure the package for building and dynamic linking.
|
||||
* `%cabal build`: builds the package.
|
||||
* `+%global debug_package %{nil}+`: debuginfo is disabled since ghc's output is not in GDB format.
|
||||
* `+%cabal_configure+`: configure the package for building and dynamic linking.
|
||||
* `+%cabal build+`: builds the package.
|
||||
|
||||
`%ghc_bin_install` is used to install bin packages. It runs:
|
||||
`+%ghc_bin_install+` is used to install bin packages. It runs:
|
||||
|
||||
* `%cabal_install`: installs the package.
|
||||
* `%ghc_strip_dynlinked`: strips the dynamically linked binary.
|
||||
* `+%cabal_install+`: installs the package.
|
||||
* `+%ghc_strip_dynlinked+`: strips the dynamically linked binary.
|
||||
|
||||
== Lib and BinLib packages
|
||||
|
||||
BinLib package executables should be dynamically linked to other shared Haskell libraries when available, but this can be overridden if necessary by defining the `ghc_without_dynamic` macro.
|
||||
BinLib package executables should be dynamically linked to other shared Haskell libraries when available, but this can be overridden if necessary by defining the `+ghc_without_dynamic+` macro.
|
||||
|
||||
Devel subpackages need to setup some Requires:
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ Requires(postun): ghc-compiler = %{ghc_version}
|
|||
Requires: ghc-%{pkg_name} = %{version}-%{release}
|
||||
....
|
||||
|
||||
Lib packages need to use `%setup -n`:
|
||||
Lib packages need to use `+%setup -n+`:
|
||||
|
||||
....
|
||||
%prep
|
||||
|
|
@ -333,39 +333,39 @@ Both Lib and BinLib have:
|
|||
%ghc_pkg_recache
|
||||
....
|
||||
|
||||
`%ghc_lib_build` is used to configure, build and generate documentation for Lib and BinLib packages. It runs:
|
||||
`+%ghc_lib_build+` is used to configure, build and generate documentation for Lib and BinLib packages. It runs:
|
||||
|
||||
* `%global debug_package %{nil}`: debuginfo is disabled since ghc's output is not in DWARF format.
|
||||
* `%cabal_configure --ghc -p`: configures the package for building with ghc and profiling. Libraries should build profiling versions of their static libraries.
|
||||
* `%cabal build`: builds the package.
|
||||
* `%cabal haddock`: generates HTML library documentation from the source code.
|
||||
** If necessary (if e.g. documentation is failing to build for some reason) this can be skipped by defining `without_haddock`.
|
||||
** Additionally links to colored html sourcecode are also generated with `hscolour`, which can be disabled by defining `without_hscolour`.
|
||||
* `+%global debug_package %{nil}+`: debuginfo is disabled since ghc's output is not in DWARF format.
|
||||
* `+%cabal_configure --ghc -p+`: configures the package for building with ghc and profiling. Libraries should build profiling versions of their static libraries.
|
||||
* `+%cabal build+`: builds the package.
|
||||
* `+%cabal haddock+`: generates HTML library documentation from the source code.
|
||||
** If necessary (if e.g. documentation is failing to build for some reason) this can be skipped by defining `+without_haddock+`.
|
||||
** Additionally links to colored html sourcecode are also generated with `+hscolour+`, which can be disabled by defining `+without_hscolour+`.
|
||||
|
||||
`%ghc_lib_install` is used to install Lib and BinLib packages. It runs:
|
||||
`+%ghc_lib_install+` is used to install Lib and BinLib packages. It runs:
|
||||
|
||||
* `%cabal_install`: installs the package without registering it in ghc-pkg.
|
||||
* `%cabal_pkg_conf`: creates ghc-pkg .conf metadata file for package installation time
|
||||
* `%ghc_gen_filelists`: generates rpm filelists.
|
||||
* `%ghc_strip_dynlinked`: strips dynamically linked objects.
|
||||
* `+%cabal_install+`: installs the package without registering it in ghc-pkg.
|
||||
* `+%cabal_pkg_conf+`: creates ghc-pkg .conf metadata file for package installation time
|
||||
* `+%ghc_gen_filelists+`: generates rpm filelists.
|
||||
* `+%ghc_strip_dynlinked+`: strips dynamically linked objects.
|
||||
|
||||
`%ghc_pkg_recache`: used in %post and %postun for devel subpackage - refreshes the ghc package cache database with .conf file data.
|
||||
`+%ghc_pkg_recache+`: used in %post and %postun for devel subpackage - refreshes the ghc package cache database with .conf file data.
|
||||
|
||||
== Directories
|
||||
|
||||
GHC libraries are installed under `%ghcpkgdir/%{pkg_name}-%{version}`:
|
||||
GHC libraries are installed under `+%ghcpkgdir/%{pkg_name}-%{version}+`:
|
||||
|
||||
Library documentation lives under `%ghclibdocdir/%{pkg_name}-%{version}`.
|
||||
Library documentation lives under `+%ghclibdocdir/%{pkg_name}-%{version}+`.
|
||||
|
||||
== File lists
|
||||
|
||||
Filelists for shared and devel library subpackages are generated through `%ghc_lib_install` using the macro `%ghc_gen_filelists`.
|
||||
Filelists for shared and devel library subpackages are generated through `+%ghc_lib_install+` using the macro `+%ghc_gen_filelists+`.
|
||||
|
||||
It generates the filelists `ghc-%{pkg_name}.files` and `ghc-%{pkg_name}-devel.files`.
|
||||
It generates the filelists `+ghc-%{pkg_name}.files+` and `+ghc-%{pkg_name}-devel.files+`.
|
||||
|
||||
== Compiling non-Cabal packages
|
||||
|
||||
Packages compiling Haskell code without Cabal, ie directly with `ghc` or `ghc --make`, should use `-O1` optimization, like Cabal does by default.
|
||||
Packages compiling Haskell code without Cabal, ie directly with `+ghc+` or `+ghc --make+`, should use `+-O1+` optimization, like Cabal does by default.
|
||||
|
||||
== References
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Many system services require some amount of initial setup before they can run pr
|
|||
|
||||
Traditionally, this was done by RPM scriptlets as part of the installation or upgrade of a package. This was sensible for a time when the majority of installations were performed by attended or unattended installers (such as anaconda and kickstart).
|
||||
|
||||
Today we see an increased reliance on generating virtual machine images for use in both traditional and cloud-computing environments. In those cases, having system-specific data created at package installation time is problematic. It means that the production of such images need to have significant care applied to remove any system-specific information about them and then additional tools written to apply the corrected information post-deployment. *The goal of this guideline is to ensure that if a system clean-up service such as virt-sysprep is run on the system and then the machine is rebooted, any service that requires first-time configuration will re-run it.* The mechanism by which we will accomplish this is to remove such first-time configuration from RPM scriptlets (e.g. `%post`) and instead execute this configuration as part of service startup with systemd.
|
||||
Today we see an increased reliance on generating virtual machine images for use in both traditional and cloud-computing environments. In those cases, having system-specific data created at package installation time is problematic. It means that the production of such images need to have significant care applied to remove any system-specific information about them and then additional tools written to apply the corrected information post-deployment. *The goal of this guideline is to ensure that if a system clean-up service such as virt-sysprep is run on the system and then the machine is rebooted, any service that requires first-time configuration will re-run it.* The mechanism by which we will accomplish this is to remove such first-time configuration from RPM scriptlets (e.g. `+%post+`) and instead execute this configuration as part of service startup with systemd.
|
||||
|
||||
This guideline describes a mechanism that can be used for both traditional and cloud-based deployment styles.
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ Therefore, instead of creating a self-signed certificate, we will create a tempo
|
|||
|
||||
== Common Guidelines
|
||||
|
||||
For all system-specific cases, we will take advantage of systemd's http://www.freedesktop.org/software/systemd/man/systemd.service.html[service] functionality. Packagers will create a new service unit file for each service unit in their package that requires per-system configuration. This service unit will be named `-init.service` and installed to `/usr/lib/systemd/system`. For example, the `tog-pegasus.service` configuration unit would be `/usr/lib/systemd/tog-pegasus-init.service`.
|
||||
For all system-specific cases, we will take advantage of systemd's http://www.freedesktop.org/software/systemd/man/systemd.service.html[service] functionality. Packagers will create a new service unit file for each service unit in their package that requires per-system configuration. This service unit will be named `+-init.service+` and installed to `+/usr/lib/systemd/system+`. For example, the `+tog-pegasus.service+` configuration unit would be `+/usr/lib/systemd/tog-pegasus-init.service+`.
|
||||
|
||||
The contents of this service unit will be as follows:
|
||||
|
||||
|
|
@ -59,9 +59,9 @@ RemainAfterExit=no
|
|||
ExecStart=/path/to/config/script
|
||||
....
|
||||
|
||||
The syntax for `ConditionPathExists=` uses the ! to indicate negation (the file is not present). The | is used to create an OR logical pairing (resulting in the lack of ANY of these files causing the configuration to be run). Those are called "triggering" conditions, for full explanation see http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConditionArchitecture=[systemd.unit(5)]. The `/path/to/config/script` can be any executable script or binary that will generate the initial configuration needed by this service. It *must* generate the files tested by `ConditionPathExists`. If the script is a single command, it can be run directly by this service unit. If it needs to run multiple commands, it is recommended to create a script file in the package's `/usr/libexec/` directory and execute that.
|
||||
The syntax for `+ConditionPathExists=+` uses the ! to indicate negation (the file is not present). The | is used to create an OR logical pairing (resulting in the lack of ANY of these files causing the configuration to be run). Those are called "triggering" conditions, for full explanation see http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConditionArchitecture=[systemd.unit(5)]. The `+/path/to/config/script+` can be any executable script or binary that will generate the initial configuration needed by this service. It *must* generate the files tested by `+ConditionPathExists+`. If the script is a single command, it can be run directly by this service unit. If it needs to run multiple commands, it is recommended to create a script file in the package's `+/usr/libexec/+` directory and execute that.
|
||||
|
||||
To use `tog-pegasus.service` as an example:
|
||||
To use `+tog-pegasus.service+` as an example:
|
||||
|
||||
....
|
||||
[Unit]
|
||||
|
|
@ -78,7 +78,7 @@ RemainAfterExit=no
|
|||
ExecStart=/usr/bin/sscg --package tog-pegasus --ca-file /etc/Pegasus/client.pem --cert-file /etc/Pegasus/server.pem --cert-key-file /etc/Pegasus/file.pem
|
||||
....
|
||||
|
||||
The `ExecStart` command may do anything, so long as it returns 0 on success. In this case, we are generating a self-signed certificate for the service to use.
|
||||
The `+ExecStart+` command may do anything, so long as it returns 0 on success. In this case, we are generating a self-signed certificate for the service to use.
|
||||
|
||||
Packagers will also need to update their primary service unit to require this one and run after it:
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ Requires=<service>-init.service
|
|||
After=<service>-init.service
|
||||
....
|
||||
|
||||
To continue the `tog-pegasus.service` example:
|
||||
To continue the `+tog-pegasus.service+` example:
|
||||
|
||||
....
|
||||
[Unit]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Fedora Java packaging is originally based on http://www.jpackage.org[JPackage Pr
|
|||
|
||||
Packages MUST follow the standard Fedora link:Packaging/NamingGuidelines[ package naming guidelines].
|
||||
|
||||
Java API documentation MUST be placed into a sub-package called `%{name}-javadoc`.
|
||||
Java API documentation MUST be placed into a sub-package called `+%{name}-javadoc+`.
|
||||
|
||||
== Release tags
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ Packages MUST follow the standard Fedora link:Packaging/NamingGuidelines#Package
|
|||
|
||||
Packages MUST follow the standard Fedora Packaging:Guidelines#No_inclusion_of_pre-built_binaries_or_libraries[ dependency bundling guidelines].
|
||||
|
||||
In particular `*.class` and `*.jar` files from upstream releases MUST NOT be used during build of Fedora packages and they MUST NOT be included in binary RPM.
|
||||
In particular `+*.class+` and `+*.jar+` files from upstream releases MUST NOT be used during build of Fedora packages and they MUST NOT be included in binary RPM.
|
||||
|
||||
== JAR file installation
|
||||
|
||||
|
|
@ -30,44 +30,44 @@ If a project offers the choice of packaging it as a single monolithic JAR or sev
|
|||
|
||||
=== Installation directory
|
||||
|
||||
* All architecture-independent JAR files MUST go into `%{_javadir}` or its subdirectory.
|
||||
* All architecture-independent JAR files MUST go into `+%{_javadir}+` or its subdirectory.
|
||||
|
||||
* For installation of architecture dependent JAR files, see link:#Packaging_JAR_files_that_use_JNI[Packaging JAR files that use JNI].
|
||||
|
||||
=== Filenames
|
||||
|
||||
* If the package provides a *single* JAR file installed filename SHOULD be `%{name}.jar`.
|
||||
* If the package provides *multiple* JAR files, they SHOULD be installed in a `%{name}` subdirectory
|
||||
* Versioned JAR files (`*-%{version}.jar`) MUST NOT be installed unless the package is a compatibility package
|
||||
* If the package provides a *single* JAR file installed filename SHOULD be `+%{name}.jar+`.
|
||||
* If the package provides *multiple* JAR files, they SHOULD be installed in a `+%{name}+` subdirectory
|
||||
* Versioned JAR files (`+*-%{version}.jar+`) MUST NOT be installed unless the package is a compatibility package
|
||||
* Packages MAY provide alternative filenames as long as they do not conflict with other packages
|
||||
|
||||
== BuildRequires and Requires
|
||||
|
||||
Java packages MUST BuildRequire their respective build system:
|
||||
|
||||
* `BuildRequires: maven-local` for packages built with Maven
|
||||
* `BuildRequires: ant` for packages built with ant
|
||||
* `BuildRequires: java-devel` for packages built with javac
|
||||
* `+BuildRequires: maven-local+` for packages built with Maven
|
||||
* `+BuildRequires: ant+` for packages built with ant
|
||||
* `+BuildRequires: java-devel+` for packages built with javac
|
||||
|
||||
Java binary packages or their dependencies MUST have Requires (generated by RPM or manual) on:
|
||||
|
||||
* `java-headless` or `java-headless >= 1:minimal_required_version`
|
||||
* `javapackages-filesystem`
|
||||
* `+java-headless+` or `+java-headless >= 1:minimal_required_version+`
|
||||
* `+javapackages-filesystem+`
|
||||
|
||||
If java-headless requirement is insufficient package MUST have Requires:
|
||||
|
||||
* `java` or `java >= 1:minimal_required_version`
|
||||
* `+java+` or `+java >= 1:minimal_required_version+`
|
||||
|
||||
== Javadoc installation
|
||||
|
||||
* javadoc documentation MAY be generated
|
||||
* If javadoc documentation is generated it MUST be installed into a directory of `%{_javadocdir}/%{name}` as part of javadoc subpackage
|
||||
* Directory or symlink `%{_javadocdir}/%{name}-%{version}` SHOULD NOT exist.
|
||||
* The javadoc subpackage MUST be declared `noarch` even if main package is architecture specific.
|
||||
* If javadoc documentation is generated it MUST be installed into a directory of `+%{_javadocdir}/%{name}+` as part of javadoc subpackage
|
||||
* Directory or symlink `+%{_javadocdir}/%{name}-%{version}+` SHOULD NOT exist.
|
||||
* The javadoc subpackage MUST be declared `+noarch+` even if main package is architecture specific.
|
||||
|
||||
== No class-path in MANIFEST.MF
|
||||
|
||||
* JAR files MUST NOT include `class-path` entry inside META-INF/MANIFEST.MF
|
||||
* JAR files MUST NOT include `+class-path+` entry inside META-INF/MANIFEST.MF
|
||||
|
||||
== Hardcoded paths
|
||||
|
||||
|
|
@ -75,15 +75,15 @@ Packages MUST NOT hardcode paths to JAR files they use. When package needs to re
|
|||
|
||||
== Maven pom.xml files
|
||||
|
||||
If upstream project is shipping Maven `pom.xml` files, these MUST be installed. Additionally package MUST install mapping between upstream artifact and filesystem by using the `%mvn_install` macro.
|
||||
If upstream project is shipping Maven `+pom.xml+` files, these MUST be installed. Additionally package MUST install mapping between upstream artifact and filesystem by using the `+%mvn_install+` macro.
|
||||
|
||||
If upstream project does not ship Maven `pom.xml` file, official http://mvnrepository.com/[maven repository] should be searched and if there are `pom.xml` files they SHOULD be installed.
|
||||
If upstream project does not ship Maven `+pom.xml+` file, official http://mvnrepository.com/[maven repository] should be searched and if there are `+pom.xml+` files they SHOULD be installed.
|
||||
|
||||
If modifications to Maven pom.xml files are needed `%pom_*` family of macros SHOULD be used
|
||||
If modifications to Maven pom.xml files are needed `+%pom_*+` family of macros SHOULD be used
|
||||
|
||||
== Wrapper Scripts
|
||||
|
||||
Applications wishing to provide a convenient method of execution SHOULD provide a wrapper script in `%{_bindir}`. Packages SHOULD use `%jpackage_script` to create these wrapper scripts.
|
||||
Applications wishing to provide a convenient method of execution SHOULD provide a wrapper script in `+%{_bindir}+`. Packages SHOULD use `+%jpackage_script+` to create these wrapper scripts.
|
||||
|
||||
== Compatibility packages
|
||||
|
||||
|
|
@ -98,12 +98,12 @@ In certain cases it might be necessary to create compatibility packages that pro
|
|||
|
||||
Java programs that wish to make calls into native libraries do so via the Java Native Interface (JNI). A Java package uses JNI if it contains a .so file. Note that this file can be embedded within JAR files themselves.
|
||||
|
||||
Note that GCJ packages contain `.so`s in `%{_libdir}/gcj/%{name}` but they are not JNI .sos.
|
||||
Note that GCJ packages contain `+.so+`s in `+%{_libdir}/gcj/%{name}+` but they are not JNI .sos.
|
||||
|
||||
=== Guideline
|
||||
|
||||
* JNI packages MUST follow guidelines of ordinary Java packages with exceptions listed here
|
||||
* JAR files using JNI or containing JNI shared objects themselves MUST be placed in `%{_jnidir}` and MAY be symlinked to `%{_libdir}/%{name}`.
|
||||
* JNI shared objects MUST be placed in `%{_libdir}/%{name}`
|
||||
* JAR files using JNI or containing JNI shared objects themselves MUST be placed in `+%{_jnidir}+` and MAY be symlinked to `+%{_libdir}/%{name}+`.
|
||||
* JNI shared objects MUST be placed in `+%{_libdir}/%{name}+`
|
||||
|
||||
Category:Java Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ The name of a JavaScript library package must start with _js-_ then the upstream
|
|||
|
||||
== BuildRequires
|
||||
|
||||
To ensure the presence of the necessary RPM macros, all packages that provide JavaScript in `%{_jsdir}` must have:
|
||||
To ensure the presence of the necessary RPM macros, all packages that provide JavaScript in `+%{_jsdir}+` must have:
|
||||
|
||||
....
|
||||
BuildRequires: web-assets-devel
|
||||
|
|
@ -32,13 +32,13 @@ BuildRequires: web-assets-devel
|
|||
|
||||
== Requires
|
||||
|
||||
To ensure the availability of the necessary directories, all packages that provide JavaScript in `%{_jsdir}` must have:
|
||||
To ensure the availability of the necessary directories, all packages that provide JavaScript in `+%{_jsdir}+` must have:
|
||||
|
||||
....
|
||||
Requires: web-assets-filesystem
|
||||
....
|
||||
|
||||
JavaScript packages *must not* have Requires on any HTTP daemon-specific configuration package, such as `web-assets-httpd`, since they could be used by any HTTP daemon.
|
||||
JavaScript packages *must not* have Requires on any HTTP daemon-specific configuration package, such as `+web-assets-httpd+`, since they could be used by any HTTP daemon.
|
||||
|
||||
== RPM Macros
|
||||
|
||||
|
|
@ -50,25 +50,25 @@ JavaScript packages *must not* have Requires on any HTTP daemon-specific configu
|
|||
|
||||
== Install Location
|
||||
|
||||
* If a JavaScript library can be executed locally or consists purely of JavaScript code, it must be installed into a subdirectory of `%{_jsdir}`.
|
||||
* If a JavaScript library can be executed locally or consists purely of JavaScript code, it must be installed into a subdirectory of `+%{_jsdir}+`.
|
||||
|
||||
* If a package contains JavaScript code, but is never useful outside the browser (e.g. if it is some sort of HTML user interface library) it may instead install to `%{_assetdir}`. For more information, see Packaging:Web_Assets[the Web Assets guidelines].
|
||||
* If a package contains JavaScript code, but is never useful outside the browser (e.g. if it is some sort of HTML user interface library) it may instead install to `+%{_assetdir}+`. For more information, see Packaging:Web_Assets[the Web Assets guidelines].
|
||||
|
||||
* If a package contains JavaScript code that is only used as part of a web application, and it is not useful to any other applications whatsoever, it may continue to ship that code along with the application. However, that does not absolve it from complying with the rest of these guidelines.
|
||||
|
||||
* If a package contains JavaScript code that is not useful on the web, but only in locally run software (e.g. Packaging:Node.js[Node.js] or GNOME shell extensions), it should use the appropriate directory for its runtime, not `%{_jsdir}`.
|
||||
* If a package contains JavaScript code that is not useful on the web, but only in locally run software (e.g. Packaging:Node.js[Node.js] or GNOME shell extensions), it should use the appropriate directory for its runtime, not `+%{_jsdir}+`.
|
||||
|
||||
== Server Location
|
||||
|
||||
JavaScript code is included as part of the general Packaging:Web_Assets[Web Assets framework]. Therefore, `%{_jsdir}` is available on Fedora-provided web servers by default at `/_sysassets/javascript/`.
|
||||
JavaScript code is included as part of the general Packaging:Web_Assets[Web Assets framework]. Therefore, `+%{_jsdir}+` is available on Fedora-provided web servers by default at `+/_sysassets/javascript/+`.
|
||||
|
||||
For instance, jQuery may be installed in `%{_jsdir}/jquery/jquery-min.js`, so web applications that need to use it can simply include this HTML tag:
|
||||
For instance, jQuery may be installed in `+%{_jsdir}/jquery/jquery-min.js+`, so web applications that need to use it can simply include this HTML tag:
|
||||
|
||||
....
|
||||
<script type="text/javascript" src="/_sysassets/javascript/jquery/jquery-min.js"></script>
|
||||
....
|
||||
|
||||
Regardless, web applications may want to make subdirectories of `%{_jsdir}` available under their own directory via aliases or symlinks for compatibility purposes or to eliminate needless deviation from upstream.
|
||||
Regardless, web applications may want to make subdirectories of `+%{_jsdir}+` available under their own directory via aliases or symlinks for compatibility purposes or to eliminate needless deviation from upstream.
|
||||
|
||||
== Compilation/Minification
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ JavaScript files intended for the web may include the source of other JavaScript
|
|||
|
||||
* The bundled library must be shipped as a separate package in Fedora, which also meets these guidelines.
|
||||
* The package that statically includes the library must use the code from that separate package. It *must not* bundle its own version of the library.
|
||||
* The package that statically includes the library must include virtual provides in the form `Provides: js-includes(``)` for all libraries it statically includes in this fashion. `web-assets-devel` provides a `%js_includes` macro that will automatically add the version present in the mock buildroot to the virtual provides. To use it, just add `%js_includes ` anywhere before `%prep` in your spec file.
|
||||
* The package that statically includes the library must include virtual provides in the form `+Provides: js-includes(+``+)+` for all libraries it statically includes in this fashion. `+web-assets-devel+` provides a `+%js_includes+` macro that will automatically add the version present in the mock buildroot to the virtual provides. To use it, just add `+%js_includes +` anywhere before `+%prep+` in your spec file.
|
||||
|
||||
Again, this is only useful for the web. Locally used JavaScript runtimes (like Node.js or GNOME Shell extensions) *must* have a mechanism for utilizing libraries, and they are not permitted to utilize this exception to the Packaging:No_Bundled_Libraries[standard bundled libraries policy].
|
||||
|
||||
|
|
@ -100,8 +100,8 @@ Sometimes there may exist a simple wrapper from a foreign language (like Ruby vi
|
|||
|
||||
Some Node.js modules include parts that can be used in the browser or by other server-side JavaScript engines. Such packages should be shipped as one SRPM that contains two packages:
|
||||
|
||||
* One `js-foo` package that contains the pure JavaScript portion, following these guidelines.
|
||||
* One `+js-foo+` package that contains the pure JavaScript portion, following these guidelines.
|
||||
|
||||
* One `nodejs-foo` package that contains the Node.js module portion, following the Packaging:Node.js[Node.js guidelines]. This may symlink to the necessary files or directories of the `js-foo` package.
|
||||
* One `+nodejs-foo+` package that contains the Node.js module portion, following the Packaging:Node.js[Node.js guidelines]. This may symlink to the necessary files or directories of the `+js-foo+` package.
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -2,40 +2,40 @@ The idea behind "langpacks" is to separate translations or language specific con
|
|||
|
||||
Subpackages that exist solely to contain additional language translations or content must be named in the form -langpack-, where is the name of the package that the langpacks belong to and is a valid language code from _/usr/share/xml/iso-codes/iso_639_3.xml_ or from _/usr/share/i18n/locales/_. Specifically, the langcode value used in the package name must agree with the langcode identifier used in the directory path by upstream for the translation or language files.
|
||||
|
||||
The langpack ecosystem does not need any procedural logic in the form of plugins. Instead it takes advantage of the weak and rich dependency features provided by RPM. The necessary dependencies are computed by the package manager (DNF or PackageKit) so it is essential to include the following `Supplements:` tag relation in the langpack package definition in the spec file:
|
||||
The langpack ecosystem does not need any procedural logic in the form of plugins. Instead it takes advantage of the weak and rich dependency features provided by RPM. The necessary dependencies are computed by the package manager (DNF or PackageKit) so it is essential to include the following `+Supplements:+` tag relation in the langpack package definition in the spec file:
|
||||
|
||||
`Supplements: (%{name} = %{version}-%{release} and langpacks-``)`
|
||||
`+Supplements: (%{name} = %{version}-%{release} and langpacks-+``+)+`
|
||||
|
||||
== Example
|
||||
|
||||
Suppose you have a package with following spec file:
|
||||
|
||||
`Name: php-horde-Horde-Perms` +
|
||||
`...` +
|
||||
`%files -f Horde_Perms.lang` +
|
||||
`/usr/share/pear-data/Horde_Perms/locale/` +
|
||||
`...`
|
||||
`+Name: php-horde-Horde-Perms+` +
|
||||
`+...+` +
|
||||
`+%files -f Horde_Perms.lang+` +
|
||||
`+/usr/share/pear-data/Horde_Perms/locale/+` +
|
||||
`+...+`
|
||||
|
||||
In order to create langpacks for each language (_/usr/share/pear-data/Horde_Perms/locale//LC_MESSAGES/Horde_Perms.mo_ translations), you would need to define a new subpackage for each package. The snippet below shows a macro for automating the definition of langpacks, along with the definition of langpacks for _bs_ and _cs_ languages. This would replace the lines shown above. Note that this macro definition is specific to the example package; you will need to modify it as appropriate for your package.
|
||||
|
||||
`Name: php-horde-Horde-Perms` +
|
||||
`...` +
|
||||
`+Name: php-horde-Horde-Perms+` +
|
||||
`+...+` +
|
||||
+
|
||||
`%define lang_subpkg() \` +
|
||||
`%package langpack-%{1}\` +
|
||||
`Summary: %{2} language data for %{name}\` +
|
||||
`BuildArch: noarch\` +
|
||||
`Requires: %{name} = %{version}-%{release}\` +
|
||||
`Supplements: (%{name} = %{version}-%{release} and langpacks-%{1})\` +
|
||||
`\` +
|
||||
`%description langpack-%{1}\` +
|
||||
`%{2} language data for %{name}.\` +
|
||||
`\` +
|
||||
`%files langpack-%{1}\` +
|
||||
`%{_datadir}/pear-data/Horde_Perms/locale/%{1}/` +
|
||||
` %lang_subpkg bs Bosnian` +
|
||||
`%lang_subpkg cs Czech` +
|
||||
`...` +
|
||||
`+%define lang_subpkg() \+` +
|
||||
`+%package langpack-%{1}\+` +
|
||||
`+Summary: %{2} language data for %{name}\+` +
|
||||
`+BuildArch: noarch\+` +
|
||||
`+Requires: %{name} = %{version}-%{release}\+` +
|
||||
`+Supplements: (%{name} = %{version}-%{release} and langpacks-%{1})\+` +
|
||||
`+\+` +
|
||||
`+%description langpack-%{1}\+` +
|
||||
`+%{2} language data for %{name}.\+` +
|
||||
`+\+` +
|
||||
`+%files langpack-%{1}\+` +
|
||||
`+%{_datadir}/pear-data/Horde_Perms/locale/%{1}/+` +
|
||||
`+ %lang_subpkg bs Bosnian+` +
|
||||
`+%lang_subpkg cs Czech+` +
|
||||
`+...+` +
|
||||
+
|
||||
`%files` +
|
||||
`...`
|
||||
`+%files+` +
|
||||
`+...+`
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ If code is multiple licensed, and at least one of the licenses is approved for F
|
|||
|
||||
== License Text
|
||||
|
||||
If the source package includes the text of the license(s) in its own file, then that file, containing the text of the license(s) for the package must be included in `%license`. If the source package does not include the text of the license(s), the packager should contact upstream and encourage them to correct this mistake.
|
||||
If the source package includes the text of the license(s) in its own file, then that file, containing the text of the license(s) for the package must be included in `+%license+`. If the source package does not include the text of the license(s), the packager should contact upstream and encourage them to correct this mistake.
|
||||
|
||||
In cases where the upstream has chosen a license that requires that a copy of the license text be distributed along with the binaries and/or source code, but does not provide a copy of the license text (in the source tree, or in some rare cases, anywhere), the packager should do their best to point out this confusion to upstream. This sometimes occurs when an upstream project's only reference to a license is in a README (where they simply say "licensed under the FOO license"), on their website, or when they simply do not check a copy of the license into their Source tree. Common licenses that require including their texts with all derivative works include ASL 2.0, EPL, BSD and MIT. Packagers should point out to upstream that by not including a proper full license text, they are making it difficult or impossible for anyone to comply with their desired license terms.
|
||||
|
||||
However, in situations where upstream is unresponsive, unable, or unwilling to provide proper full license text as part of the source code, and the indicated license requires that the full license text be included, Fedora Packagers must either:
|
||||
|
||||
* Include a copy of what they believe the license text is intended to be, as part of the Fedora package in `%license`, in order to remain in compliance. It is worth noting that this may place some additional risk on the packager, however, Fedora believes that this risk is minimized by the fact that if the upstream disagrees with what we have distributed as the full license text, they can easily remedy this by making full license text available in the source code. Packagers who choose to do this should ensure that they have exhausted all attempts to work with upstream to include the license text as part of the source code, or at least, to confirm the full license text explicitly with the upstream, as this minimizes the risk on the packager. Packagers should also take copies of license texts from reliable and canonical sources (such as the Fedora Software Licenses page, the FSF licenses page, or the OSI license list), whenever possible.
|
||||
* Include a copy of what they believe the license text is intended to be, as part of the Fedora package in `+%license+`, in order to remain in compliance. It is worth noting that this may place some additional risk on the packager, however, Fedora believes that this risk is minimized by the fact that if the upstream disagrees with what we have distributed as the full license text, they can easily remedy this by making full license text available in the source code. Packagers who choose to do this should ensure that they have exhausted all attempts to work with upstream to include the license text as part of the source code, or at least, to confirm the full license text explicitly with the upstream, as this minimizes the risk on the packager. Packagers should also take copies of license texts from reliable and canonical sources (such as the Fedora Software Licenses page, the FSF licenses page, or the OSI license list), whenever possible.
|
||||
|
||||
* Choose not to package that software for Fedora.
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ In cases where the licensing is unclear, it may be necessary to contact the copy
|
|||
|
||||
== License: field
|
||||
|
||||
Every Fedora package must contain a `License:` entry. Maintainers should be aware that the contents of the `License:` field are understood to not be legally binding (only the source code itself is), but maintainers must make every possible effort to be accurate when filling the `License:` field.
|
||||
Every Fedora package must contain a `+License:+` entry. Maintainers should be aware that the contents of the `+License:+` field are understood to not be legally binding (only the source code itself is), but maintainers must make every possible effort to be accurate when filling the `+License:+` field.
|
||||
|
||||
The License: field refers to the licenses of the contents of the *_binary_* rpm. When in doubt, ask.
|
||||
|
||||
|
|
@ -44,15 +44,15 @@ If a source package generates multiple binary packages, the License: field may d
|
|||
|
||||
=== Valid License Short Names
|
||||
|
||||
The `License:` field must be filled with the appropriate license Short License identifier(s) from the "Good License" tables on the link:Licensing[ Fedora Licensing] page. If your license does not appear in the tables, it needs to be sent to legal@lists.fedoraproject.org (note that this list is moderated, only members may directly post). If the license is approved, it will be added to the appropriate table.
|
||||
The `+License:+` field must be filled with the appropriate license Short License identifier(s) from the "Good License" tables on the link:Licensing[ Fedora Licensing] page. If your license does not appear in the tables, it needs to be sent to legal@lists.fedoraproject.org (note that this list is moderated, only members may directly post). If the license is approved, it will be added to the appropriate table.
|
||||
|
||||
=== "Distributable"
|
||||
|
||||
In the past, Fedora (and Red Hat Linux) packages have used "Distributable" in the `License:` field. In virtually all of these cases, this was not correct. Fedora no longer permits packages to use "Distributable" as a valid License. If your package contains content which is freely redistributable without restrictions, but does not contain any license other than explicit permission from the content owner/creator, then that package can use "Freely redistributable without restriction" as its `License:` identifier.
|
||||
In the past, Fedora (and Red Hat Linux) packages have used "Distributable" in the `+License:+` field. In virtually all of these cases, this was not correct. Fedora no longer permits packages to use "Distributable" as a valid License. If your package contains content which is freely redistributable without restrictions, but does not contain any license other than explicit permission from the content owner/creator, then that package can use "Freely redistributable without restriction" as its `+License:+` identifier.
|
||||
|
||||
=== Firmware
|
||||
|
||||
The `License:` field for any firmware that disallows modification should be set to: "Redistributable, no modification permitted".
|
||||
The `+License:+` field for any firmware that disallows modification should be set to: "Redistributable, no modification permitted".
|
||||
|
||||
=== Versioned licenses
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ Please note that there are already special Short License Identifiers for GPLv2+
|
|||
|
||||
=== GPL and LGPL
|
||||
|
||||
Since compatibility of code and library linking is especially complex with GPL and LGPL, Fedora packages can no longer simply use "GPL" or "LGPL" in the `License:` field. Please refer to the link:Licensing[ Fedora Licensing] page for the acceptable identifiers, and be careful to ensure that you select the correct one.
|
||||
Since compatibility of code and library linking is especially complex with GPL and LGPL, Fedora packages can no longer simply use "GPL" or "LGPL" in the `+License:+` field. Please refer to the link:Licensing[ Fedora Licensing] page for the acceptable identifiers, and be careful to ensure that you select the correct one.
|
||||
|
||||
=== Dual Licensing Scenarios
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ License: MPLv1.1 or GPLv2+
|
|||
|
||||
=== Multiple Licensing Scenarios
|
||||
|
||||
If your package contains files which are under multiple, distinct, and independent licenses, then the spec must reflect this by using "and" as a separator. Fedora maintainers are highly encouraged to avoid this scenario whenever reasonably possible, by dividing files into subpackages (subpackages can each have their own `License:` field).
|
||||
If your package contains files which are under multiple, distinct, and independent licenses, then the spec must reflect this by using "and" as a separator. Fedora maintainers are highly encouraged to avoid this scenario whenever reasonably possible, by dividing files into subpackages (subpackages can each have their own `+License:+` field).
|
||||
|
||||
Example:
|
||||
Package bar-utils contains some files under the Python License, some other files under the GNU Lesser General Public License v2 or later, and one file under the BSD License (no advertising). The package spec must have:
|
||||
|
|
@ -93,14 +93,14 @@ License: Python and LGPLv2+ and BSD
|
|||
In addition, the package must contain a comment explaining the multiple licensing breakdown. The actual implementation of this is left to the maintainer.
|
||||
Some suggested implementations include
|
||||
|
||||
* A comment right above the `License:` field:
|
||||
* A comment right above the `+License:+` field:
|
||||
|
||||
....
|
||||
# The entire source code is GPLv2+ except foolib/ which is BSD
|
||||
License: GPLv2+ and BSD
|
||||
....
|
||||
|
||||
* Including a file as `%license` which contains the licensing breakdown for the packaged files, then using:
|
||||
* Including a file as `+%license+` which contains the licensing breakdown for the packaged files, then using:
|
||||
|
||||
....
|
||||
# For a breakdown of the licensing, see PACKAGE-LICENSING
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ The files of MPI compilers MUST be installed in the following directories:
|
|||
[cols=",",options="header",]
|
||||
|===================================================================
|
||||
|File type |Placement
|
||||
|Binaries |`%{_libdir}/%{name}/bin`
|
||||
|Libraries |`%{_libdir}/%{name}/lib`
|
||||
|[[PackagingDrafts/Fortran |Fortran modules]] |`%{_fmoddir}/%{name}`
|
||||
|[[Packaging/Python |Python modules]] |`%{python2_sitearch}/%{name}`
|
||||
`%{python3_sitearch}/%{name}`
|
||||
|Config files |`%{_sysconfdir}/%{name}-%{_arch}`
|
||||
|Binaries |`+%{_libdir}/%{name}/bin+`
|
||||
|Libraries |`+%{_libdir}/%{name}/lib+`
|
||||
|[[PackagingDrafts/Fortran |Fortran modules]] |`+%{_fmoddir}/%{name}+`
|
||||
|[[Packaging/Python |Python modules]] |`+%{python2_sitearch}/%{name}+`
|
||||
`+%{python3_sitearch}/%{name}+`
|
||||
|Config files |`+%{_sysconfdir}/%{name}-%{_arch}+`
|
||||
|===================================================================
|
||||
|
||||
As include files and manual pages are bound to overlap between different MPI implementations, they MUST also placed outside normal directories. It is possible that some man pages or include files (either those of the MPI compiler itself or of some MPI software installed in the compiler's directory) are architecture specific (e.g. a definition on a 32-bit arch differs from that on a 64-bit arch), the directories that MUST be used are as follows:
|
||||
|
|
@ -27,17 +27,17 @@ As include files and manual pages are bound to overlap between different MPI imp
|
|||
[cols=",",options="header",]
|
||||
|================================================
|
||||
|File type |Placement
|
||||
|Man pages |`%{_mandir}/%{name}-%{_arch}`
|
||||
|Include files |`%{_includedir}/%{name}-%{_arch}`
|
||||
|Man pages |`+%{_mandir}/%{name}-%{_arch}+`
|
||||
|Include files |`+%{_includedir}/%{name}-%{_arch}+`
|
||||
|================================================
|
||||
|
||||
Architecture independent parts (except headers which go into `-devel`) MUST be placed in a `-common` subpackage that is `BuildArch: noarch`.
|
||||
Architecture independent parts (except headers which go into `+-devel+`) MUST be placed in a `+-common+` subpackage that is `+BuildArch: noarch+`.
|
||||
|
||||
The runtime of MPI compilers (mpirun, the libraries, the manuals etc) MUST be packaged into %\{name}, and the development headers and libraries into %\{name}-devel.
|
||||
|
||||
As the compiler is installed outside `PATH`, one needs to load the relevant variables before being able to use the compiler or run MPI programs. This is done using link:Packaging/EnvironmentModules[environment modules].
|
||||
As the compiler is installed outside `+PATH+`, one needs to load the relevant variables before being able to use the compiler or run MPI programs. This is done using link:Packaging/EnvironmentModules[environment modules].
|
||||
|
||||
The module file MUST be installed under `%{_sysconfdir}/modulefiles/mpi`. This allows as user with only one mpi implementation installed to load the module with:
|
||||
The module file MUST be installed under `+%{_sysconfdir}/modulefiles/mpi+`. This allows as user with only one mpi implementation installed to load the module with:
|
||||
|
||||
....
|
||||
module load mpi
|
||||
|
|
@ -51,31 +51,31 @@ conflict mpi
|
|||
|
||||
to prevent concurrent loading of multiple mpi modules.
|
||||
|
||||
The module file MUST prepend `$MPI_BIN` into the user's `PATH` and prepend `$MPI_LIB` to `LD_LIBRARY_PATH`.
|
||||
The module file MUST prepend `+$MPI_BIN+` into the user's `+PATH+` and prepend `+$MPI_LIB+` to `+LD_LIBRARY_PATH+`.
|
||||
The module file MUST also set some helper variables (primarily for use in spec files):
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|==========================================================================================
|
||||
|Variable |Value |Explanation
|
||||
|`MPI_BIN` |`%{_libdir}/%{name}/bin` |Binaries compiled against the MPI stack
|
||||
|`MPI_SYSCONFIG` |`%{_sysconfdir}/%{name}-%{_arch}` |MPI stack specific configuration files
|
||||
|`MPI_FORTRAN_MOD_DIR` |`%{_fmoddir}/%{name}` |MPI stack specific Fortran module directory
|
||||
|`MPI_INCLUDE` |`%{_includedir}/%{name}-%{_arch}` |MPI stack specific headers
|
||||
|`MPI_LIB` |`%{_libdir}/%{name}/lib` |Libraries compiled against the MPI stack
|
||||
|`MPI_MAN` |`%{_mandir}/%{name}-%{_arch}` |MPI stack specific man pages
|
||||
|`MPI_PYTHON2_SITEARCH` |`%{python2_sitearch}/%{name}` |MPI stack specific Python 2 modules
|
||||
|`MPI_PYTHON3_SITEARCH` |`%{python3_sitearch}/%{name}` |MPI stack specific Python 3 modules
|
||||
|`MPI_COMPILER` |`%{name}-%{_arch}` |Name of compiler package, for use in e.g. spec files
|
||||
|`MPI_SUFFIX` |`_%{name}` |The suffix used for programs compiled against the MPI stack
|
||||
|`+MPI_BIN+` |`+%{_libdir}/%{name}/bin+` |Binaries compiled against the MPI stack
|
||||
|`+MPI_SYSCONFIG+` |`+%{_sysconfdir}/%{name}-%{_arch}+` |MPI stack specific configuration files
|
||||
|`+MPI_FORTRAN_MOD_DIR+` |`+%{_fmoddir}/%{name}+` |MPI stack specific Fortran module directory
|
||||
|`+MPI_INCLUDE+` |`+%{_includedir}/%{name}-%{_arch}+` |MPI stack specific headers
|
||||
|`+MPI_LIB+` |`+%{_libdir}/%{name}/lib+` |Libraries compiled against the MPI stack
|
||||
|`+MPI_MAN+` |`+%{_mandir}/%{name}-%{_arch}+` |MPI stack specific man pages
|
||||
|`+MPI_PYTHON2_SITEARCH+` |`+%{python2_sitearch}/%{name}+` |MPI stack specific Python 2 modules
|
||||
|`+MPI_PYTHON3_SITEARCH+` |`+%{python3_sitearch}/%{name}+` |MPI stack specific Python 3 modules
|
||||
|`+MPI_COMPILER+` |`+%{name}-%{_arch}+` |Name of compiler package, for use in e.g. spec files
|
||||
|`+MPI_SUFFIX+` |`+_%{name}+` |The suffix used for programs compiled against the MPI stack
|
||||
|==========================================================================================
|
||||
|
||||
As these directories may be used by software using the MPI stack, the MPI runtime package MUST own all of them.
|
||||
|
||||
MUST: By default, NO files are placed in `/etc/ld.so.conf.d`. If the packager wishes to provide alternatives support, it MUST be placed in a subpackage along with the ld.so.conf.d file so that alternatives support does not need to be installed if not wished for.
|
||||
MUST: By default, NO files are placed in `+/etc/ld.so.conf.d+`. If the packager wishes to provide alternatives support, it MUST be placed in a subpackage along with the ld.so.conf.d file so that alternatives support does not need to be installed if not wished for.
|
||||
|
||||
MUST: If the maintainer wishes for the environment module to load automatically by use of a scriptlet in /etc/profile.d or by some other mechanism, this MUST be done in a subpackage.
|
||||
|
||||
MUST: The MPI compiler package MUST provide an RPM macro that makes loading and unloading the support easy in spec files, e.g. by placing the following in `/etc/rpm/macros.openmpi`
|
||||
MUST: The MPI compiler package MUST provide an RPM macro that makes loading and unloading the support easy in spec files, e.g. by placing the following in `+/etc/rpm/macros.openmpi+`
|
||||
|
||||
....
|
||||
%_openmpi_load \
|
||||
|
|
@ -87,21 +87,21 @@ MUST: The MPI compiler package MUST provide an RPM macro that makes loading and
|
|||
module unload mpi/openmpi-%{_arch};
|
||||
....
|
||||
|
||||
loading and unloading the compiler in spec files is as easy as `%{_openmpi_load}` and `%{_openmpi_unload}`.
|
||||
loading and unloading the compiler in spec files is as easy as `+%{_openmpi_load}+` and `+%{_openmpi_unload}+`.
|
||||
|
||||
Automatic setting of the module loading path in python interpreters is done using a `.pth` file placed in one of the directories normally searched for modules (`%{python2_sitearch}`, `%{python3_sitearch}`). Those `.pth` files should append the directory specified with $MPI_PYTHON2_SITEARCH or $MPI_PYTHON3_SITEARCH environment variable, depending on the interpreter version, to `sys.path`, and do nothing if those variables are unset. Module files MUST NOT set PYTHONPATH directly, since it cannot be set for both Python versions at the same time.
|
||||
Automatic setting of the module loading path in python interpreters is done using a `+.pth+` file placed in one of the directories normally searched for modules (`+%{python2_sitearch}+`, `+%{python3_sitearch}+`). Those `+.pth+` files should append the directory specified with $MPI_PYTHON2_SITEARCH or $MPI_PYTHON3_SITEARCH environment variable, depending on the interpreter version, to `+sys.path+`, and do nothing if those variables are unset. Module files MUST NOT set PYTHONPATH directly, since it cannot be set for both Python versions at the same time.
|
||||
|
||||
If the environment module sets compiler flags such as `CFLAGS` (thus overriding the ones exported in `%configure`, the RPM macro MUST make them use the Fedora optimization flags `%{optflags}` once again (as in the example above in which the openmpi-%\{_arch} module sets CFLAGS).
|
||||
If the environment module sets compiler flags such as `+CFLAGS+` (thus overriding the ones exported in `+%configure+`, the RPM macro MUST make them use the Fedora optimization flags `+%{optflags}+` once again (as in the example above in which the openmpi-%\{_arch} module sets CFLAGS).
|
||||
|
||||
== Packaging of MPI software
|
||||
|
||||
Software that supports MPI MUST be packaged also in serial mode [i.e. no MPI], if it is supported by upstream. (for instance: `foo`).
|
||||
Software that supports MPI MUST be packaged also in serial mode [i.e. no MPI], if it is supported by upstream. (for instance: `+foo+`).
|
||||
|
||||
If possible, the packager MUST package versions for each MPI compiler in Fedora (e.g. if something can only be built with mpich and mvapich2, then mvapich1 and openmpi packages do not need to be made).
|
||||
|
||||
MPI implementation specific files MUST be installed in the directories used by the used MPI compiler (`$MPI_BIN`, `$MPI_LIB` and so on).
|
||||
MPI implementation specific files MUST be installed in the directories used by the used MPI compiler (`+$MPI_BIN+`, `+$MPI_LIB+` and so on).
|
||||
|
||||
The binaries MUST be suffixed with `$MPI_SUFFIX` (e.g. _openmpi for Open MPI, _mpich for MPICH and _mvapich2 for MVAPICH2). This is for two reasons: the serial version of the program can still be run when an MPI module is loaded and the user is always aware of the version s/he is running. This does not need to hurt the use of shell scripts:
|
||||
The binaries MUST be suffixed with `+$MPI_SUFFIX+` (e.g. _openmpi for Open MPI, _mpich for MPICH and _mvapich2 for MVAPICH2). This is for two reasons: the serial version of the program can still be run when an MPI module is loaded and the user is always aware of the version s/he is running. This does not need to hurt the use of shell scripts:
|
||||
|
||||
....
|
||||
# Which MPI implementation do we use?
|
||||
|
|
@ -120,15 +120,15 @@ mpirun -np 4 bar${MPI_SUFFIX} -process
|
|||
bar -collect
|
||||
....
|
||||
|
||||
The MPI enabled bits MUST be placed in a subpackage with the suffix denoting the MPI compiler used (for instance: `foo-openmpi` for Open MPI [the traditional MPI compiler in Fedora] or `foo-mpich` for MPICH). For directory ownership and to guarantee the pickup of the correct MPI runtime, the MPI subpackages MUST require the correct MPI compiler's runtime package.
|
||||
The MPI enabled bits MUST be placed in a subpackage with the suffix denoting the MPI compiler used (for instance: `+foo-openmpi+` for Open MPI [the traditional MPI compiler in Fedora] or `+foo-mpich+` for MPICH). For directory ownership and to guarantee the pickup of the correct MPI runtime, the MPI subpackages MUST require the correct MPI compiler's runtime package.
|
||||
|
||||
Each MPI build of shared libraries SHOULD have a separate -libs subpackage for the libraries (e.g. foo-mpich-libs). As in the case of MPI compilers, library configuration (in `/etc/ld.so.conf.d`) MUST NOT be made.
|
||||
Each MPI build of shared libraries SHOULD have a separate -libs subpackage for the libraries (e.g. foo-mpich-libs). As in the case of MPI compilers, library configuration (in `+/etc/ld.so.conf.d+`) MUST NOT be made.
|
||||
|
||||
In case the headers are the same regardless of the compilation method and architecture (e.g. 32-bit serial, 64-bit Open MPI, MPICH), they MUST be split into a separate `-headers` subpackage (e.g. 'foo-headers'). Fortran modules are architecture specific and as such are placed in the (MPI implementation specific) `-devel` package (foo-devel for the serial version and foo-openmpi-devel for the Open MPI version).
|
||||
In case the headers are the same regardless of the compilation method and architecture (e.g. 32-bit serial, 64-bit Open MPI, MPICH), they MUST be split into a separate `+-headers+` subpackage (e.g. 'foo-headers'). Fortran modules are architecture specific and as such are placed in the (MPI implementation specific) `+-devel+` package (foo-devel for the serial version and foo-openmpi-devel for the Open MPI version).
|
||||
|
||||
Each MPI build MUST have a separate -devel subpackage (e.g. foo-mpich-devel) that includes the development libraries and `Requires: %{name}-headers` if such a package exists. The goal is to be able to install and develop using e.g. 'foo-mpich-devel' without needing to install e.g. openmpi or the serial version of the package.
|
||||
Each MPI build MUST have a separate -devel subpackage (e.g. foo-mpich-devel) that includes the development libraries and `+Requires: %{name}-headers+` if such a package exists. The goal is to be able to install and develop using e.g. 'foo-mpich-devel' without needing to install e.g. openmpi or the serial version of the package.
|
||||
|
||||
Files must be shared between packages as much as possible. Compiler independent parts, such as data files in `%{_datadir}/%{name}` and man files MUST be put into a `-common` subpackage that is required by all of the binary packages (the serial package and all of the MPI packages).
|
||||
Files must be shared between packages as much as possible. Compiler independent parts, such as data files in `+%{_datadir}/%{name}+` and man files MUST be put into a `+-common+` subpackage that is required by all of the binary packages (the serial package and all of the MPI packages).
|
||||
|
||||
=== A sample spec file
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
__TOC__
|
||||
|
||||
This document provides best practices for the usage of http://mesonbuild.com/[the Meson build system] in Fedora packages. Meson is a build system (similar to automake) which can generate code for other lower-level build systems. For example, it can generate code for https://ninja-build.org/[ninja]. When packaging software which builds using Meson it's important to use the `%meson` macros instead of `%ninja` or other lower-level build system macros directly. The backend used by Meson could change.
|
||||
This document provides best practices for the usage of http://mesonbuild.com/[the Meson build system] in Fedora packages. Meson is a build system (similar to automake) which can generate code for other lower-level build systems. For example, it can generate code for https://ninja-build.org/[ninja]. When packaging software which builds using Meson it's important to use the `+%meson+` macros instead of `+%ninja+` or other lower-level build system macros directly. The backend used by Meson could change.
|
||||
|
||||
== Build Dependencies
|
||||
|
||||
|
|
@ -14,22 +14,22 @@ BuildRequires: meson
|
|||
|
||||
You will generally make use of these in your specs:
|
||||
|
||||
`%meson`::
|
||||
Defines CFLAGS, LDFLAGS, etc. and calls %__meson with appropriate parameters (`--libdir=%{_libdir}` and such). You can pass `-Doption=value` to this macro in order to set options for the buildsystem.
|
||||
`%meson_build`::
|
||||
An alias for `%ninja_build -C %{_vpath_builddir}`
|
||||
`%meson_install`::
|
||||
An alias for `%ninja_install -C %{_vpath_builddir}`
|
||||
`%meson_test`::
|
||||
An alias for `%ninja_test -C %{_vpath_builddir}`
|
||||
`+%meson+`::
|
||||
Defines CFLAGS, LDFLAGS, etc. and calls %__meson with appropriate parameters (`+--libdir=%{_libdir}+` and such). You can pass `+-Doption=value+` to this macro in order to set options for the buildsystem.
|
||||
`+%meson_build+`::
|
||||
An alias for `+%ninja_build -C %{_vpath_builddir}+`
|
||||
`+%meson_install+`::
|
||||
An alias for `+%ninja_install -C %{_vpath_builddir}+`
|
||||
`+%meson_test+`::
|
||||
An alias for `+%ninja_test -C %{_vpath_builddir}+`
|
||||
|
||||
It is rarely necessary (but permissible) to use or alter these:
|
||||
|
||||
`%_vpath_srcdir`::
|
||||
Path (relative to the build directory) where the sources to be built are located (default: `.`)
|
||||
`%_vpath_builddir`::
|
||||
Path (relative to the build directory) where the The build directory (default: `%{_target_platform}`)
|
||||
`%__meson`::
|
||||
`+%_vpath_srcdir+`::
|
||||
Path (relative to the build directory) where the sources to be built are located (default: `+.+`)
|
||||
`+%_vpath_builddir+`::
|
||||
Path (relative to the build directory) where the The build directory (default: `+%{_target_platform}+`)
|
||||
`+%__meson+`::
|
||||
The path to the meson executable
|
||||
|
||||
== Example RPM spec file
|
||||
|
|
|
|||
|
|
@ -19,26 +19,26 @@ Cross compiled MinGW packages must follow Fedora policy, except where noted in t
|
|||
|
||||
== Package naming
|
||||
|
||||
MinGW packages require special naming to denote the appropriate CPU architecture the binaries have been built for. There should *never* be a package prefixed with `mingw-` output during a build. The `mingw-` prefix is exclusive for RPM spec file names and the source RPM file name. The CPU architecture specific packages are created by sections with `%files -n mingw32-foo` or `%files -n mingw64-foo`.
|
||||
MinGW packages require special naming to denote the appropriate CPU architecture the binaries have been built for. There should *never* be a package prefixed with `+mingw-+` output during a build. The `+mingw-+` prefix is exclusive for RPM spec file names and the source RPM file name. The CPU architecture specific packages are created by sections with `+%files -n mingw32-foo+` or `+%files -n mingw64-foo+`.
|
||||
|
||||
[cols=",",]
|
||||
|=======================================================
|
||||
|`mingw-` |Used for source package and RPM spec name
|
||||
|`mingw32-` |Used for packages which are built for Win32
|
||||
|`mingw64-` |Used for packages which are built for Win64
|
||||
|`+mingw-+` |Used for source package and RPM spec name
|
||||
|`+mingw32-+` |Used for packages which are built for Win32
|
||||
|`+mingw64-+` |Used for packages which are built for Win64
|
||||
|=======================================================
|
||||
|
||||
== Base packages
|
||||
|
||||
The base packages provide a root filesystem, base libraries, binutils (basic programs like 'strip', 'ld' etc), the compiler (gcc) and the Win32/Win64 API. Packages may need to depend on one or more of these. In particular, almost all packages should BuildRequire `mingw32-filesystem`, `mingw64-filesystem`, `mingw32-gcc` and `mingw64-gcc`. The correct Requires flags will get added automatically when the `%{?mingw_package_header}` macro is mentioned in the spec file (as will be described later on in these guidelines)
|
||||
The base packages provide a root filesystem, base libraries, binutils (basic programs like 'strip', 'ld' etc), the compiler (gcc) and the Win32/Win64 API. Packages may need to depend on one or more of these. In particular, almost all packages should BuildRequire `+mingw32-filesystem+`, `+mingw64-filesystem+`, `+mingw32-gcc+` and `+mingw64-gcc+`. The correct Requires flags will get added automatically when the `+%{?mingw_package_header}+` macro is mentioned in the spec file (as will be described later on in these guidelines)
|
||||
|
||||
[cols=",",]
|
||||
|=================================================================================================================================================================================================================================
|
||||
|`mingw32-filesystem` / `mingw64-filesystem` |Core filesystem directory layout, and RPM macros for spec files. Equivalent to 'filesystem' RPM
|
||||
|`mingw32-binutils` / `mingw64-binutils` |Cross-compiled binutils (utilities like 'strip', 'as', 'ld') which understand Windows executables and DLLs. Equivalent to 'binutils' RPM
|
||||
|`mingw32-gcc` / `mingw64-gcc` |GNU compiler collection. Compilers for C and C++ which cross-compile to a Windows target. Equivalent to gcc RPM
|
||||
|`mingw32-crt` / `mingw64-crt` |Base libraries for core MinGW runtime & development environment. Equivalent to 'glibc' RPM
|
||||
|`mingw32-headers` / `mingw64-headers` |Win32 and Win64 API. A free (public domain) reimplementation of the header files required to link to the Win32 and Win64 API. No direct equivalent in base Fedora - glibc-devel is closest
|
||||
|`+mingw32-filesystem+` / `+mingw64-filesystem+` |Core filesystem directory layout, and RPM macros for spec files. Equivalent to 'filesystem' RPM
|
||||
|`+mingw32-binutils+` / `+mingw64-binutils+` |Cross-compiled binutils (utilities like 'strip', 'as', 'ld') which understand Windows executables and DLLs. Equivalent to 'binutils' RPM
|
||||
|`+mingw32-gcc+` / `+mingw64-gcc+` |GNU compiler collection. Compilers for C and C++ which cross-compile to a Windows target. Equivalent to gcc RPM
|
||||
|`+mingw32-crt+` / `+mingw64-crt+` |Base libraries for core MinGW runtime & development environment. Equivalent to 'glibc' RPM
|
||||
|`+mingw32-headers+` / `+mingw64-headers+` |Win32 and Win64 API. A free (public domain) reimplementation of the header files required to link to the Win32 and Win64 API. No direct equivalent in base Fedora - glibc-devel is closest
|
||||
|=================================================================================================================================================================================================================================
|
||||
|
||||
== Build for multiple targets
|
||||
|
|
@ -52,17 +52,17 @@ When a package can only be built for either one of these targets this can be ind
|
|||
|
||||
[cols=",",]
|
||||
|===============================================================
|
||||
|`%global mingw_build_win32 0` |Don't build for the Win32 target
|
||||
|`%global mingw_build_win64 0` |Don't build for the Win64 target
|
||||
|`+%global mingw_build_win32 0+` |Don't build for the Win32 target
|
||||
|`+%global mingw_build_win64 0+` |Don't build for the Win64 target
|
||||
|===============================================================
|
||||
|
||||
== One source RPM, separate binary RPMs per-target
|
||||
|
||||
Each cross compiled MinGW package which builds binaries for a specific target should put the binaries for that target in a separate subpackage. So if a package `foo` builds binaries for the Win32 and Win64 targets, then the source RPM should provide two subpackages named `mingw32-foo` and `mingw64-foo`.
|
||||
Each cross compiled MinGW package which builds binaries for a specific target should put the binaries for that target in a separate subpackage. So if a package `+foo+` builds binaries for the Win32 and Win64 targets, then the source RPM should provide two subpackages named `+mingw32-foo+` and `+mingw64-foo+`.
|
||||
|
||||
This means that a spec file must contains %package and %files sections for all the targets.
|
||||
|
||||
If a package contains translations then all calls to the `%find_lang` must be replaced by `%mingw_find_lang`.
|
||||
If a package contains translations then all calls to the `+%find_lang+` must be replaced by `+%mingw_find_lang+`.
|
||||
This causes all translation filelists to be split in per-target filelists.
|
||||
For example: when a spec file contains something like this:
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ For example: when a spec file contains something like this:
|
|||
%mingw_find_lang foo
|
||||
....
|
||||
|
||||
then two files will get created named `mingw32-foo.lang` and `mingw64-foo.lang`.
|
||||
then two files will get created named `+mingw32-foo.lang+` and `+mingw64-foo.lang+`.
|
||||
These file lists can be included in the %files section for the targets:
|
||||
|
||||
....
|
||||
|
|
@ -83,71 +83,71 @@ These file lists can be included in the %files section for the targets:
|
|||
|
||||
== Filesystem layout
|
||||
|
||||
`[root]` +
|
||||
` |` +
|
||||
` +- etc` +
|
||||
` | |` +
|
||||
` | +- rpm` +
|
||||
` | |` +
|
||||
` | +- macros.mingw` +
|
||||
` | +- macros.mingw32` +
|
||||
` | +- macros.mingw64` +
|
||||
` |` +
|
||||
` +- usr` +
|
||||
` |` +
|
||||
` +- bin - Links to MinGW cross compiler toolchain` +
|
||||
` | |` +
|
||||
` | +- i686-w64-mingw32-cpp` +
|
||||
` | +- i686-w64-mingw32-gcc` +
|
||||
` | +- i686-w64-mingw32-g++` +
|
||||
` | +- x86_64-w64-mingw32-cpp` +
|
||||
` | +- x86_64-w64-mingw32-gcc` +
|
||||
` | +- x86_64-w64-mingw32-g++` +
|
||||
` | +- ... etc..` +
|
||||
` |` +
|
||||
` +- lib` +
|
||||
` | |` +
|
||||
` | +- rpm` +
|
||||
` | |` +
|
||||
` | +- mingw-find-debuginfo.sh - extract debug information from Win32 and Win64 binaries` +
|
||||
` | +- mingw-find-lang.sh - generates per-target file lists containing translations` +
|
||||
` | +- mingw-find-provides.sh - extra DLL names` +
|
||||
` | +- mingw-find-requires.sh - discover required DLL names` +
|
||||
` |` +
|
||||
` +- i686-w64-mingw32 - root of mingw toolchain and binaries for the Win32 target - see next diagram` +
|
||||
` +- x86_64-w64-mingw32 - root of mingw toolchain and binaries for the Win64 target - see next diagram`
|
||||
`+[root]+` +
|
||||
`+ |+` +
|
||||
`+ +- etc+` +
|
||||
`+ | |+` +
|
||||
`+ | +- rpm+` +
|
||||
`+ | |+` +
|
||||
`+ | +- macros.mingw+` +
|
||||
`+ | +- macros.mingw32+` +
|
||||
`+ | +- macros.mingw64+` +
|
||||
`+ |+` +
|
||||
`+ +- usr+` +
|
||||
`+ |+` +
|
||||
`+ +- bin - Links to MinGW cross compiler toolchain+` +
|
||||
`+ | |+` +
|
||||
`+ | +- i686-w64-mingw32-cpp+` +
|
||||
`+ | +- i686-w64-mingw32-gcc+` +
|
||||
`+ | +- i686-w64-mingw32-g+++` +
|
||||
`+ | +- x86_64-w64-mingw32-cpp+` +
|
||||
`+ | +- x86_64-w64-mingw32-gcc+` +
|
||||
`+ | +- x86_64-w64-mingw32-g+++` +
|
||||
`+ | +- ... etc..+` +
|
||||
`+ |+` +
|
||||
`+ +- lib+` +
|
||||
`+ | |+` +
|
||||
`+ | +- rpm+` +
|
||||
`+ | |+` +
|
||||
`+ | +- mingw-find-debuginfo.sh - extract debug information from Win32 and Win64 binaries+` +
|
||||
`+ | +- mingw-find-lang.sh - generates per-target file lists containing translations+` +
|
||||
`+ | +- mingw-find-provides.sh - extra DLL names+` +
|
||||
`+ | +- mingw-find-requires.sh - discover required DLL names+` +
|
||||
`+ |+` +
|
||||
`+ +- i686-w64-mingw32 - root of mingw toolchain and binaries for the Win32 target - see next diagram+` +
|
||||
`+ +- x86_64-w64-mingw32 - root of mingw toolchain and binaries for the Win64 target - see next diagram+`
|
||||
|
||||
`/usr/i686-w64-mingw32` +
|
||||
`/usr/x86_64-w64-mingw32` +
|
||||
` |` +
|
||||
` +- bin - Binutils toolchain binaries for the target` +
|
||||
` | |` +
|
||||
` | +- ar` +
|
||||
` | +- as` +
|
||||
` | +- dlltool` +
|
||||
` | +- ld` +
|
||||
` | +- ... etc ...` +
|
||||
` |` +
|
||||
` +- lib - Binutils toolchain support libraries / files for the target` +
|
||||
` |` +
|
||||
` +- sys-root - root for cross compiled MinGW binaries` +
|
||||
` |` +
|
||||
` +- mingw` +
|
||||
` |` +
|
||||
` +- bin - cross-compiled MinGW binaries & runtime DLL parts` +
|
||||
` +- etc - configuration files` +
|
||||
` +- include - include files for cross compiled MinGW libs` +
|
||||
` +- lib - cross-compiled static MinGW libraries & linktime DLL parts` +
|
||||
` | |` +
|
||||
` | +- pkgconfig - pkg-config definitions for libraries` +
|
||||
` |` +
|
||||
` +- share` +
|
||||
` |` +
|
||||
` +- man`
|
||||
`+/usr/i686-w64-mingw32+` +
|
||||
`+/usr/x86_64-w64-mingw32+` +
|
||||
`+ |+` +
|
||||
`+ +- bin - Binutils toolchain binaries for the target+` +
|
||||
`+ | |+` +
|
||||
`+ | +- ar+` +
|
||||
`+ | +- as+` +
|
||||
`+ | +- dlltool+` +
|
||||
`+ | +- ld+` +
|
||||
`+ | +- ... etc ...+` +
|
||||
`+ |+` +
|
||||
`+ +- lib - Binutils toolchain support libraries / files for the target+` +
|
||||
`+ |+` +
|
||||
`+ +- sys-root - root for cross compiled MinGW binaries+` +
|
||||
`+ |+` +
|
||||
`+ +- mingw+` +
|
||||
`+ |+` +
|
||||
`+ +- bin - cross-compiled MinGW binaries & runtime DLL parts+` +
|
||||
`+ +- etc - configuration files+` +
|
||||
`+ +- include - include files for cross compiled MinGW libs+` +
|
||||
`+ +- lib - cross-compiled static MinGW libraries & linktime DLL parts+` +
|
||||
`+ | |+` +
|
||||
`+ | +- pkgconfig - pkg-config definitions for libraries+` +
|
||||
`+ |+` +
|
||||
`+ +- share+` +
|
||||
`+ |+` +
|
||||
`+ +- man+`
|
||||
|
||||
== Filenames of the cross-compilers and binutils
|
||||
|
||||
The MinGW cross-compilers and binutils are Fedora binaries and are therefore placed in `%{_bindir}` (ie. `/usr/bin`) according to the FHS and Fedora guidelines.
|
||||
The MinGW cross-compilers and binutils are Fedora binaries and are therefore placed in `+%{_bindir}+` (ie. `+/usr/bin+`) according to the FHS and Fedora guidelines.
|
||||
|
||||
The MinGW cross-compilers and binutils which generate i686 binaries for Windows are named:
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ The MinGW cross-compilers and binutils which generate i686 binaries for Windows
|
|||
....
|
||||
|
||||
The same binaries are present in
|
||||
`%{_prefix}/i686-w64-mingw32/bin` without any prefix in the
|
||||
`+%{_prefix}/i686-w64-mingw32/bin+` without any prefix in the
|
||||
name, ie:
|
||||
|
||||
....
|
||||
|
|
@ -193,7 +193,7 @@ And the Win64 target is provided by the macro:
|
|||
|
||||
== Standard mingw RPM macros
|
||||
|
||||
The `mingw-filesystem` package provides a number of convenience macros for the cross compiled sysroot directories, and
|
||||
The `+mingw-filesystem+` package provides a number of convenience macros for the cross compiled sysroot directories, and
|
||||
toolchain. It is mandatory to use these macros in all MinGW cross compiled packages submitted to Fedora.
|
||||
|
||||
=== Toolchain macros
|
||||
|
|
@ -313,10 +313,10 @@ For the Win64 target:
|
|||
|
||||
== Compilation of binaries
|
||||
|
||||
In order to build binaries for multiple targets we have to call commands like `./configure` and `make` multiple times (once for each target).
|
||||
In order to build binaries for multiple targets we have to call commands like `+./configure+` and `+make+` multiple times (once for each target).
|
||||
If one has to write this all out in a spec file then it will lead to duplicate code.
|
||||
To reduce the amount of duplication, several RPM macros have been introduced to help with the compilation.
|
||||
These macros are `%mingw_configure`, `%mingw_cmake`, `%mingw_cmake_kde4`, `%mingw_qmake_qt4`, `%mingw_qmake_qt5` and `%mingw_make`
|
||||
These macros are `+%mingw_configure+`, `+%mingw_cmake+`, `+%mingw_cmake_kde4+`, `+%mingw_qmake_qt4+`, `+%mingw_qmake_qt5+` and `+%mingw_make+`
|
||||
|
||||
These macros use out of source compilation to build binaries for all the targets.
|
||||
Almost all packages support out of source compilation or require slight patching. The only known exceptions to date are zlib and openssl.
|
||||
|
|
@ -345,12 +345,12 @@ This can be rewritten to something like this:
|
|||
MINGW_BUILDDIR_SUFFIX=static %mingw_configure --enable-static
|
||||
....
|
||||
|
||||
Most packages used the command `make %{?_smp_mflags}` to build the package.
|
||||
In the MinGW cross compiler framework you have to use `%mingw_make %{?_smp_mflags}` to build the package for all configured targets.
|
||||
As with the `%mingw_configure` macro you can also use the MINGW_BUILDDIR_SUFFIX environment variable to indicate a custom suffix to the build directory used
|
||||
Most packages used the command `+make %{?_smp_mflags}+` to build the package.
|
||||
In the MinGW cross compiler framework you have to use `+%mingw_make %{?_smp_mflags}+` to build the package for all configured targets.
|
||||
As with the `+%mingw_configure+` macro you can also use the MINGW_BUILDDIR_SUFFIX environment variable to indicate a custom suffix to the build directory used
|
||||
|
||||
To install the package the command `make install DESTDIR=$RPM_BUILD_ROOT` was used in almost all cases.
|
||||
This can be rewritten to `%mingw_make install DESTDIR=$RPM_BUILD_ROOT` to install the package for all configured targets
|
||||
To install the package the command `+make install DESTDIR=$RPM_BUILD_ROOT+` was used in almost all cases.
|
||||
This can be rewritten to `+%mingw_make install DESTDIR=$RPM_BUILD_ROOT+` to install the package for all configured targets
|
||||
The environment variable MINGW_BUILDDIR_SUFFIX can also be used here
|
||||
|
||||
Some packages require some custom instructions before the files are ready to be packaged. Such code can remain as is. However, you may need to duplicate these instructions multiple times (for all configured targets).
|
||||
|
|
@ -363,7 +363,7 @@ If a package contains binaries which depend on a DLL provided by another package
|
|||
mingw32(foo.dll)
|
||||
....
|
||||
|
||||
where `foo.dll` is the name of the DLL. The name must be converted to lowercase because Windows binaries contain case
|
||||
where `+foo.dll+` is the name of the DLL. The name must be converted to lowercase because Windows binaries contain case
|
||||
insensitive dependencies. The form 'mingw32(foo.dll)' should be used for Win32 binaries and the form 'mingw64(foo.dll)' for Win64 binaries.
|
||||
|
||||
Correct dependency generation is done automatically. Packagers should start their spec files with this line:
|
||||
|
|
@ -372,22 +372,22 @@ Correct dependency generation is done automatically. Packagers should start thei
|
|||
%{?mingw_package_header}
|
||||
....
|
||||
|
||||
All binary packages should depend on `mingw32-filesystem` or `mingw64-filesystem` (depending on the files in the package). If the line mentioned above is used then it will be added automatically, so you don't have to add it yourself
|
||||
All binary packages should depend on `+mingw32-filesystem+` or `+mingw64-filesystem+` (depending on the files in the package). If the line mentioned above is used then it will be added automatically, so you don't have to add it yourself
|
||||
|
||||
All specfiles should BuildRequire at least one of these (depending on the targets for which you want to build):
|
||||
|
||||
`BuildRequires: mingw32-filesystem >= minimum-version` +
|
||||
`BuildRequires: mingw64-filesystem >= minimum-version`
|
||||
`+BuildRequires: mingw32-filesystem >= minimum-version+` +
|
||||
`+BuildRequires: mingw64-filesystem >= minimum-version+`
|
||||
|
||||
and any other BuildRequires that they need.
|
||||
|
||||
The `minimum-version` must be at least 95 or any later version which provides the functionality you need
|
||||
The `+minimum-version+` must be at least 95 or any later version which provides the functionality you need
|
||||
|
||||
== Build architecture
|
||||
|
||||
All packages should have:
|
||||
|
||||
`BuildArch: noarch`
|
||||
`+BuildArch: noarch+`
|
||||
|
||||
unless they contain Fedora native executables.
|
||||
|
||||
|
|
@ -395,22 +395,22 @@ unless they contain Fedora native executables.
|
|||
|
||||
All libraries must be built as DLLs.
|
||||
|
||||
Because of the peculiarity of Windows, DLLs are stored in the `%{mingw32_bindir}` directory, along with a control file in
|
||||
the `%{mingw32_libdir}` directory. For example, for a library called `foo` there would be:
|
||||
Because of the peculiarity of Windows, DLLs are stored in the `+%{mingw32_bindir}+` directory, along with a control file in
|
||||
the `+%{mingw32_libdir}+` directory. For example, for a library called `+foo+` there would be:
|
||||
|
||||
....
|
||||
%{mingw32_bindir}/foo.dll
|
||||
%{mingw32_libdir}/foo.dll.a
|
||||
....
|
||||
|
||||
The `foo.dll` file is the main library, `foo.dll.a` is a stub linked to applications so they can find the library at runtime. All of these files are required in those locations in order to link successfully. The `.dll` may contain a version number although not always (eg. `foo-0.dll`).
|
||||
The `+foo.dll+` file is the main library, `+foo.dll.a+` is a stub linked to applications so they can find the library at runtime. All of these files are required in those locations in order to link successfully. The `+.dll+` may contain a version number although not always (eg. `+foo-0.dll+`).
|
||||
|
||||
=== Do not use %\{mingw32_bindir}/* or %\{mingw32_libdir}/* in %files section
|
||||
|
||||
The `%files` section must list DLLs and import libraries separately. Packages must NOT use `%{mingw32_bindir}/*` or
|
||||
`%{mingw32_libdir}/*`
|
||||
The `+%files+` section must list DLLs and import libraries separately. Packages must NOT use `+%{mingw32_bindir}/*+` or
|
||||
`+%{mingw32_libdir}/*+`
|
||||
|
||||
The reason for this is that libtool is very fragile and will give up on building a DLL very easily. Therefore we force the name of the DLL to be listed explicitly in the `%files` section in order to catch this during RPM builds.
|
||||
The reason for this is that libtool is very fragile and will give up on building a DLL very easily. Therefore we force the name of the DLL to be listed explicitly in the `+%files+` section in order to catch this during RPM builds.
|
||||
|
||||
=== Stripping
|
||||
|
||||
|
|
@ -430,7 +430,7 @@ Most binaries contain debugging symbols when the package gets built. To split th
|
|||
%{?mingw_debug_package}
|
||||
....
|
||||
|
||||
The `%{?mingw_debug_package}` line must be placed after the `%description tag`. Otherwise spectool and other RPM tools may fail to function
|
||||
The `+%{?mingw_debug_package}+` line must be placed after the `+%description tag+`. Otherwise spectool and other RPM tools may fail to function
|
||||
|
||||
== Executables (EXEs)
|
||||
|
||||
|
|
@ -444,11 +444,11 @@ Executables which are required for proper functionality of the libraries must be
|
|||
There are various types of files which are simply duplicates of equivalent files found in Fedora native packages. These files should not be packaged in the MinGW package.
|
||||
The following files don't need to be packaged in the MinGW package when their native counterpart already contains them:
|
||||
|
||||
* Man pages (`%{mingw32_mandir}` / `%{mingw64_mandir}`)
|
||||
* Info files (`%{mingw32_infodir}` / `%{mingw64_infodir}`)
|
||||
* Generic documentation (`%{mingw32_docdir}` / `%{mingw64_docdir}`)
|
||||
* Autoconf files (`%{mingw32_datadir}/aclocal` / `%{mingw64_datadir}/aclocal`)
|
||||
* gtk-doc files (`%{mingw32_datadir}/gtk-doc` / `%{mingw64_datadir}/gtk-doc`)
|
||||
* Man pages (`+%{mingw32_mandir}+` / `+%{mingw64_mandir}+`)
|
||||
* Info files (`+%{mingw32_infodir}+` / `+%{mingw64_infodir}+`)
|
||||
* Generic documentation (`+%{mingw32_docdir}+` / `+%{mingw64_docdir}+`)
|
||||
* Autoconf files (`+%{mingw32_datadir}/aclocal+` / `+%{mingw64_datadir}/aclocal+`)
|
||||
* gtk-doc files (`+%{mingw32_datadir}/gtk-doc+` / `+%{mingw64_datadir}/gtk-doc+`)
|
||||
|
||||
== Example Specfile
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ In addition, because some architectures simply do not support mono, every mono p
|
|||
ExclusiveArch: %{mono_arches}
|
||||
....
|
||||
|
||||
The `%mono_arches` must be used instead of a list of architectures in order to facilitate changes to the architecture list.
|
||||
The `+%mono_arches+` must be used instead of a list of architectures in order to facilitate changes to the architecture list.
|
||||
|
||||
== gacutil in a spec file
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
|||
0123456789-._+
|
||||
....
|
||||
|
||||
But do check #Separators for additional restrictions on using the `-._+` characters.
|
||||
But do check #Separators for additional restrictions on using the `+-._++` characters.
|
||||
|
||||
=== General Naming
|
||||
|
||||
|
|
@ -93,8 +93,8 @@ For many reasons, it is sometimes advantageous to keep multiple versions of a pa
|
|||
|
||||
*Examples:*
|
||||
|
||||
* The python-sqlalchemy package occasionally has multiple versions in Fedora for backwards compatibility. The most current version of python-sqlalchemy is named `python-sqlalchemy` and an older supported version is `python-sqlalchemy0.5`. No delimiter is used in this situation.
|
||||
* The most current version of the v8 package is named `v8`. In order to package version "3.13", the package MUST be named `v8_3.13`.
|
||||
* The python-sqlalchemy package occasionally has multiple versions in Fedora for backwards compatibility. The most current version of python-sqlalchemy is named `+python-sqlalchemy+` and an older supported version is `+python-sqlalchemy0.5+`. No delimiter is used in this situation.
|
||||
* The most current version of the v8 package is named `+v8+`. In order to package version "3.13", the package MUST be named `+v8_3.13+`.
|
||||
|
||||
Please also note that strings such as "-latest" can often become misleading over time if the package (in *all* active Fedora releases) is not kept updated with the latest upstream version.
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ See: Packaging:Guidelines#Renaming.2FReplacing_Existing_Packages
|
|||
|
||||
== Documentation Subpackages
|
||||
|
||||
Large documentation files SHOULD go in a subpackage. This subpackage must be named with the format: `%{name}-doc` .
|
||||
Large documentation files SHOULD go in a subpackage. This subpackage must be named with the format: `+%{name}-doc+` .
|
||||
The definition of large is left up to the packager's best judgement, but is not restricted to size. Large can refer to either size or quantity of files.
|
||||
|
||||
== Font Packages
|
||||
|
|
@ -125,7 +125,7 @@ Packages containing fonts must be named *[foundryname-]projectname[-fontfamilyna
|
|||
|
||||
If a package is considered an "addon" package that enhances or adds functionality to an existing Fedora package without being useful on its own, its name SHOULD reflect this fact. +
|
||||
+
|
||||
The new package ("child") SHOULD prepend the "parent" package in its name, in the format: `%{parent}-%{child}`.
|
||||
The new package ("child") SHOULD prepend the "parent" package in its name, in the format: `+%{parent}-%{child}+`.
|
||||
|
||||
*Examples:*
|
||||
|
||||
|
|
@ -136,15 +136,15 @@ python3-twisted (the twisted module for python3, relies on python3)
|
|||
xmms-cdread (direct cd read functionality for xmms, relies on xmms)
|
||||
....
|
||||
|
||||
When the addon package is a language binding, note that the language itself is always the parent. Thus, a lua binding for the "randomdb" database would be `lua-randomdb`, not `randomdb-lua`. Also note that some packages may have grandfathered names using the opposite ordering.
|
||||
When the addon package is a language binding, note that the language itself is always the parent. Thus, a lua binding for the "randomdb" database would be `+lua-randomdb+`, not `+randomdb-lua+`. Also note that some packages may have grandfathered names using the opposite ordering.
|
||||
|
||||
There are some exceptions to this general addon package naming policy, and they are noted below. +
|
||||
|
||||
=== httpd, pam, and SDL
|
||||
|
||||
Packages that rely on Apache httpd, pam, or SDL as a parent use a slightly different naming scheme.
|
||||
pam and SDL addons use the format: `%{parent}_%{child}`, with an underscore "_" as a delimiter.
|
||||
Apache httpd addons use the format: `mod_%{child}`, with an underscore "_" as a delimiter.
|
||||
pam and SDL addons use the format: `+%{parent}_%{child}+`, with an underscore "_" as a delimiter.
|
||||
Apache httpd addons use the format: `+mod_%{child}+`, with an underscore "_" as a delimiter.
|
||||
This naming scheme is usually the same as used for the source tarball name. +
|
||||
*Examples:*
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ SDL_ttf (TrueType font rendering support for SDL, relies on SDL)
|
|||
|
||||
=== Eclipse plugins
|
||||
|
||||
Eclipse plugin packages MUST be named `eclipse-`. For example, a package of the AnyEdit plugin for Eclipse would be named `eclipse-anyedit`.
|
||||
Eclipse plugin packages MUST be named `+eclipse-+`. For example, a package of the AnyEdit plugin for Eclipse would be named `+eclipse-anyedit+`.
|
||||
|
||||
=== emacs components
|
||||
|
||||
|
|
@ -184,7 +184,7 @@ emacs-autex (autex component only for GNU Emacs)
|
|||
|
||||
=== erlang modules
|
||||
|
||||
Packages of erlang modules (thus they rely on erlang as a parent) have their own naming scheme. They SHOULD take into account the upstream name of the erlang module. This makes a package name format of `erlang-$NAME`. When in doubt, use the name of the module that you use when importing it into a script.
|
||||
Packages of erlang modules (thus they rely on erlang as a parent) have their own naming scheme. They SHOULD take into account the upstream name of the erlang module. This makes a package name format of `+erlang-$NAME+`. When in doubt, use the name of the module that you use when importing it into a script.
|
||||
|
||||
'''Example: '''
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ See the Packaging:GAP#Naming[GAP guidelines] for the proper naming of GAP addon
|
|||
|
||||
=== gnome shell extensions
|
||||
|
||||
Packages that extend gnome shell SHOULD begin with the prefix `gnome-shell-extension-`. In particular, this prefix SHOULD NOT be pluralized (ie: it SHOULD NOT be `gnome-shell-extensions`).
|
||||
Packages that extend gnome shell SHOULD begin with the prefix `+gnome-shell-extension-+`. In particular, this prefix SHOULD NOT be pluralized (ie: it SHOULD NOT be `+gnome-shell-extensions+`).
|
||||
|
||||
=== OCaml modules
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ This naming does not apply to applications written in OCaml, which can be given
|
|||
|
||||
=== LibreOffice extensions
|
||||
|
||||
Packages of LibreOffice extensions (thus they rely on LibreOffice as a parent) have their own naming scheme. They must take into account the upstream name of the LibreOffice extension. This makes a package name format of `libreoffice-$NAME`.
|
||||
Packages of LibreOffice extensions (thus they rely on LibreOffice as a parent) have their own naming scheme. They must take into account the upstream name of the LibreOffice extension. This makes a package name format of `+libreoffice-$NAME+`.
|
||||
|
||||
=== perl modules
|
||||
|
||||
|
|
@ -241,7 +241,7 @@ about changing "." to "-" applies.
|
|||
|
||||
=== Python source package naming
|
||||
|
||||
Source packages for Python modules SHOULD be named using the `python-` prefix.
|
||||
Source packages for Python modules SHOULD be named using the `+python-+` prefix.
|
||||
|
||||
'''Examples: '''
|
||||
|
||||
|
|
@ -253,20 +253,20 @@ python-PyQt4 (python module named PyQt4)
|
|||
However, it does occur that two separately maintained modules have the same
|
||||
name but are targeted against different versions of Python. In this case,
|
||||
source package for the software targeted at Python2 SHOULD take a
|
||||
`python2-` prefix, and the source package for the Python3 version
|
||||
SHOULD have a name beginning with `python3-`.
|
||||
`+python2-+` prefix, and the source package for the Python3 version
|
||||
SHOULD have a name beginning with `+python3-+`.
|
||||
|
||||
==== Python2 binary package naming
|
||||
|
||||
Python2 binary packages MUST be named using a `python2-` prefix.
|
||||
Python2 binary packages MUST be named using a `+python2-+` prefix.
|
||||
|
||||
==== Python3 binary package naming
|
||||
|
||||
Python3 binary packages MUST be named with a prefix of `python3-`.
|
||||
Python3 binary packages MUST be named with a prefix of `+python3-+`.
|
||||
|
||||
=== R modules
|
||||
|
||||
Packages of R modules (thus they rely on R as a parent) have their own naming scheme. They SHOULD take into account the upstream name of the R module. This makes a package name format of `R-$NAME`. When in doubt, use the name of the module that you type to import it in R.
|
||||
Packages of R modules (thus they rely on R as a parent) have their own naming scheme. They SHOULD take into account the upstream name of the R module. This makes a package name format of `+R-$NAME+`. When in doubt, use the name of the module that you type to import it in R.
|
||||
|
||||
'''Examples: '''
|
||||
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ The following macros are defined for you:
|
|||
|nodejs_sitearch |%\{_prefix}/lib/node_modules |Where native C++ Node.js modules are installed
|
||||
|nodejs_symlink_deps |%\{_prefix}/lib/rpm/nodejs-symlink-deps |See link:#Symlinking_Dependencies[#Symlinking Dependencies] below.
|
||||
|nodejs_fixdep |%\{_prefix}/lib/rpm/nodejs-fixdep |See link:#Correcting_Dependencies[#Correcting Dependencies]
|
||||
|nodejs_arches |%\{ix86} x86_64 %\{arm} |See #ExclusiveArch. This macro is provided by `redhat-rpm-config` in F19+ so it works with Koji properly.
|
||||
|nodejs_arches |%\{ix86} x86_64 %\{arm} |See #ExclusiveArch. This macro is provided by `+redhat-rpm-config+` in F19+ so it works with Koji properly.
|
||||
|nodejs_default_filter |%global __provides_exclude_from ^%\{nodejs_sitearch}/.*\\.node$ |Filters unwanted provides from native modules. See link:#Filtering_Unwanted_Provides[#Filtering Unwanted Provides] below.
|
||||
|=================================================================================================================================================================================================================
|
||||
|
||||
These macros are provided by the _nodejs-packaging_ package.
|
||||
|
||||
During `%install` or when listing `%files` you can use the `%nodejs_sitelib` or `%nodejs_sitearch` macro to specify where the installed modules are to be found. For instance:
|
||||
During `+%install+` or when listing `+%files+` you can use the `+%nodejs_sitelib+` or `+%nodejs_sitearch+` macro to specify where the installed modules are to be found. For instance:
|
||||
|
||||
....
|
||||
%files
|
||||
|
|
@ -43,11 +43,11 @@ During `%install` or when listing `%files` you can use the `%nodejs_sitelib` or
|
|||
%{nodejs_sitearch}/barmodule/
|
||||
....
|
||||
|
||||
Using this macro instead of hardcoding the directory in the specfile ensures your spec remains compatible with the installed Node.js version even if the directory structure changes radically (for instance, if `%nodejs_sitelib` moves into `%{_datadir}`).
|
||||
Using this macro instead of hardcoding the directory in the specfile ensures your spec remains compatible with the installed Node.js version even if the directory structure changes radically (for instance, if `+%nodejs_sitelib+` moves into `+%{_datadir}+`).
|
||||
|
||||
== Using tarballs from the npm registry
|
||||
|
||||
The canonical method for shipping most node modules is tarballs from the npm registry. The `Source0` for such modules should be of the form http://registry.npmjs.org/[`http://registry.npmjs.org/`]`/-/``-``.tgz`. For instance:
|
||||
The canonical method for shipping most node modules is tarballs from the npm registry. The `+Source0+` for such modules should be of the form http://registry.npmjs.org/[`+http://registry.npmjs.org/+`]`+/-/+``+-+``+.tgz+`. For instance:
|
||||
|
||||
....
|
||||
Source0: http://registry.npmjs.org/npm/-/npm-1.1.70.tgz
|
||||
|
|
@ -55,7 +55,7 @@ Source0: http://registry.npmjs.org/npm/-/npm-1.1.70.tgz
|
|||
|
||||
This method should be preferred to using checkouts from git or automatically generated tarballs from GitHub.
|
||||
|
||||
These tarballs store the contents of the module inside a `package` directory, so every package using these tarballs should use the following in `%prep`:
|
||||
These tarballs store the contents of the module inside a `+package+` directory, so every package using these tarballs should use the following in `+%prep+`:
|
||||
|
||||
....
|
||||
%prep
|
||||
|
|
@ -66,23 +66,23 @@ These tarballs store the contents of the module inside a `package` directory, so
|
|||
|
||||
The V8 JavaScript runtime used by Node.js uses a Just-in-Time (JIT) compiler that is specially tuned to individual architectures, and must be manually ported to any new architectures that wish to support it. Node.js packages must include an ExclusiveArch line that restricts them to only these architectures.
|
||||
|
||||
The `%{nodejs_arches}` macro is provided to make this easy, so pure JavaScript modules must use:
|
||||
The `+%{nodejs_arches}+` macro is provided to make this easy, so pure JavaScript modules must use:
|
||||
|
||||
....
|
||||
ExclusiveArch: %{nodejs_arches} noarch
|
||||
....
|
||||
|
||||
Native (binary) modules must omit `noarch` and list only `%{nodejs_arches}` or the list of architectures as appropriate.
|
||||
Native (binary) modules must omit `+noarch+` and list only `+%{nodejs_arches}+` or the list of architectures as appropriate.
|
||||
|
||||
== Installing Modules
|
||||
|
||||
Most node modules do not contain their own install mechanism. Instead they rely on `npm` to do it for them. `npm` *must not* be used to install modules in Fedora packages, since it usually requires network access, always tries to bundle libraries, and installs files in a manner inconsistent with the Filesystem Hierarchy Standard (FHS).
|
||||
Most node modules do not contain their own install mechanism. Instead they rely on `+npm+` to do it for them. `+npm+` *must not* be used to install modules in Fedora packages, since it usually requires network access, always tries to bundle libraries, and installs files in a manner inconsistent with the Filesystem Hierarchy Standard (FHS).
|
||||
|
||||
Instead, install files in their proper place manually using `install` or `cp`. Most files should be installed in `%{nodejs_sitelib}/` but documentation should be installed via `%doc`. In the event that the module ships arch independent content other than JavaScript code, that content should be installed in `%{_datadir}` and the module should be patched to cope with that.
|
||||
Instead, install files in their proper place manually using `+install+` or `+cp+`. Most files should be installed in `+%{nodejs_sitelib}/+` but documentation should be installed via `+%doc+`. In the event that the module ships arch independent content other than JavaScript code, that content should be installed in `+%{_datadir}+` and the module should be patched to cope with that.
|
||||
|
||||
=== Client-side JavaScript
|
||||
|
||||
Many node modules contain JavaScript that can be used both client-side and server-side and it is sometimes hard to identify code intended only for use in the browser. Since there are no current packaging guidelines for client-side JavaScript and bundling of such code is currently permitted in Fedora, it is currently permissible for client-side JavaScript to be bundled with nodejs modules in `%{nodejs_sitelib}`.
|
||||
Many node modules contain JavaScript that can be used both client-side and server-side and it is sometimes hard to identify code intended only for use in the browser. Since there are no current packaging guidelines for client-side JavaScript and bundling of such code is currently permitted in Fedora, it is currently permissible for client-side JavaScript to be bundled with nodejs modules in `+%{nodejs_sitelib}+`.
|
||||
|
||||
== Automatic Requires and Provides
|
||||
|
||||
|
|
@ -90,13 +90,13 @@ The _nodejs_ package includes an automatic Requires and Provides generator that
|
|||
|
||||
=== Provides
|
||||
|
||||
It also adds virtual provides in the form `npm(``)` to identify modules listed in the npm registry (the module is listed at npmjs.org) . If a module is not listed in the npm registry, it must not provide this. Modules that aren't listed in the npm registry should set `private` to `true` in their `package.json` file. If not, you must patch `package.json` to include that.
|
||||
It also adds virtual provides in the form `+npm(+``+)+` to identify modules listed in the npm registry (the module is listed at npmjs.org) . If a module is not listed in the npm registry, it must not provide this. Modules that aren't listed in the npm registry should set `+private+` to `+true+` in their `+package.json+` file. If not, you must patch `+package.json+` to include that.
|
||||
|
||||
=== Correcting Dependencies
|
||||
|
||||
Occasionally the dependencies listed in package.json are inaccurate. For instance, the module may work with a newer version of a dependency than the one explictly listed in the _package.json_ file. To correct this, use the `%nodejs_fixdep` RPM macro. This macro should be used in `%prep` and will patch _package.json_ to contain the correct dependency information.
|
||||
Occasionally the dependencies listed in package.json are inaccurate. For instance, the module may work with a newer version of a dependency than the one explictly listed in the _package.json_ file. To correct this, use the `+%nodejs_fixdep+` RPM macro. This macro should be used in `+%prep+` and will patch _package.json_ to contain the correct dependency information.
|
||||
|
||||
To convert any dependency to not list a specific version, just call `%nodejs_fixdep` with the npm module name of the dependency. This changes the version in _package.json_ to `*`. (Or adds one if it wasn't already listed.) For example:
|
||||
To convert any dependency to not list a specific version, just call `+%nodejs_fixdep+` with the npm module name of the dependency. This changes the version in _package.json_ to `+*+`. (Or adds one if it wasn't already listed.) For example:
|
||||
|
||||
....
|
||||
%prep
|
||||
|
|
@ -112,7 +112,7 @@ You can also specify a version:
|
|||
%nodejs_fixdep foomodule '>2.0'
|
||||
....
|
||||
|
||||
The second argument to `%nodejs_fixdep` must be a valid _package.json_ version specifier as explained in https://npmjs.org/doc/json.html[`\`man npm json\``].
|
||||
The second argument to `+%nodejs_fixdep+` must be a valid _package.json_ version specifier as explained in https://npmjs.org/doc/json.html[`+\+`man npm json\`++`].
|
||||
|
||||
You can also remove a dependency:
|
||||
|
||||
|
|
@ -124,23 +124,23 @@ You can also remove a dependency:
|
|||
|
||||
== Symlinking Dependencies
|
||||
|
||||
Node.js and npm require that dependencies explicitly be included or linked into a _node_modules_ directory inside the module directory. To make this easier, a `%nodejs_symlink_deps` macro is provided and will automatically create a _node_modules_ tree with symlinks for each dependency listed in _package.json_. This macro should be called in the `%install` section of every Node.js module package.
|
||||
Node.js and npm require that dependencies explicitly be included or linked into a _node_modules_ directory inside the module directory. To make this easier, a `+%nodejs_symlink_deps+` macro is provided and will automatically create a _node_modules_ tree with symlinks for each dependency listed in _package.json_. This macro should be called in the `+%install+` section of every Node.js module package.
|
||||
|
||||
== Removing bundled modules
|
||||
|
||||
Some node modules contain copies of other libraries in their source tree. You must remove these in `%prep`. Simply running `rm -rf node_modules` is sufficient for most modules.
|
||||
Some node modules contain copies of other libraries in their source tree. You must remove these in `+%prep+`. Simply running `+rm -rf node_modules+` is sufficient for most modules.
|
||||
|
||||
`%nodejs_symlink_deps` outputs a warning when a _node_modules_ directory already exists in the `%buildroot`, and will fail if it cannot create a symlink because a directory for it already exists.
|
||||
`+%nodejs_symlink_deps+` outputs a warning when a _node_modules_ directory already exists in the `+%buildroot+`, and will fail if it cannot create a symlink because a directory for it already exists.
|
||||
|
||||
== Building native modules with node-gyp
|
||||
|
||||
Most native modules use the `node-gyp` tool to build themselves, which configures and uses the `gyp` build framework to build addon modules that can interact with Node.js and the V8 JavaScript interpreter used by it.
|
||||
Most native modules use the `+node-gyp+` tool to build themselves, which configures and uses the `+gyp+` build framework to build addon modules that can interact with Node.js and the V8 JavaScript interpreter used by it.
|
||||
|
||||
The WAF build framework has been abandoned by upstream and is not supported in Fedora.
|
||||
|
||||
=== BuildRequires
|
||||
|
||||
To build a native module designed to be built with node-gyp, add `BuildRequires: node-gyp`, along with `BuildRequires: nodejs-devel` and _-devel_ packages for any shared libraries needed by the module.
|
||||
To build a native module designed to be built with node-gyp, add `+BuildRequires: node-gyp+`, along with `+BuildRequires: nodejs-devel+` and _-devel_ packages for any shared libraries needed by the module.
|
||||
|
||||
=== %build
|
||||
|
||||
|
|
@ -154,13 +154,13 @@ export CXXFLAGS="%{optflags}"
|
|||
node-gyp rebuild
|
||||
....
|
||||
|
||||
Note that some modules may specify something like `node-gyp configure && node-gyp build`. This is equivalent to `node-gyp rebuild`.
|
||||
Note that some modules may specify something like `+node-gyp configure && node-gyp build+`. This is equivalent to `+node-gyp rebuild+`.
|
||||
|
||||
=== %install
|
||||
|
||||
`node-gyp` creates a shared object file with the extension `.node` as part of its build process, which should be located in `build/Release`. This file may be used as the main entry point for the library, or is utilized by JavaScript wrapper code included with the module.
|
||||
`+node-gyp+` creates a shared object file with the extension `+.node+` as part of its build process, which should be located in `+build/Release+`. This file may be used as the main entry point for the library, or is utilized by JavaScript wrapper code included with the module.
|
||||
|
||||
If the shared object is used as the main entry point, it should be installed at `%{nodejs_sitelib}/``/index.node`. The `require()` function will automatically load this if there is no corresponding `index.js` or entry point defined in _package.json_ to override it. For example:
|
||||
If the shared object is used as the main entry point, it should be installed at `+%{nodejs_sitelib}/+``+/index.node+`. The `+require()+` function will automatically load this if there is no corresponding `+index.js+` or entry point defined in _package.json_ to override it. For example:
|
||||
|
||||
....
|
||||
%install
|
||||
|
|
@ -170,7 +170,7 @@ cp -p build/Release/index.node package.json %{buildroot}%{nodejs_sitelib}/foomod
|
|||
|
||||
If the shared object is called by JavaScript wrapper code, the situation is slightly more complicated.
|
||||
|
||||
If the module uses the npm https://npmjs.org/package/bindings[_bindings_] module, the shared object file should be installed in `%{nodejs_sitelib}/``/build/``.node`, which is at the top of _bindings_' search path and where `node-gyp` usually creates a symlink to wherever the real shared object file exists. For example:
|
||||
If the module uses the npm https://npmjs.org/package/bindings[_bindings_] module, the shared object file should be installed in `+%{nodejs_sitelib}/+``+/build/+``+.node+`, which is at the top of _bindings_' search path and where `+node-gyp+` usually creates a symlink to wherever the real shared object file exists. For example:
|
||||
|
||||
....
|
||||
%install
|
||||
|
|
@ -179,7 +179,7 @@ cp -p package.json wrapper.js %{buildroot}%{nodejs_sitelib}/foomodule/
|
|||
cp -p build/Release/foomodule.node %{buildroot}%{nodejs_sitelib}/foomodule/build/
|
||||
....
|
||||
|
||||
If the module hardcodes `build/Release/``.node`, the module should be patched to use `build/``.node` instead, and upstream should be advised that they should use the _bindings_ module, because their module could break when users use debug builds of node.
|
||||
If the module hardcodes `+build/Release/+``+.node+`, the module should be patched to use `+build/+``+.node+` instead, and upstream should be advised that they should use the _bindings_ module, because their module could break when users use debug builds of node.
|
||||
|
||||
If the module uses it's own Makefiles to locate the shared object file(s) to a specific location, then those files should installed in that location.
|
||||
|
||||
|
|
@ -187,15 +187,15 @@ If the module uses it's own Makefiles to locate the shared object file(s) to a s
|
|||
|
||||
Many native modules contain bundled copies of libraries already present in Fedora. You must build against the system version of these libraries. For more information, see Packaging:No_Bundled_Libraries[Packaging:No Bundled Libraries].
|
||||
|
||||
The Fedora version of `node-gyp` will handle the fact that shared versions of libuv, v8, and http_parser without modification to the module, since `node-gyp` always unconditionally configures these libraries. However, some modules may rely on other libraries bundled with node, such as openssl or c-ares. These may need to be patched to use the system headers for these libraries.
|
||||
The Fedora version of `+node-gyp+` will handle the fact that shared versions of libuv, v8, and http_parser without modification to the module, since `+node-gyp+` always unconditionally configures these libraries. However, some modules may rely on other libraries bundled with node, such as openssl or c-ares. These may need to be patched to use the system headers for these libraries.
|
||||
|
||||
=== Filtering Unwanted Provides
|
||||
|
||||
RPM automatically adds some unwanted virtual provides to the shared object files included with native modules. To remove them, add `%{?nodejs_default_filter}` to the top of the package's spec file. For more information, see Packaging:AutoProvidesAndRequiresFiltering.
|
||||
RPM automatically adds some unwanted virtual provides to the shared object files included with native modules. To remove them, add `+%{?nodejs_default_filter}+` to the top of the package's spec file. For more information, see Packaging:AutoProvidesAndRequiresFiltering.
|
||||
|
||||
== Build testing in %check
|
||||
|
||||
All Node.js module spec files must include a `%check` section that contains (at minimum) the line:
|
||||
All Node.js module spec files must include a `+%check+` section that contains (at minimum) the line:
|
||||
|
||||
....
|
||||
%{__nodejs} -e 'require("./")'
|
||||
|
|
@ -205,18 +205,18 @@ This test ensures that the module is actually loadable, which will help avoid si
|
|||
|
||||
Any other tests made available by upstream should also be run wherever possible.
|
||||
|
||||
For convienence, %nodejs_symlink_deps also accepts a `--check` argument, which will make it operate in the current working directory instead of the buildroot. You can use this in the `%check` section to make dependencies available for running tests. When this argument is used, development dependencies as listed in the "devDependencies" key in _package.json_ are also linked.
|
||||
For convienence, %nodejs_symlink_deps also accepts a `+--check+` argument, which will make it operate in the current working directory instead of the buildroot. You can use this in the `+%check+` section to make dependencies available for running tests. When this argument is used, development dependencies as listed in the "devDependencies" key in _package.json_ are also linked.
|
||||
|
||||
== Handling Multiple Version Scenarios
|
||||
|
||||
Occasionally, there may be an update to a Node.js module that involves backwards-incompatible changes. In such situations, it may be necessary to ship a compatibility package with the older version to allow time for dependencies to migrate to the new version. The Requires generator and `%nodejs_symlink_deps` contain logic that handles such situations transparently for packages that depend on these modules. No special action is required for other modules that depend on multiply-versioned modules that already exist.
|
||||
Occasionally, there may be an update to a Node.js module that involves backwards-incompatible changes. In such situations, it may be necessary to ship a compatibility package with the older version to allow time for dependencies to migrate to the new version. The Requires generator and `+%nodejs_symlink_deps+` contain logic that handles such situations transparently for packages that depend on these modules. No special action is required for other modules that depend on multiply-versioned modules that already exist.
|
||||
|
||||
However, the actual multiply-versioned packages require special attention in order for this to work. To implement this, first contact the https://admin.fedoraproject.org/mailman/listinfo/nodejs[Node.js SIG mailing list], explain the situation, and include the npm module name of the affected package. The `nodejs-packaging` maintainers will then add it to the `/usr/share/node/multiver_modules` file so the package is treated specially by `%nodejs_symlink_deps`.
|
||||
However, the actual multiply-versioned packages require special attention in order for this to work. To implement this, first contact the https://admin.fedoraproject.org/mailman/listinfo/nodejs[Node.js SIG mailing list], explain the situation, and include the npm module name of the affected package. The `+nodejs-packaging+` maintainers will then add it to the `+/usr/share/node/multiver_modules+` file so the package is treated specially by `+%nodejs_symlink_deps+`.
|
||||
|
||||
Then, in both the original package and the compatibility package, change the `%install` section to install the module into a versioned directory in `%{nodejs_sitelib}` of the form `@`. For instance, the 2.x `uglify-js` module should install into `uglify-js@2`.
|
||||
Then, in both the original package and the compatibility package, change the `+%install+` section to install the module into a versioned directory in `+%{nodejs_sitelib}+` of the form `+@+`. For instance, the 2.x `+uglify-js+` module should install into `+uglify-js@2+`.
|
||||
|
||||
One of the packages must additionally provide a symlink from the usual location to the versioned location described above. For instance, `%{nodejs_sitelib}/uglify-js` would point to `%{nodejs_sitelib}/uglify-js@2` in the previous example. Typically the newest package should provide this symlink, but it might be prudent for the older version to provide it instead when introducing such a package into an existing Fedora release, so as not to break dependent packages. The symlink can then be migrated to the newest version in the next Fedora release.
|
||||
One of the packages must additionally provide a symlink from the usual location to the versioned location described above. For instance, `+%{nodejs_sitelib}/uglify-js+` would point to `+%{nodejs_sitelib}/uglify-js@2+` in the previous example. Typically the newest package should provide this symlink, but it might be prudent for the older version to provide it instead when introducing such a package into an existing Fedora release, so as not to break dependent packages. The symlink can then be migrated to the newest version in the next Fedora release.
|
||||
|
||||
Finally, any packages that depend on a version that *does not* provide the aforementioned symlink from the base name to the versioned directory must be rebuilt in order to work properly. To obtain a list of potentially affected packages, run `reqoquery --whatrequires 'npm(module_name)'` or `npm view module_name dependencies`. Please coordinate with the Node.js SIG if any rebuilds are necessary.
|
||||
Finally, any packages that depend on a version that *does not* provide the aforementioned symlink from the base name to the versioned directory must be rebuilt in order to work properly. To obtain a list of potentially affected packages, run `+reqoquery --whatrequires 'npm(module_name)'+` or `+npm view module_name dependencies+`. Please coordinate with the Node.js SIG if any rebuilds are necessary.
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ The following macros are defined in /etc/rpm/macros.octave in the octave 3.4.0 (
|
|||
|
||||
=== Naming of Octave packages
|
||||
|
||||
Packages of Octave packages have their own naming scheme. They should take into account the upstream name of the package. This makes a package name format of `octave-$NAME`. When in doubt, use the name of the module that you type to import it in octave.
|
||||
Packages of Octave packages have their own naming scheme. They should take into account the upstream name of the package. This makes a package name format of `+octave-$NAME+`. When in doubt, use the name of the module that you type to import it in octave.
|
||||
|
||||
'''Examples: '''
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ Actuarial functions for Casualty and Property lines.
|
|||
|
||||
=== Summary of differences between arch-specific and noarch octave packages
|
||||
|
||||
* Noarch packages set `BuildArch: noarch`
|
||||
* Noarch packages set `+BuildArch: noarch+`
|
||||
* Don't require a specific api version
|
||||
* Noarch packages don't install anything into %\{octpkglibdir}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,25 +4,25 @@ Each Ruby package *must* indicate the Ruby ABI version it depends on with a line
|
|||
Requires: ruby(abi) = 1.8
|
||||
....
|
||||
|
||||
Ruby packages *must* require ruby at build time with a `BuildRequires: ruby`, and *may* indicate the minimal ruby version they need for building.
|
||||
Ruby packages *must* require ruby at build time with a `+BuildRequires: ruby+`, and *may* indicate the minimal ruby version they need for building.
|
||||
|
||||
== Naming Guidelines
|
||||
|
||||
These naming guidelines only apply to ruby packages whose main purpose is providing a Ruby library; packages that mainly provide user-level tools that happen to be written in Ruby do not need to follow these naming guidelines, and should follow the general link:Packaging/NamingGuidelines[ NamingGuidelines] instead.
|
||||
|
||||
The name of a ruby extension/library package *must* be of the form `ruby-UPSTREAM`. If the upstream name `UPSTREAM` contains `ruby`, that *should* be dropped from the name. For example, the SQLite database driver for ruby is called `sqlite3-ruby`. The corresponding Fedora package should be called `ruby-sqlite3`, and not `ruby-sqlite3-ruby`.
|
||||
The name of a ruby extension/library package *must* be of the form `+ruby-UPSTREAM+`. If the upstream name `+UPSTREAM+` contains `+ruby+`, that *should* be dropped from the name. For example, the SQLite database driver for ruby is called `+sqlite3-ruby+`. The corresponding Fedora package should be called `+ruby-sqlite3+`, and not `+ruby-sqlite3-ruby+`.
|
||||
|
||||
A ruby extension/library package *must* indicate what it provides with a `Provides: ruby(LIBRARY) = VERSION` declaration in the spec file. The string `LIBRARY` *should* be the same as what is used in the `require` statement in a Ruby script that uses the library. The `VERSION` *should* be the upstream version of the library, as long as upstream follows a sane versioning scheme. For example, a Ruby script using the SQLite database driver will include it with `require 'sqlite3'`. The specfile for the corresponding Fedora package must contain a line `Provides: ruby(sqlite3) = 1.1.0`, assuming the package contains version 1.1.0 of the library.
|
||||
A ruby extension/library package *must* indicate what it provides with a `+Provides: ruby(LIBRARY) = VERSION+` declaration in the spec file. The string `+LIBRARY+` *should* be the same as what is used in the `+require+` statement in a Ruby script that uses the library. The `+VERSION+` *should* be the upstream version of the library, as long as upstream follows a sane versioning scheme. For example, a Ruby script using the SQLite database driver will include it with `+require 'sqlite3'+`. The specfile for the corresponding Fedora package must contain a line `+Provides: ruby(sqlite3) = 1.1.0+`, assuming the package contains version 1.1.0 of the library.
|
||||
|
||||
== Build Architecture and File Placement
|
||||
|
||||
The following only affects the files that the package installs into `%{_libdir}/ruby`, i.e., Ruby library files. All other files in a Ruby package must adhere to the general Fedora Extras packaging conventions.
|
||||
The following only affects the files that the package installs into `+%{_libdir}/ruby+`, i.e., Ruby library files. All other files in a Ruby package must adhere to the general Fedora Extras packaging conventions.
|
||||
|
||||
=== Pure Ruby packages
|
||||
|
||||
Pure Ruby packages *must* be built as noarch packages.
|
||||
|
||||
The Ruby library files in a pure Ruby package *must* be placed into `Config::CONFIG["sitelibdir"]`. The specfile *must* get that path using
|
||||
The Ruby library files in a pure Ruby package *must* be placed into `+Config::CONFIG["sitelibdir"]+`. The specfile *must* get that path using
|
||||
|
||||
....
|
||||
%{!?ruby_sitelib: %global ruby_sitelib %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"] ')}
|
||||
|
|
@ -32,19 +32,19 @@ The Ruby library files in a pure Ruby package *must* be placed into `Config::CON
|
|||
|
||||
For packages with binary content, e.g., database drivers or any other Ruby bindings to C libraries, the package *must* be architecture specific.
|
||||
|
||||
The binary files in a Ruby package with binary content *must* be placed into `Config::CONFIG["sitearchdir"]`. The Ruby files in such a package *should* be placed into that directory, too. The specfile *must* get that path using
|
||||
The binary files in a Ruby package with binary content *must* be placed into `+Config::CONFIG["sitearchdir"]+`. The Ruby files in such a package *should* be placed into that directory, too. The specfile *must* get that path using
|
||||
|
||||
....
|
||||
%{!?ruby_sitearch: %global ruby_sitearch %(ruby -rrbconfig -e 'puts Config::CONFIG["sitearchdir"] ')}
|
||||
....
|
||||
|
||||
For packages which create C shared libraries using `extconf.rb`
|
||||
For packages which create C shared libraries using `+extconf.rb+`
|
||||
|
||||
....
|
||||
export CONFIGURE_ARGS="--with-cflags='%{optflags}'"
|
||||
....
|
||||
|
||||
*should* be used to pass `CFLAGS` to `Makefile` correctly.
|
||||
*should* be used to pass `+CFLAGS+` to `+Makefile+` correctly.
|
||||
This also applies to Ruby Gems.
|
||||
|
||||
== Ruby Gems
|
||||
|
|
@ -53,12 +53,12 @@ http://www.rubygems.org/[Ruby Gems] are Ruby's own packaging format. Gems contai
|
|||
|
||||
Both RPM's and Gems use similar terminology --- there's specfiles, package names, dependencies etc. for both. To keep confusion to a minimum, whenever the term from the Gem world is meant, it is explicitly called the 'Gem specification'. An unqualified 'package' in the following always means an RPM.
|
||||
|
||||
* Packages that contain Ruby Gems *must* be called `rubygem-%{gemname}` where `gemname` is the name from the Gem's specification.
|
||||
* The `Source` of the package *must* be the full URL to the released Gem archive; the version of the package *must* be the Gem's version
|
||||
* The package *must* have a `Requires` and a `BuildRequires` on `rubygems`
|
||||
* The package *must* provide `rubygem(%{gemname})` where `gemname` is the name from the Gem's specification. For every dependency on a Gem named `gemdep`, the package must contain a `Requires` on `rubygem(%{gemdep})` with the same version constraints as the Gem
|
||||
* The `%prep` and `%build` sections of the specfile *should* be empty.
|
||||
* The Gem *must* be installed into `%{gemdir}` defined as
|
||||
* Packages that contain Ruby Gems *must* be called `+rubygem-%{gemname}+` where `+gemname+` is the name from the Gem's specification.
|
||||
* The `+Source+` of the package *must* be the full URL to the released Gem archive; the version of the package *must* be the Gem's version
|
||||
* The package *must* have a `+Requires+` and a `+BuildRequires+` on `+rubygems+`
|
||||
* The package *must* provide `+rubygem(%{gemname})+` where `+gemname+` is the name from the Gem's specification. For every dependency on a Gem named `+gemdep+`, the package must contain a `+Requires+` on `+rubygem(%{gemdep})+` with the same version constraints as the Gem
|
||||
* The `+%prep+` and `+%build+` sections of the specfile *should* be empty.
|
||||
* The Gem *must* be installed into `+%{gemdir}+` defined as
|
||||
|
||||
....
|
||||
%global gemdir %(ruby -rubygems -e 'puts Gem::dir' 2>/dev/null)
|
||||
|
|
@ -78,19 +78,19 @@ gem install --local --install-dir %{buildroot}%{gemdir} --force %{SOURCE0}
|
|||
%{gemdir}/specifications/%{gemname}-%{version}.gemspec
|
||||
....
|
||||
|
||||
* Architecture-specific content *must not* be installed into `%{gemdir}`
|
||||
* If the Gem only contains pure Ruby code, it *must* be marked as `BuildArch: noarch`. If the Gem contains binary content (e.g., for a database driver), it *must* be marked as architecture specific, and all architecture specific content *must* be moved from the `%{gemdir}` to the [#ruby_sitearch `%{ruby_sitearch}` directory] during `%install`
|
||||
* Architecture-specific content *must not* be installed into `+%{gemdir}+`
|
||||
* If the Gem only contains pure Ruby code, it *must* be marked as `+BuildArch: noarch+`. If the Gem contains binary content (e.g., for a database driver), it *must* be marked as architecture specific, and all architecture specific content *must* be moved from the `+%{gemdir}+` to the [#ruby_sitearch `+%{ruby_sitearch}+` directory] during `+%install+`
|
||||
|
||||
=== Ruby Gem with extension libraries written in C
|
||||
|
||||
When a Ruby Gem contains extension libraries written in C,
|
||||
|
||||
* First, `%prep` stage *must* contain `%setup -q -c -T` to create the directory where C libraries are compiled.
|
||||
* First, `+%prep+` stage *must* contain `+%setup -q -c -T+` to create the directory where C libraries are compiled.
|
||||
* Then at %build stage the Ruby Gem *must* be installed under the directory created at %prep stage to get C libraries compiled under there.
|
||||
* When `gem install` is used to install Gem file, using `-V` option is *recommend* to check if `CFLAGS` is correctly honored.
|
||||
* Finally at `%install` stage the whole tree under the directory created at %prep stage *should* be *copied* (not moved) to under `%{buildroot}%{gemdir}`.
|
||||
** When all tree under the directory created at %prep stage is moved to under `%{buildroot}`, `find_debuginfo.sh` will complain that the corresponding source files are missing.
|
||||
* Installed C codes (usually under `%{geminstdir}/etc`) *may* be removed even if `gem contents %{gemname}` reports that installed C codes should be found there.
|
||||
* When `+gem install+` is used to install Gem file, using `+-V+` option is *recommend* to check if `+CFLAGS+` is correctly honored.
|
||||
* Finally at `+%install+` stage the whole tree under the directory created at %prep stage *should* be *copied* (not moved) to under `+%{buildroot}%{gemdir}+`.
|
||||
** When all tree under the directory created at %prep stage is moved to under `+%{buildroot}+`, `+find_debuginfo.sh+` will complain that the corresponding source files are missing.
|
||||
* Installed C codes (usually under `+%{geminstdir}/etc+`) *may* be removed even if `+gem contents %{gemname}+` reports that installed C codes should be found there.
|
||||
|
||||
==== Note
|
||||
|
||||
|
|
@ -106,14 +106,14 @@ must still apply.
|
|||
|
||||
=== Packaging for Gem and non-Gem use
|
||||
|
||||
If the same Ruby library is to be packaged for use as a Gem and as a straight Ruby library without Gem support, it *must* be packaged as a Gem first. To make it available to code that does not use Ruby Gems, a subpackage called `ruby-%{gemname}` *must* be created in the `rubygem-%{gemname}` package such that
|
||||
If the same Ruby library is to be packaged for use as a Gem and as a straight Ruby library without Gem support, it *must* be packaged as a Gem first. To make it available to code that does not use Ruby Gems, a subpackage called `+ruby-%{gemname}+` *must* be created in the `+rubygem-%{gemname}+` package such that
|
||||
|
||||
* The subpackage *must* require `rubygem(%gemname) = %version`
|
||||
* The subpackage *must* provide `ruby(LIBRARY) = %version` where LIBRARY is the same as in the [#ruby_naming general Ruby guideline] above.
|
||||
* All the toplevel library files of the Gem must be symlinked into `ruby_sitelib`.
|
||||
* The subpackage *must* require `+rubygem(%gemname) = %version+`
|
||||
* The subpackage *must* provide `+ruby(LIBRARY) = %version+` where LIBRARY is the same as in the [#ruby_naming general Ruby guideline] above.
|
||||
* All the toplevel library files of the Gem must be symlinked into `+ruby_sitelib+`.
|
||||
* The subpackage *must* own these symbolic links.
|
||||
|
||||
As an example, for `activesupport`, the `rubygem-activesupport` package would have a subpackge `ruby-activesupport`:
|
||||
As an example, for `+activesupport+`, the `+rubygem-activesupport+` package would have a subpackge `+ruby-activesupport+`:
|
||||
|
||||
....
|
||||
%package -n ruby-activesupport
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ While upstream used the same package and distribution format for PECL and PEAR,
|
|||
|
||||
3 channels are defined on installation of php-pear
|
||||
|
||||
* `pear.php.net` (alias pear) : the default channel for PHP Extension and Application Repository
|
||||
* `pecl.php.net` (alias pecl) : the default channel for PHP Extension Community Library
|
||||
* `__uri` : Pseudo-channel for static packages
|
||||
* `+pear.php.net+` (alias pear) : the default channel for PHP Extension and Application Repository
|
||||
* `+pecl.php.net+` (alias pecl) : the default channel for PHP Extension Community Library
|
||||
* `+__uri+` : Pseudo-channel for static packages
|
||||
|
||||
Other channels must be configured at RPM build time and at at RPM installation time.
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ We want to ensure that all packages have sensible defaults for whichever Product
|
|||
=== Per-Product Default Configuration
|
||||
|
||||
* For each Product requiring a unique default configuration, the packager MUST provide a copy of the default configuration file, modified as appropriate for the specific product.
|
||||
* The product-specific configuration file MUST be named based on the package's normal naming scheme, with the main part of the name being suffixed by a dash followed by the name of the product. For example, if the package normally uses `foo.conf`, then the Server version MUST be named `foo-server.conf`.
|
||||
* If the configuration will be symlinked in place, the product-specific configuration file MUST be located in an appropriate part of the /etc hierarchy. The divergent config file MUST be specified as `%config(noreplace)` in %files as per the usual /etc packaging guidelines.
|
||||
* The product-specific configuration file MUST be named based on the package's normal naming scheme, with the main part of the name being suffixed by a dash followed by the name of the product. For example, if the package normally uses `+foo.conf+`, then the Server version MUST be named `+foo-server.conf+`.
|
||||
* If the configuration will be symlinked in place, the product-specific configuration file MUST be located in an appropriate part of the /etc hierarchy. The divergent config file MUST be specified as `+%config(noreplace)+` in %files as per the usual /etc packaging guidelines.
|
||||
* If the configuration will be copied in place, the product-specific configuration file MUST be located in an appropriate part of the /usr/share hierarchy. The divergent config file MUST be specified as a normal file in the %files section.
|
||||
|
||||
=== Applying Configuration
|
||||
|
||||
In order to apply the configuration, the packager MUST implement a mechanism in the `%posttrans` section of the specfile that behaves as follows:
|
||||
In order to apply the configuration, the packager MUST implement a mechanism in the `+%posttrans+` section of the specfile that behaves as follows:
|
||||
|
||||
* It MUST first check whether the final config file already exists. If so, the script MUST make no changes.
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ if [ ! -e %{_sysconfdir}/foo/foo.conf ]; then
|
|||
fi
|
||||
....
|
||||
|
||||
* Then it MUST use the value of the Fedora `VARIANT_ID` to symlink or copy one of the divergent config files (or the default) to the final config file location. It will get this value by importing the contents of /etc/os-release as shell values. Known values of this field at the time of this writing are "atomichost", "cloud", "server" and "workstation". For more detail, see http://www.freedesktop.org/software/systemd/man/os-release.html#VARIANT_ID=[the os-release(5) man page].
|
||||
* Then it MUST use the value of the Fedora `+VARIANT_ID+` to symlink or copy one of the divergent config files (or the default) to the final config file location. It will get this value by importing the contents of /etc/os-release as shell values. Known values of this field at the time of this writing are "atomichost", "cloud", "server" and "workstation". For more detail, see http://www.freedesktop.org/software/systemd/man/os-release.html#VARIANT_ID=[the os-release(5) man page].
|
||||
|
||||
....
|
||||
. /etc/os-release || :
|
||||
|
|
|
|||
|
|
@ -31,23 +31,23 @@ In general, a noarch Perl package must own:
|
|||
|
||||
== Build Dependencies
|
||||
|
||||
As stated in Packaging:Guidelines#BuildRequires_2, a package must explicitly indicate its build dependencies (using `BuildRequires:`) outside of the minimal set required for RPM to build packages. This includes any dependency on Perl. While Perl may have been in the default buildroot at one time, this is not currently the case.
|
||||
As stated in Packaging:Guidelines#BuildRequires_2, a package must explicitly indicate its build dependencies (using `+BuildRequires:+`) outside of the minimal set required for RPM to build packages. This includes any dependency on Perl. While Perl may have been in the default buildroot at one time, this is not currently the case.
|
||||
|
||||
Below is a list of Perl-related build dependencies you may need.
|
||||
|
||||
* `perl-generators` – Automatically generates run-time Requires and Provides for installed Perl files. Whenever you install a Perl script or a Perl module, you must include a build dependency on this package.
|
||||
* `+perl-generators+` – Automatically generates run-time Requires and Provides for installed Perl files. Whenever you install a Perl script or a Perl module, you must include a build dependency on this package.
|
||||
|
||||
* `perl-interpreter` – The Perl interpreter must be listed as a build dependency if it is called in any way, either explicitly via `perl` or `%__perl`, or as part of your package's build system.
|
||||
* `+perl-interpreter+` – The Perl interpreter must be listed as a build dependency if it is called in any way, either explicitly via `+perl+` or `+%__perl+`, or as part of your package's build system.
|
||||
|
||||
* `perl-devel` - Provides Perl header files. If building architecture-specific code which links to `libperl.so` library (e.g. an XS Perl module), you must include `BuildRequires: perl-devel`.
|
||||
* `+perl-devel+` - Provides Perl header files. If building architecture-specific code which links to `+libperl.so+` library (e.g. an XS Perl module), you must include `+BuildRequires: perl-devel+`.
|
||||
|
||||
If a specific Perl module is required at build time, use `perl(`__`MODULE`__`)` syntax as documented above. This applies to so called _core_ modules as well, since they may move in and out of the base Perl package over time.
|
||||
If a specific Perl module is required at build time, use `+perl(+`__`+MODULE+`__`+)+` syntax as documented above. This applies to so called _core_ modules as well, since they may move in and out of the base Perl package over time.
|
||||
|
||||
If you need to limit your package to a specific Perl version, use `perl(:VERSION)` dependency with desired version constraint (e.g. `perl(:VERSION) >= 5.22`). Do not use a comparison against the version of the `perl` package because it includes an epoch number, which makes version comparisons tricky.
|
||||
If you need to limit your package to a specific Perl version, use `+perl(:VERSION)+` dependency with desired version constraint (e.g. `+perl(:VERSION) >= 5.22+`). Do not use a comparison against the version of the `+perl+` package because it includes an epoch number, which makes version comparisons tricky.
|
||||
|
||||
== Perl Requires and Provides
|
||||
|
||||
Perl packages use the virtual `perl(Foo)` naming to indicate a given Perl module. Packages should use this methodology, and not require the package name directly. For example, a package requiring the Perl module Readonly should not explicitly require `perl-Readonly`, but rather `perl(Readonly)`, which the `perl-Readonly` package provides.
|
||||
Perl packages use the virtual `+perl(Foo)+` naming to indicate a given Perl module. Packages should use this methodology, and not require the package name directly. For example, a package requiring the Perl module Readonly should not explicitly require `+perl-Readonly+`, but rather `+perl(Readonly)+`, which the `+perl-Readonly+` package provides.
|
||||
|
||||
It is recommended to include explicit dependencies for core modules, because they can move between sub-packages or disappear from core Perl.
|
||||
|
||||
|
|
@ -56,20 +56,20 @@ It is recommended to include explicit dependencies for core modules, because the
|
|||
All Perl modules must include the versioned MODULE_COMPAT Requires:
|
||||
|
||||
....
|
||||
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
|
||||
Requires: perl(:MODULE_COMPAT_%(eval "`+%{__perl} -V:version+`"; echo $version))
|
||||
....
|
||||
|
||||
This is to ensure that Perl packages have a dependency on the particular version of Perl it was built against, or on a newer version of Perl that provides backward compatibility with it.
|
||||
|
||||
For example, `perl-5.8.8` provided not only `perl(:MODULE_COMPAT_5.8.8)`, but also `perl(:MODULE_COMPAT_5.8.7)`, etc., because backward compatibility was guaranteed for Fedora Perl 5.8.x.
|
||||
For example, `+perl-5.8.8+` provided not only `+perl(:MODULE_COMPAT_5.8.8)+`, but also `+perl(:MODULE_COMPAT_5.8.7)+`, etc., because backward compatibility was guaranteed for Fedora Perl 5.8.x.
|
||||
|
||||
On the other hand, `perl-5.10.1` implements some incompatible changes to module tree layout and `libperl.so` build options. Once the compatibility aids are removed, `perl-5.10.1` and above will no longer provide `perl(:MODULE_COMPAT_5.10.0)`.
|
||||
On the other hand, `+perl-5.10.1+` implements some incompatible changes to module tree layout and `+libperl.so+` build options. Once the compatibility aids are removed, `+perl-5.10.1+` and above will no longer provide `+perl(:MODULE_COMPAT_5.10.0)+`.
|
||||
|
||||
In the future, it is possible that `perl-5.12.2` will provide not only `perl(:MODULE_COMPAT_5.12.[012])`, but also `perl(:MODULE_COMPAT_5.10.[123])`, if the backward compatibility with all versions >= 5.10.1 is maintained.
|
||||
In the future, it is possible that `+perl-5.12.2+` will provide not only `+perl(:MODULE_COMPAT_5.12.[012])+`, but also `+perl(:MODULE_COMPAT_5.10.[123])+`, if the backward compatibility with all versions >= 5.10.1 is maintained.
|
||||
|
||||
==== Packages that link to `libperl`
|
||||
==== Packages that link to `+libperl+`
|
||||
|
||||
Some packages link to `libperl.so`, usually to provide embedded Perl functionality. All of these packages must also use the versioned `MODULE_COMPAT` dependency, because the automatically generated dependency on `libperl.so` does not include any interface version number.
|
||||
Some packages link to `+libperl.so+`, usually to provide embedded Perl functionality. All of these packages must also use the versioned `+MODULE_COMPAT+` dependency, because the automatically generated dependency on `+libperl.so+` does not include any interface version number.
|
||||
|
||||
=== Filtering Requires and Provides
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ RPM's dependency generator can often throw in additional dependencies and will o
|
|||
|
||||
Under some circumstances, RPM's automatic dependency generator can miss dependencies that should be added.
|
||||
This is usually as a result of using language constructs that the dependency script wasn't expecting.
|
||||
An example of this is in the `perl-Class-Accessor-Chained` package, where the following can be found:
|
||||
An example of this is in the `+perl-Class-Accessor-Chained+` package, where the following can be found:
|
||||
|
||||
....
|
||||
use base 'Class::Accessor::Fast';
|
||||
|
|
@ -87,7 +87,7 @@ use base 'Class::Accessor::Fast';
|
|||
use base 'Class::Accessor';
|
||||
....
|
||||
|
||||
A tell-tale sign of this particular construct is that the package contains a dependency on `perl(base)`, but this is not the only situation in which dependencies can be missed. This package needed additional dependencies as follows:
|
||||
A tell-tale sign of this particular construct is that the package contains a dependency on `+perl(base)+`, but this is not the only situation in which dependencies can be missed. This package needed additional dependencies as follows:
|
||||
|
||||
....
|
||||
Requires: perl(Class::Accessor), perl(Class::Accessor::Fast)
|
||||
|
|
@ -95,7 +95,7 @@ Requires: perl(Class::Accessor), perl(Class::Accessor::Fast)
|
|||
|
||||
In general, it's a good idea to look at the upstream package's documentation for details of other dependencies.
|
||||
|
||||
Another similar example of missing requirements can be seen in `perl-Spreadsheet-WriteExcel`:
|
||||
Another similar example of missing requirements can be seen in `+perl-Spreadsheet-WriteExcel+`:
|
||||
|
||||
....
|
||||
package Spreadsheet::WriteExcel::Utility;
|
||||
|
|
@ -104,7 +104,7 @@ use autouse 'Date::Calc' => qw(Delta_DHMS Decode_Date_EU Decode_Date_US);
|
|||
use autouse 'Date::Manip' => qw(ParseDate Date_Init);
|
||||
....
|
||||
|
||||
Similarly, it possible to miss Provides:, as was the case in http://bugzilla.redhat.com/167797[Bug #167797] , where the `perl-DBD-Pg` package failed to Provide: `perl(DBD::Pg)` due to the following construct in `DBD::Pg` version 1.43:
|
||||
Similarly, it possible to miss Provides:, as was the case in http://bugzilla.redhat.com/167797[Bug #167797] , where the `+perl-DBD-Pg+` package failed to Provide: `+perl(DBD::Pg)+` due to the following construct in `+DBD::Pg+` version 1.43:
|
||||
|
||||
....
|
||||
{ package DBD::Pg;
|
||||
|
|
@ -122,7 +122,7 @@ If something is missing, it can be fixed either by using manual Provides: entrie
|
|||
|
||||
== URL tag
|
||||
|
||||
For CPAN-based packages the URL tag should use a non-versioned metacpan.org URL. E.g., if one were packaging the module `Net::XMPP`, the URL would be:
|
||||
For CPAN-based packages the URL tag should use a non-versioned metacpan.org URL. E.g., if one were packaging the module `+Net::XMPP+`, the URL would be:
|
||||
|
||||
....
|
||||
URL: https://metacpan.org/release/Net-XMPP
|
||||
|
|
@ -142,14 +142,14 @@ There are a couple caveats here:
|
|||
|
||||
* Optional tests do not need to be enabled if they will cause circular build deps
|
||||
* Tests which require network or display access should be disabled for the buildsystem, but with a method provided for local builds
|
||||
* Tests which do not test package functionality should still be invoked, but their exclusion not be considered a blocker (e.g. `Test::Pod::Coverage`, `Test::Kwalitee` and the like)
|
||||
* Author, "release candidate", or smoke tests do not need to be enabled e.g. tests using `Perl::Critic`.
|
||||
* Tests which do not test package functionality should still be invoked, but their exclusion not be considered a blocker (e.g. `+Test::Pod::Coverage+`, `+Test::Kwalitee+` and the like)
|
||||
* Author, "release candidate", or smoke tests do not need to be enabled e.g. tests using `+Perl::Critic+`.
|
||||
|
||||
Additionally, for "meta" packages that provide a common interface to a number of similar modules, it is not necessary to package all of the modules that the package supports so long as at least one module exists to allow the meta package to provide functionality. For instance, the package `perl-JSON-Any` (`JSON::Any`) provides a common interface to `JSON`, `JSON::XS`, `JSON::PC`, `JSON::Syck` and `JSON::DWIM`; `JSON::PC` and `JSON::DWIM` are not currently in Fedora and do not need to be packaged as, e.g. `JSON::XS` enables `JSON::Any`.
|
||||
Additionally, for "meta" packages that provide a common interface to a number of similar modules, it is not necessary to package all of the modules that the package supports so long as at least one module exists to allow the meta package to provide functionality. For instance, the package `+perl-JSON-Any+` (`+JSON::Any+`) provides a common interface to `+JSON+`, `+JSON::XS+`, `+JSON::PC+`, `+JSON::Syck+` and `+JSON::DWIM+`; `+JSON::PC+` and `+JSON::DWIM+` are not currently in Fedora and do not need to be packaged as, e.g. `+JSON::XS+` enables `+JSON::Any+`.
|
||||
|
||||
== Conditionally enabling/disabling tests
|
||||
|
||||
One common way to disable a test for mock but enable it locally is to use a `_with_foo` macro test. e.g.:
|
||||
One common way to disable a test for mock but enable it locally is to use a `+_with_foo+` macro test. e.g.:
|
||||
|
||||
....
|
||||
%check
|
||||
|
|
@ -157,22 +157,22 @@ One common way to disable a test for mock but enable it locally is to use a `_wi
|
|||
./Build test
|
||||
....
|
||||
|
||||
With this construct, an offending test will be removed and not executed, unless `--with network_tests` is passed to `rpmbuild` or %_with_network_tests is defined somewhere, e.g. in a user's `$HOME/.rpmmacros`. This approach preserves the test suite for local builds while working within the technical limitations of the buildsystem.
|
||||
With this construct, an offending test will be removed and not executed, unless `+--with network_tests+` is passed to `+rpmbuild+` or %_with_network_tests is defined somewhere, e.g. in a user's `+$HOME/.rpmmacros+`. This approach preserves the test suite for local builds while working within the technical limitations of the buildsystem.
|
||||
|
||||
== Makefile.PL vs Build.PL
|
||||
|
||||
Perl modules typically utilize one of two different buildsystems:
|
||||
|
||||
* `ExtUtils::MakeMaker`
|
||||
* `Module::Build`
|
||||
* `+ExtUtils::MakeMaker+`
|
||||
* `+Module::Build+`
|
||||
|
||||
The two different styles are easily recognizable: `ExtUtils::MakeMaker` employs the `Makefile.PL` build file, and is the "classical" approach; `Module::Build` is a newer approach, with support for things MakeMaker cannot do. While the ultimate choice of which system to employ is clearly in the hands of upstream, if `Build.PL` is present in a distribution the packager should employ that build framework unless there is a good reason to do otherwise.
|
||||
The two different styles are easily recognizable: `+ExtUtils::MakeMaker+` employs the `+Makefile.PL+` build file, and is the "classical" approach; `+Module::Build+` is a newer approach, with support for things MakeMaker cannot do. While the ultimate choice of which system to employ is clearly in the hands of upstream, if `+Build.PL+` is present in a distribution the packager should employ that build framework unless there is a good reason to do otherwise.
|
||||
|
||||
See also PackagingTips/Perl#Makefile.PL_vs_Build.PL .
|
||||
|
||||
== .h files in module packages
|
||||
|
||||
It is not uncommon for binary module packages to include .h files, see e.g. `perl-DBI`, `perl-Glib`, `perl-Gtk2`. For a variety of reasons these should not be split off into a -devel package.
|
||||
It is not uncommon for binary module packages to include .h files, see e.g. `+perl-DBI+`, `+perl-Glib+`, `+perl-Gtk2+`. For a variety of reasons these should not be split off into a -devel package.
|
||||
|
||||
== Updates of packages
|
||||
|
||||
|
|
@ -187,6 +187,6 @@ PERL5_CPANPLUS_IS_RUNNING=1 to avoid CPAN entirely.
|
|||
|
||||
People around Perl, who are packaging, maintaining & reviewing packages. If you are interested in Perl, join https://lists.fedoraproject.org/mailman/listinfo/Perl-devel[the mailing list], where are discussed latest issues.
|
||||
|
||||
New Perl packages should set the https://lists.fedoraproject.org/mailman/listinfo/Perl-devel[Fedora Perl SIG mailing list] as a member of the initial-cc list for bugzilla. This can be done by adding the user `perl-sig` to the initial CC list when creating the link:Package_SCM_admin_requests#New_Packages[New Package SCM Request].
|
||||
New Perl packages should set the https://lists.fedoraproject.org/mailman/listinfo/Perl-devel[Fedora Perl SIG mailing list] as a member of the initial-cc list for bugzilla. This can be done by adding the user `+perl-sig+` to the initial CC list when creating the link:Package_SCM_admin_requests#New_Packages[New Package SCM Request].
|
||||
|
||||
Category:Perl Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
== BuildRequires: pkgconfig(foo) vs. foo-devel
|
||||
|
||||
Fedora packages which use `pkg-config` to build against a library (e.g. 'foo') on which they depend, *SHOULD* express their build dependency correctly as `pkgconfig(foo)`.
|
||||
Fedora packages which use `+pkg-config+` to build against a library (e.g. 'foo') on which they depend, *SHOULD* express their build dependency correctly as `+pkgconfig(foo)+`.
|
||||
|
||||
=== Rationale
|
||||
|
||||
The build infrastructure for a given package will often locate and use required libraries by using `pkg-config`.
|
||||
The build infrastructure for a given package will often locate and use required libraries by using `+pkg-config+`.
|
||||
|
||||
Thus, `pkgconfig(foo)` is the true statement of the build dependency, and is how it should be expressed in the spec file.
|
||||
Thus, `+pkgconfig(foo)+` is the true statement of the build dependency, and is how it should be expressed in the spec file.
|
||||
|
||||
For historical reasons, many packages seem to have a hard-coded "`BuildRequires: foo-devel`", with the name of the package which _currently_ provides the required pkgconfig module. This is fragile and less portable than simply expressing the real dependency. Where package names change, and/or a required pkgconfig module is later provided by a _different_ package, these hard-coded dependencies break.
|
||||
For historical reasons, many packages seem to have a hard-coded "`+BuildRequires: foo-devel+`", with the name of the package which _currently_ provides the required pkgconfig module. This is fragile and less portable than simply expressing the real dependency. Where package names change, and/or a required pkgconfig module is later provided by a _different_ package, these hard-coded dependencies break.
|
||||
|
||||
Note that it shall still be acceptable to require specific packages by name if they are required for some reason _other_ than a `pkg-config` module that they provide.
|
||||
Note that it shall still be acceptable to require specific packages by name if they are required for some reason _other_ than a `+pkg-config+` module that they provide.
|
||||
|
||||
=== Example
|
||||
|
||||
Packages which build against `libproxy` should contain the following:
|
||||
Packages which build against `+libproxy+` should contain the following:
|
||||
|
||||
....
|
||||
BuildRequires: pkgconfig(libproxy-1.0)
|
||||
|
|
@ -26,4 +26,4 @@ BuildRequires: pkgconfig(libproxy-1.0)
|
|||
BuildRequires: libproxy-devel
|
||||
....
|
||||
|
||||
This way, if the `libproxy-1.0.pc` pkgconfig module is ever provided from a differently-named package (such as by PacRunner once its integration is complete, or by a '`libproxy1`' backward-compatibility package as has happened to a number of other libraries in the past), the dependency will continue to be correct.
|
||||
This way, if the `+libproxy-1.0.pc+` pkgconfig module is ever provided from a differently-named package (such as by PacRunner once its integration is complete, or by a '`+libproxy1+`' backward-compatibility package as has happened to a number of other libraries in the past), the dependency will continue to be correct.
|
||||
|
|
|
|||
|
|
@ -14,23 +14,23 @@ For example Preupgrade Assistant content subpackage for _mariadb_ will be named
|
|||
|
||||
* All packages must have
|
||||
|
||||
` Requires: preupgrade-assistant` +
|
||||
` BuildRequires: preupgrade-assistant-devel`
|
||||
`+ Requires: preupgrade-assistant+` +
|
||||
`+ BuildRequires: preupgrade-assistant-devel+`
|
||||
|
||||
Devel package contains macros and contents validating check script.
|
||||
|
||||
== Architecture
|
||||
|
||||
* All _preupgrade-assistant-*_ subpackages must be architecture independent, i.e. have `BuildArch: noarch`.
|
||||
* All _preupgrade-assistant-*_ subpackages must be architecture independent, i.e. have `+BuildArch: noarch+`.
|
||||
|
||||
== Macros
|
||||
|
||||
* Macro denoting the parent directory where the package files go is `%{preupgrade_dir}`. This currently expands to `/usr/share/preupgrade`.
|
||||
* Macro `%{preupg_number}` means source release from which the system is going to be upgraded, e.g. Fedora 22.
|
||||
* Macro `%{postupg_number}` means target release to which the system is going to be upgraded, e.g. Fedora 23.
|
||||
* Macro `%{preupg_results}` means where the contents files are generated
|
||||
* Macro `%{preupgrade_name}` means *Fedora%\{preupg_number}_%\{postupg_number}*, e.g. Fedora22_23
|
||||
* Macro `%{preupgrade_dir}` reference to */usr/share/preupgrade/%\{preupgrade_name}*
|
||||
* Macro denoting the parent directory where the package files go is `+%{preupgrade_dir}+`. This currently expands to `+/usr/share/preupgrade+`.
|
||||
* Macro `+%{preupg_number}+` means source release from which the system is going to be upgraded, e.g. Fedora 22.
|
||||
* Macro `+%{postupg_number}+` means target release to which the system is going to be upgraded, e.g. Fedora 23.
|
||||
* Macro `+%{preupg_results}+` means where the contents files are generated
|
||||
* Macro `+%{preupgrade_name}+` means *Fedora%\{preupg_number}_%\{postupg_number}*, e.g. Fedora22_23
|
||||
* Macro `+%{preupgrade_dir}+` reference to */usr/share/preupgrade/%\{preupgrade_name}*
|
||||
|
||||
== Prep section
|
||||
|
||||
|
|
@ -46,15 +46,15 @@ Content files are:
|
|||
|
||||
INI file is checked by *%\{preupgrade_build}* script. If something is missing user is informed.
|
||||
|
||||
`[preupgrade]` +
|
||||
`content_title: Short content name` +
|
||||
`author: Your Name <yname@ydomain.com>` +
|
||||
`content_description: 'Enter your description here'` +
|
||||
`config_file: `` THIS IS OPTIONAL. IT INFORMS ADMINISTRATOR WHAT FILES ARE AFFECTED` +
|
||||
`check_script: ` +
|
||||
`solution: ` +
|
||||
`applies_to: <specify_package_needs_to_be_on_system. if_not_installed_then_NOT_APPLICABLE> , comma separated` +
|
||||
`requires: `` THIS IS OPTIONAL`
|
||||
`+[preupgrade]+` +
|
||||
`+content_title: Short content name+` +
|
||||
`+author: Your Name <yname@ydomain.com>+` +
|
||||
`+content_description: 'Enter your description here'+` +
|
||||
`+config_file: +``+ THIS IS OPTIONAL. IT INFORMS ADMINISTRATOR WHAT FILES ARE AFFECTED+` +
|
||||
`+check_script: +` +
|
||||
`+solution: +` +
|
||||
`+applies_to: <specify_package_needs_to_be_on_system. if_not_installed_then_NOT_APPLICABLE> , comma separated+` +
|
||||
`+requires: +``+ THIS IS OPTIONAL+`
|
||||
|
||||
The elements description:
|
||||
|
||||
|
|
@ -71,81 +71,81 @@ The elements description:
|
|||
|
||||
Template for bash check script
|
||||
|
||||
`#!/bin/bash` +
|
||||
`+#!/bin/bash+` +
|
||||
+
|
||||
`. /usr/share/preupgrade/common.sh` +
|
||||
`+. /usr/share/preupgrade/common.sh+` +
|
||||
+
|
||||
`#END GENERATED SECTION` +
|
||||
`+#END GENERATED SECTION+` +
|
||||
+
|
||||
`# This check can be used if you need root privilegues` +
|
||||
`+# This check can be used if you need root privilegues+` +
|
||||
+
|
||||
`# Copy your config file from RHEL6 (in case of scenario RHEL6_7) ` +
|
||||
`# to Temporary Directory` +
|
||||
`CONFIG_FILE="full_path_to_your_config_file"` +
|
||||
`mkdir -p $VALUE_TMP_PREUPGRADE/cleanconf/$(dirname $CONFIG_FILE)` +
|
||||
`cp $CONFIG_FILE $VALUE_TMP_PREUPGRADE/cleanconf/$CONFIG_FILE` +
|
||||
`+# Copy your config file from RHEL6 (in case of scenario RHEL6_7) +` +
|
||||
`+# to Temporary Directory+` +
|
||||
`+CONFIG_FILE="full_path_to_your_config_file"+` +
|
||||
`+mkdir -p $VALUE_TMP_PREUPGRADE/cleanconf/$(dirname $CONFIG_FILE)+` +
|
||||
`+cp $CONFIG_FILE $VALUE_TMP_PREUPGRADE/cleanconf/$CONFIG_FILE+` +
|
||||
+
|
||||
`# Now check you configuration file for options` +
|
||||
`# and for other stuff related with configuration` +
|
||||
`+# Now check you configuration file for options+` +
|
||||
`+# and for other stuff related with configuration+` +
|
||||
+
|
||||
`# If configuration can be used on target system (like RHEL7 in case of RHEL6_7)` +
|
||||
`# the exit should be RESULT_PASS` +
|
||||
`+# If configuration can be used on target system (like RHEL7 in case of RHEL6_7)+` +
|
||||
`+# the exit should be RESULT_PASS+` +
|
||||
+
|
||||
`# If configuration can not be used on target system (like RHEL 7 in case of RHEL6_7)` +
|
||||
`# scenario then result should be RESULT_FAIL. Correction of` +
|
||||
`# configuration file is provided either by solution script` +
|
||||
`# or by postupgrade script located in $VALUE_TMP_PREUPGRADE/postupgrade.d/` +
|
||||
`+# If configuration can not be used on target system (like RHEL 7 in case of RHEL6_7)+` +
|
||||
`+# scenario then result should be RESULT_FAIL. Correction of+` +
|
||||
`+# configuration file is provided either by solution script+` +
|
||||
`+# or by postupgrade script located in $VALUE_TMP_PREUPGRADE/postupgrade.d/+` +
|
||||
+
|
||||
`# if configuration file can be fixed then fix them in temporary directory` +
|
||||
`# $VALUE_TMP_PREUPGRADE/$CONFIG_FILE and result should be RESULT_FIXED` +
|
||||
`# More information about this issues should be described in solution.txt file` +
|
||||
`# as reference to KnowledgeBase article.` +
|
||||
`+# if configuration file can be fixed then fix them in temporary directory+` +
|
||||
`+# $VALUE_TMP_PREUPGRADE/$CONFIG_FILE and result should be RESULT_FIXED+` +
|
||||
`+# More information about this issues should be described in solution.txt file+` +
|
||||
`+# as reference to KnowledgeBase article.+` +
|
||||
+
|
||||
`grep "Sometext" $CONFIG_FILE` +
|
||||
`if [ $? -ne 0 ]; then` +
|
||||
` log_info "Config file $CONFIG_FILE will be fixed by solution script"` +
|
||||
` # postupgrade.d directory from your content is automatically copied by` +
|
||||
` # preupgrade assistant into $VALUE_TMP_PREUPGRADE/postupgrade.d/ directory` +
|
||||
` exit $RESULT_FAIL` +
|
||||
`fi` +
|
||||
`+grep "Sometext" $CONFIG_FILE+` +
|
||||
`+if [ $? -ne 0 ]; then+` +
|
||||
`+ log_info "Config file $CONFIG_FILE will be fixed by solution script"+` +
|
||||
`+ # postupgrade.d directory from your content is automatically copied by+` +
|
||||
`+ # preupgrade assistant into $VALUE_TMP_PREUPGRADE/postupgrade.d/ directory+` +
|
||||
`+ exit $RESULT_FAIL+` +
|
||||
`+fi+` +
|
||||
+
|
||||
`exit $RESULT_PASS`
|
||||
`+exit $RESULT_PASS+`
|
||||
|
||||
=== Python check script template
|
||||
|
||||
Template for python check script
|
||||
|
||||
`#!/usr/bin/python` +
|
||||
`# -*- Mode: Python; python-indent: 8; indent-tabs-mode: t -*- ` +
|
||||
`+#!/usr/bin/python+` +
|
||||
`+# -*- Mode: Python; python-indent: 8; indent-tabs-mode: t -*- +` +
|
||||
+
|
||||
`import sys, os, errno` +
|
||||
`import datetime` +
|
||||
`+import sys, os, errno+` +
|
||||
`+import datetime+` +
|
||||
+
|
||||
`from preup.script_api import *` +
|
||||
`+from preup.script_api import *+` +
|
||||
+
|
||||
`#END GENERATED SECTION` +
|
||||
`component = "Specify component name used for logging"` +
|
||||
`# exit functions are exit_{pass,not_applicable, fixed, fail, etc.}` +
|
||||
`# logging functions are log_{error, warning, info, etc.}` +
|
||||
`# for logging in-place risk use functions log_{extreme, high, medium, slight}_risk` +
|
||||
`+#END GENERATED SECTION+` +
|
||||
`+component = "Specify component name used for logging"+` +
|
||||
`+# exit functions are exit_{pass,not_applicable, fixed, fail, etc.}+` +
|
||||
`+# logging functions are log_{error, warning, info, etc.}+` +
|
||||
`+# for logging in-place risk use functions log_{extreme, high, medium, slight}_risk+` +
|
||||
+
|
||||
`def main():` +
|
||||
` if os.geteuid() != 0:` +
|
||||
` sys.stdout.write("Need to be root.\n")` +
|
||||
` log_slight_risk("The script needs to be run under root account")` +
|
||||
` exit_error()` +
|
||||
`+def main():+` +
|
||||
`+ if os.geteuid() != 0:+` +
|
||||
`+ sys.stdout.write("Need to be root.\n")+` +
|
||||
`+ log_slight_risk("The script needs to be run under root account")+` +
|
||||
`+ exit_error()+` +
|
||||
+
|
||||
+
|
||||
`if __name__ == "__main__":` +
|
||||
` set_component(component) ` +
|
||||
` main()` +
|
||||
` exit_pass()`
|
||||
`+if __name__ == "__main__":+` +
|
||||
`+ set_component(component) +` +
|
||||
`+ main()+` +
|
||||
`+ exit_pass()+`
|
||||
|
||||
== Build section
|
||||
|
||||
Run command:
|
||||
|
||||
`%{preupgrade_build} %{preupgrade_name}/%{name}/`
|
||||
`+%{preupgrade_build} %{preupgrade_name}/%{name}/+`
|
||||
|
||||
%\{preupgrade_build} command has to succeed. Warning can be suppressed.
|
||||
|
||||
|
|
@ -153,41 +153,41 @@ Run command:
|
|||
|
||||
All files from _preupgrade_ directory should be installed with
|
||||
|
||||
`%install` +
|
||||
`...` +
|
||||
`mkdir -p ${buildroot}%{preupgrade_dir}/%{name}` +
|
||||
`install -p -m 755 %{SourceY} ${buildroot}%{preupgrade_dir}/%{name}/check.sh` +
|
||||
`install -p -m 644 %{SourceZ} ${buildroot}%{preupgrade_dir}/%{name}/solution.txt` +
|
||||
`install -p -m 644 %{preupgrade_name}-%{preupg_results}/%{name}/group.xml ${buildroot}%{preupgrade_dir}/%{name}/group.xml`
|
||||
`+%install+` +
|
||||
`+...+` +
|
||||
`+mkdir -p ${buildroot}%{preupgrade_dir}/%{name}+` +
|
||||
`+install -p -m 755 %{SourceY} ${buildroot}%{preupgrade_dir}/%{name}/check.sh+` +
|
||||
`+install -p -m 644 %{SourceZ} ${buildroot}%{preupgrade_dir}/%{name}/solution.txt+` +
|
||||
`+install -p -m 644 %{preupgrade_name}-%{preupg_results}/%{name}/group.xml ${buildroot}%{preupgrade_dir}/%{name}/group.xml+`
|
||||
|
||||
== Files section
|
||||
|
||||
* Directory where Preupgrade Assistant installs files and directories must be owned by the subpackage
|
||||
|
||||
`%files` +
|
||||
`...` +
|
||||
`%files -n preupgrade-assistant-%{name}` +
|
||||
`%dir %{preupgrade_dir}/%{name}`
|
||||
`+%files+` +
|
||||
`+...+` +
|
||||
`+%files -n preupgrade-assistant-%{name}+` +
|
||||
`+%dir %{preupgrade_dir}/%{name}+`
|
||||
|
||||
* All files except text files should be listed like
|
||||
|
||||
`%files` +
|
||||
`...` +
|
||||
`%files -n preupgrade-assistant-%{name}` +
|
||||
`%{preupgrade_dir}/%{name}/*.{sh,py}` +
|
||||
`%{preupgrade_dir}/%{name}/*.xml`
|
||||
`+%files+` +
|
||||
`+...+` +
|
||||
`+%files -n preupgrade-assistant-%{name}+` +
|
||||
`+%{preupgrade_dir}/%{name}/*.{sh,py}+` +
|
||||
`+%{preupgrade_dir}/%{name}/*.xml+`
|
||||
|
||||
* All text files from content should be listed via
|
||||
|
||||
`%files` +
|
||||
`...` +
|
||||
`%files -n preupgrade-assistant-%{name}` +
|
||||
`%doc %{preupgrade_dir}/%{name}/*.txt`
|
||||
`+%files+` +
|
||||
`+...+` +
|
||||
`+%files -n preupgrade-assistant-%{name}+` +
|
||||
`+%doc %{preupgrade_dir}/%{name}/*.txt+`
|
||||
|
||||
== Directory ownership
|
||||
|
||||
Directories `/usr/share/preupgrade` and
|
||||
`%{preupgrade_dir}`
|
||||
Directories `+/usr/share/preupgrade+` and
|
||||
`+%{preupgrade_dir}+`
|
||||
are owned by package _preupgrade-assistant_ itself and should not be owned by your package.
|
||||
|
||||
== Sample SPEC
|
||||
|
|
|
|||
|
|
@ -8,109 +8,111 @@ For guidelines on maintaining already existing python2 packages, see the Packagi
|
|||
|
||||
== Multiple Python Runtimes
|
||||
|
||||
For backwards compatibility, `/usr/bin/python` is, if it is installed, a symbolic link to `/usr/bin/python2`.
|
||||
For backwards compatibility, `+/usr/bin/python+` is, if it is installed, a symbolic link to `+/usr/bin/python2+`.
|
||||
|
||||
Packages in Fedora MUST NOT use `/usr/bin/python`. Instead packages for Python 3 MUST use `/usr/bin/python3` (even if upstream supports both Python 2 and 3). As a result of that `/usr/bin/python` (as well as `/usr/bin/env python` and similar) MUST NOT be used in shebang lines or as a dependency of a package. As of Fedora 30, all uses of unversioned python executables in shebang lines will fail the build.
|
||||
Packages in Fedora MUST NOT use `+/usr/bin/python+`. Instead packages for Python 3 MUST use `+/usr/bin/python3+` (even if upstream supports both Python 2 and 3). As a result of that `+/usr/bin/python+` (as well as `+/usr/bin/env python+` and similar) MUST NOT be used in shebang lines or as a dependency of a package. As of Fedora 30, all uses of unversioned python executables in shebang lines will fail the build.
|
||||
These shebangs MUST be fixed. If it is necessary to disable the checks, please see the information in Packaging:Guidelines#Shebang_lines.
|
||||
|
||||
All python runtimes have a virtual provide for `python(abi) = $MAJOR-$MINOR`. For example, the Python 3.7 runtime package has:
|
||||
All python runtimes have a virtual provide for `+python(abi) = $MAJOR-$MINOR+`. For example, the Python 3.7 runtime package has:
|
||||
|
||||
` $ rpm -q --provides python3 |grep -i abi` +
|
||||
` python(abi) = 3.7`
|
||||
`+ $ rpm -q --provides python3 |grep -i abi+` +
|
||||
`+ python(abi) = 3.7+`
|
||||
|
||||
Python modules using these runtimes should have a corresponding "Requires" line on the python runtime that they are used with. This is done automatically for files below `/usr/lib[^/]*/python${PYVER}`
|
||||
Python modules using these runtimes should have a corresponding "Requires" line on the python runtime that they are used with. This is done automatically for files below `+/usr/lib[^/]*/python${PYVER}+`
|
||||
|
||||
Mirroring the policy for regular packages, the Python-version-specific subpackages of your package MUST NOT be removed in a release branch of Fedora.
|
||||
|
||||
== Naming
|
||||
|
||||
The source package for a Python library MUST be named with the `python-` prefix. A built package however must include the Python major version in the name, using the `python3-` prefix. This is accomplished by adding a subpackage. See example bellow.
|
||||
The source package for a Python library MUST be named with the `+python-+` prefix. A built package however must include the Python major version in the name, using the `+python3-+` prefix. This is accomplished by adding a subpackage. See example bellow.
|
||||
|
||||
This rule does not apply to applications.
|
||||
|
||||
== Dependencies
|
||||
|
||||
Packages building for Python 3 will need `BuildRequires: python3-devel`.
|
||||
Packages building for Python 3 will need `+BuildRequires: python3-devel+`.
|
||||
|
||||
Packages MUST NOT have dependencies (either build-time or runtime) on packages named with the unversioned `python-` prefix. Dependencies on Python packages instead MUST use names beginning with `python3-`.
|
||||
Packages MUST NOT have dependencies (either build-time or runtime) on packages named with the unversioned `+python-+` prefix. Dependencies on Python packages instead MUST use names beginning with `+python3-+`.
|
||||
|
||||
=== Automatically generated dependencies
|
||||
|
||||
Packages MAY use the automatic Python dependency generator. This generator uses upstream egg/dist metadata (such as https://python-packaging.readthedocs.io/en/latest/dependencies.html[setuptool's install_requires]) to determine what the package should depend on. The generator parses the installed metadata from `/usr/lib(64)?/pythonX.Y/site-packages/``-``-pyX.Y.(egg|dist)-info/requires.txt`, so it will not work with software that uses plain https://docs.python.org/3/distutils/[distutils].
|
||||
Packages MAY use the automatic Python dependency generator. This generator uses upstream egg/dist metadata (such as https://python-packaging.readthedocs.io/en/latest/dependencies.html[setuptool's install_requires]) to determine what the package should depend on. The generator parses the installed metadata from `+/usr/lib(64)?/pythonX.Y/site-packages/+``+-+``+-pyX.Y.(egg|dist)-info/requires.txt+`, so it will not work with software that uses plain https://docs.python.org/3/distutils/[distutils].
|
||||
|
||||
To enable this feature, add:
|
||||
|
||||
`%{?python_enable_dependency_generator}`
|
||||
`+%{?python_enable_dependency_generator}+`
|
||||
|
||||
Although this statement can be used anywhere in the spec, we recommend putting it just before the main package's `%description` declaration.
|
||||
This generates run time requires in the form of `pythonX.Ydist(foo)`. If the generated dependencies are not accurate, additional ones can still be added manually. To remove some, a packager MAY modify upstream-provided metadata (usually specified in the `setup.py` file) in the `%prep` section of the specfile or fall back to Packaging:AutoProvidesAndRequiresFiltering[filtering] those dependencies.
|
||||
Although this statement can be used anywhere in the spec, we recommend putting it just before the main package's `+%description+` declaration.
|
||||
This generates run time requires in the form of `+pythonX.Ydist(foo)+`. If the generated dependencies are not accurate, additional ones can still be added manually. To remove some, a packager MAY modify upstream-provided metadata (usually specified in the `+setup.py+` file) in the `+%prep+` section of the specfile or fall back to Packaging:AutoProvidesAndRequiresFiltering[filtering] those dependencies.
|
||||
|
||||
The packager MUST inspect the generated requires for correctness. All dependencies MUST be resolvable within the targeted Fedora version.
|
||||
|
||||
As an example, the upstream notebook package has (as of version 5.6.0):
|
||||
|
||||
`install_requires = [` +
|
||||
` 'jinja2',` +
|
||||
` 'tornado>=4',` +
|
||||
` 'pyzmq>=17',` +
|
||||
` 'ipython_genutils',` +
|
||||
` 'traitlets>=4.2.1',` +
|
||||
` 'jupyter_core>=4.4.0',` +
|
||||
` 'jupyter_client>=5.2.0',` +
|
||||
` 'nbformat',` +
|
||||
` 'nbconvert',` +
|
||||
` 'ipykernel',` +
|
||||
` 'Send2Trash',` +
|
||||
` 'terminado>=0.8.1',` +
|
||||
` 'prometheus_client'` +
|
||||
`],`
|
||||
`+install_requires = [+` +
|
||||
`+ 'jinja2',+` +
|
||||
`+ 'tornado>=4',+` +
|
||||
`+ 'pyzmq>=17',+` +
|
||||
`+ 'ipython_genutils',+` +
|
||||
`+ 'traitlets>=4.2.1',+` +
|
||||
`+ 'jupyter_core>=4.4.0',+` +
|
||||
`+ 'jupyter_client>=5.2.0',+` +
|
||||
`+ 'nbformat',+` +
|
||||
`+ 'nbconvert',+` +
|
||||
`+ 'ipykernel',+` +
|
||||
`+ 'Send2Trash',+` +
|
||||
`+ 'terminado>=0.8.1',+` +
|
||||
`+ 'prometheus_client'+` +
|
||||
`+],+`
|
||||
|
||||
And the resulting dependencies:
|
||||
|
||||
`python3.7dist(ipykernel)` +
|
||||
`python3.7dist(ipython-genutils)` +
|
||||
`python3.7dist(jinja2)` +
|
||||
`python3.7dist(jupyter-client) >= 5.2.0` +
|
||||
`python3.7dist(jupyter-core) >= 4.4.0` +
|
||||
`python3.7dist(nbconvert)` +
|
||||
`python3.7dist(nbformat)` +
|
||||
`python3.7dist(prometheus-client)` +
|
||||
`python3.7dist(pyzmq) >= 17` +
|
||||
`python3.7dist(send2trash)` +
|
||||
`python3.7dist(terminado) >= 0.8.1` +
|
||||
`python3.7dist(tornado) >= 4` +
|
||||
`python3.7dist(traitlets) >= 4.2.1`
|
||||
`+python3.7dist(ipykernel)+` +
|
||||
`+python3.7dist(ipython-genutils)+` +
|
||||
`+python3.7dist(jinja2)+` +
|
||||
`+python3.7dist(jupyter-client) >= 5.2.0+` +
|
||||
`+python3.7dist(jupyter-core) >= 4.4.0+` +
|
||||
`+python3.7dist(nbconvert)+` +
|
||||
`+python3.7dist(nbformat)+` +
|
||||
`+python3.7dist(prometheus-client)+` +
|
||||
`+python3.7dist(pyzmq) >= 17+` +
|
||||
`+python3.7dist(send2trash)+` +
|
||||
`+python3.7dist(terminado) >= 0.8.1+` +
|
||||
`+python3.7dist(tornado) >= 4+` +
|
||||
`+python3.7dist(traitlets) >= 4.2.1+`
|
||||
|
||||
This generator will most likely be enabled by default in the future. If a packager wishes to explicitly opt out of the generator because the upstream metadata are not applicable, a packager MUST NOT assume that the generator won't be used simply because it is not enabled explicitly. Rather, they SHOULD opt out explicitly by adding:
|
||||
|
||||
`%{?python_disable_dependency_generator}`
|
||||
`+%{?python_disable_dependency_generator}+`
|
||||
|
||||
== Provides
|
||||
|
||||
Using a fictional module named "example", the subpackage containing the python3 version *must* provide `python3-example`. This is of course always the case if the subpackage is named `python3-example` (as in the examples below). If the subpackage has some other name then then `Provides: python3-example` must be added explicitly (but see the `%python_provide` macro below).
|
||||
Using a fictional module named "example", the subpackage containing the python3 version *must* provide `+python3-example+`. This is of course always the case if the subpackage is named `+python3-example+` (as in the examples below). If the subpackage has some other name then then `+Provides: python3-example+` must be added explicitly (but see the `+%python_provide+` macro below).
|
||||
|
||||
=== The %python_provide macro
|
||||
|
||||
In order to make the switch from Python 2 to Python 3 automatic, all packages that provide `python3-%{srcname}` (for any `%{srcname}`) SHOULD use the `%python_provide` macro with the package name, for example:
|
||||
In order to make the switch from Python 2 to Python 3 automatic, all packages that provide `+python3-%{srcname}+` (for any `+%{srcname}+`) SHOULD use the `+%python_provide+` macro with the package name, for example:
|
||||
|
||||
` %{?python_provide:%python_provide python3-%{srcname}}`
|
||||
----
|
||||
%{?python_provide:%python_provide python3-%{srcname}}
|
||||
----
|
||||
|
||||
This eases distribution-wide renaming of Python packages. (For example, in the future a virtual provide of `python-%{srcname}` might become appropriate for Python 3 libraries. In that case, `%python_provide` will be changed to add it.) Packages that do not include this macro would need to be adapted to such changes manually.
|
||||
This eases distribution-wide renaming of Python packages. (For example, in the future a virtual provide of `+python-%{srcname}+` might become appropriate for Python 3 libraries. In that case, `+%python_provide+` will be changed to add it.) Packages that do not include this macro would need to be adapted to such changes manually.
|
||||
|
||||
== Automatic Provides with a standardized name
|
||||
|
||||
When building a Python package, RPM looks for `.dist-info` and `.egg-info` files or directories in the `%files` sections of all packages. If one or more are found, RPM parses them to find the *standardized name* (i.e. dist name, name on PyPI) of the packaged software, and then automatically creates two `Provides:` tags in the following format:
|
||||
When building a Python package, RPM looks for `+.dist-info+` and `+.egg-info+` files or directories in the `+%files+` sections of all packages. If one or more are found, RPM parses them to find the *standardized name* (i.e. dist name, name on PyPI) of the packaged software, and then automatically creates two `+Provides:+` tags in the following format:
|
||||
|
||||
....
|
||||
Provides: python3.Ydist(CANONICAL_STANDARDIZED_NAME)
|
||||
Provides: python3dist(CANONICAL_STANDARDIZED_NAME)
|
||||
....
|
||||
|
||||
The `3.Y` is the Python version used (usually 3.6 and higher), and between the parentheses is the name of the software in a *canonical format* used by Python tools and services such as setuptools, pip and PyPI. The canonical name is obtained by switching the standardized name to lower case and converting all runs of non-alphanumeric characters to single “-” characters. Example: “The $$$ Tree” becomes “the-tree”.
|
||||
The `+3.Y+` is the Python version used (usually 3.6 and higher), and between the parentheses is the name of the software in a *canonical format* used by Python tools and services such as setuptools, pip and PyPI. The canonical name is obtained by switching the standardized name to lower case and converting all runs of non-alphanumeric characters to single “-” characters. Example: “The $$$ Tree” becomes “the-tree”.
|
||||
|
||||
=== Requires and BuildRequires with standardized names
|
||||
|
||||
These Provides tags can be used to list Requires and BuildRequires of a package using the _standardized names_ (i.e. dist name, name on PyPI) of Python modules. To make it easier, you can use the `%{py3_dist}` macro that accept one or more parameters: the _standardized name(s)_ of the desired Python software. It will convert the name(s) to the _canonical format_ and create the proper `python3dist(...)` tag(s).
|
||||
These Provides tags can be used to list Requires and BuildRequires of a package using the _standardized names_ (i.e. dist name, name on PyPI) of Python modules. To make it easier, you can use the `+%{py3_dist}+` macro that accept one or more parameters: the _standardized name(s)_ of the desired Python software. It will convert the name(s) to the _canonical format_ and create the proper `+python3dist(...)+` tag(s).
|
||||
|
||||
In addition, you can use the %\{py_dist_name} macro that simply transforms any _standardized name_ to the _canonical format_.
|
||||
|
||||
|
|
@ -129,11 +131,11 @@ Requires: %{py3_dist virtualenv pyPEG2}
|
|||
|
||||
== Source Files from PyPI
|
||||
|
||||
When packaging software which is available from PyPI, you can make use of the `%pypi_source` macro. This macro accepts from zero to three arguments and evaluates to an appropriate URL for the source file on PyPI. The arguments are:
|
||||
When packaging software which is available from PyPI, you can make use of the `+%pypi_source+` macro. This macro accepts from zero to three arguments and evaluates to an appropriate URL for the source file on PyPI. The arguments are:
|
||||
|
||||
1. The name of the PyPI project. Defaults to `%srcname` if defined, or to `%pypi_name` if defined, or to `%name` (the package name).
|
||||
2. The version of the PyPI project. Defaults to `%version` (the package version).
|
||||
3. The file extension to use. Defaults to `tar.gz`.
|
||||
1. The name of the PyPI project. Defaults to `+%srcname+` if defined, or to `+%pypi_name+` if defined, or to `+%name+` (the package name).
|
||||
2. The version of the PyPI project. Defaults to `+%version+` (the package version).
|
||||
3. The file extension to use. Defaults to `+tar.gz+`.
|
||||
|
||||
In most cases it is not necessary to specify any arguments.
|
||||
|
||||
|
|
@ -146,11 +148,11 @@ The following macros are defined for you in all supported Fedora and EPEL releas
|
|||
|Macro |Normal Definition |Notes
|
||||
|__python |/usr/bin/python |Prohibited (see note below)
|
||||
|__python3 |/usr/bin/python3 |Python 3 interpreter
|
||||
|python_provide |(Lua script) |Given a package name, evaluates to either `Provides: python-example` or nothing at all depending on the Python version. See [[Packaging:Python#The_.25python_provide_macro |here]] for an example.
|
||||
|python_provide |(Lua script) |Given a package name, evaluates to either `+Provides: python-example+` or nothing at all depending on the Python version. See [[Packaging:Python#The_.25python_provide_macro |here]] for an example.
|
||||
|python3_sitelib |/usr/lib/python3.X/site-packages |Where pure python3 modules are installed
|
||||
|python3_sitearch |/usr/lib64/python3.X/site-packages on x86_64 +
|
||||
/usr/lib/python3.X/site-packages on x86 |Where python3 extension modules that are compiled C are installed
|
||||
|py3_dist |(Lua script) |Given a standardized name (i.e. dist name, name on PyPI) of Python software, it will convert it to a canonical format, and evaluates to `python3dist(CANONICAL_NAME)`, which is useful when listing dependencies. See [[Packaging:Python#Automatic_Provides_with_a_standardized_name |above]] for more information.
|
||||
|py3_dist |(Lua script) |Given a standardized name (i.e. dist name, name on PyPI) of Python software, it will convert it to a canonical format, and evaluates to `+python3dist(CANONICAL_NAME)+`, which is useful when listing dependencies. See [[Packaging:Python#Automatic_Provides_with_a_standardized_name |above]] for more information.
|
||||
|py_byte_compile |(script) |Defined in python3-devel. See the [[Packaging:Python_Appendix#Manual_byte_compilation |byte compiling]] section for usage
|
||||
|python3_version |3.X |Defined in python3-devel. Useful when running programs with Python version in filename, such as nosetest-%\{python3_version}
|
||||
|python3_version_nodots |3X |Defined in python3-devel. Useful when listing files explicitly in %files section , such as %\{python3_sitelib}/foo/*.cpython-%\{python3_version_nodots}.pyo
|
||||
|
|
@ -160,7 +162,7 @@ The following macros are defined for you in all supported Fedora and EPEL releas
|
|||
|pypi_source |(Lua script) |Evaluates to the appropriate URL for the package. See above for more information.
|
||||
|===========================================================================================================================================================================================================================================================================================================================================
|
||||
|
||||
During `%install` or when listing `%files` you can use the `python3_sitearch` and `python3_sitelib` macros to specify where the installed modules are to be found. For instance:
|
||||
During `+%install+` or when listing `+%files+` you can use the `+python3_sitearch+` and `+python3_sitelib+` macros to specify where the installed modules are to be found. For instance:
|
||||
|
||||
....
|
||||
%files
|
||||
|
|
@ -173,7 +175,7 @@ During `%install` or when listing `%files` you can use the `python3_sitearch` an
|
|||
Use of the macros has several benefits:
|
||||
|
||||
* It ensures that the packages are installed correctly on multilib architectures.
|
||||
* Using these macros instead of hardcoding the directory in the specfile ensures your spec remains compatible with the installed python version even if the directory structure changes radically (for instance, if `python3_sitelib` moves into `%{_datadir}`).
|
||||
* Using these macros instead of hardcoding the directory in the specfile ensures your spec remains compatible with the installed python version even if the directory structure changes radically (for instance, if `+python3_sitelib+` moves into `+%{_datadir}+`).
|
||||
|
||||
== Files to include
|
||||
|
||||
|
|
@ -189,22 +191,22 @@ The source files MUST be included in the same package as the byte compiled versi
|
|||
|
||||
Packagers SHOULD NOT simply glob everything under the sitelib or sitearch directories. The following SHOULD NOT be used:
|
||||
|
||||
* `%{python3_sitelib}/*`
|
||||
* `%{python3_sitearch}/*`
|
||||
* `%{python_sitelib}/*`
|
||||
* `%{python_sitearch}/*`
|
||||
* `+%{python3_sitelib}/*+`
|
||||
* `+%{python3_sitearch}/*+`
|
||||
* `+%{python_sitelib}/*+`
|
||||
* `+%{python_sitearch}/*+`
|
||||
|
||||
And packages MUST NOT include the top-level `__pycache__` directory (see below).
|
||||
And packages MUST NOT include the top-level `+__pycache__+` directory (see below).
|
||||
|
||||
== Byte compiling
|
||||
|
||||
Python will automatically try to byte compile files when it runs in order to speed up startup the next time it is run. These files are saved in files with the extension of .pyc (compiled python). These files will be located inside a directory named `__pycache__`.
|
||||
Python will automatically try to byte compile files when it runs in order to speed up startup the next time it is run. These files are saved in files with the extension of .pyc (compiled python). These files will be located inside a directory named `+__pycache__+`.
|
||||
|
||||
The .pyc files contain byte code that is portable across OSes. If you do not include them in your packages, python will try (and generally fail) to create them when the user runs the program. If the system administrator runs the program, then the files will be successfully written, causing stray .pyc files which will not be removed when the package is removed. To prevent that the byte compiled files need to be compiled and included in the `%files` section. Normally, byte compilation is done for you by the `brp-python-bytecompile` script. This script runs after the `%install` section of the spec file has been processed and byte compiles any .py files that it finds in `%{python3_sitelib}` or `%{python3_sitearch}` (this recompilation puts the proper filesystem paths into the modules otherwise tracebacks would include the `%{buildroot}` in them).
|
||||
The .pyc files contain byte code that is portable across OSes. If you do not include them in your packages, python will try (and generally fail) to create them when the user runs the program. If the system administrator runs the program, then the files will be successfully written, causing stray .pyc files which will not be removed when the package is removed. To prevent that the byte compiled files need to be compiled and included in the `+%files+` section. Normally, byte compilation is done for you by the `+brp-python-bytecompile+` script. This script runs after the `+%install+` section of the spec file has been processed and byte compiles any .py files that it finds in `+%{python3_sitelib}+` or `+%{python3_sitearch}+` (this recompilation puts the proper filesystem paths into the modules otherwise tracebacks would include the `+%{buildroot}+` in them).
|
||||
|
||||
You must include the .pyc files in your package. If the build process creates a __pycache__ directory in a subdirectory of %\{python3_sitearch} or %\{python3_sitelib}, you must also include all items in the __pycache__ directory. You MUST NOT include the directories %\{python3_sitearch}/__pycache__ or %\{python3_sitelib}/__pycache__ because they are already owned by the python3-libs package.
|
||||
|
||||
All that you need to do is include the files in the `%files` section (replacing %\{python3_sitelib} with the appropriate macro for your package):
|
||||
All that you need to do is include the files in the `+%files+` section (replacing %\{python3_sitelib} with the appropriate macro for your package):
|
||||
|
||||
....
|
||||
%files
|
||||
|
|
@ -289,7 +291,7 @@ The following briefly summarizes the guidelines for reviewers to go over:
|
|||
* *Must*: Python modules must not download any dependencies during the build process.
|
||||
* *Must*: When building a compat package, it must install using easy_install -m so it won't conflict with the main package.
|
||||
* *Must*: When building multiple versions (for a compat package) one of the packages must contain a default version that is usable via "import MODULE" with no prior setup.
|
||||
* *Should*: If you build a python module you should use the `%python_provide` macro.
|
||||
* *Should*: If you build a python module you should use the `+%python_provide+` macro.
|
||||
* *Should*: A package which is used by another package via an egg interface should provide egg info.
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines] Category:Python
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ Here are some additional Python-related guidelines, moved here in order to keep
|
|||
|
||||
== Python 2 packages
|
||||
|
||||
If your package needs to build for Python 2 only, follow the Packaging:Python[regular Python guidelines], except substitute 3 for 2. For example instead of `%{python3_sitearch}`, use `%{python2_sitearch}`.
|
||||
If your package needs to build for Python 2 only, follow the Packaging:Python[regular Python guidelines], except substitute 3 for 2. For example instead of `+%{python3_sitearch}+`, use `+%{python2_sitearch}+`.
|
||||
|
||||
Special emphasis on the rule that packages MUST NOT use `/usr/bin/python`.
|
||||
Special emphasis on the rule that packages MUST NOT use `+/usr/bin/python+`.
|
||||
|
||||
=== Naming
|
||||
|
||||
|
|
@ -23,12 +23,12 @@ because the build products for different versions of Python usually do not confl
|
|||
|
||||
There are cases where it is not possible to build in a single directory. Most
|
||||
commonly this happens when the sources are modified during the build process to
|
||||
convert them from python2 to python3 using the the `2to3` tool (see bellow).
|
||||
convert them from python2 to python3 using the the `+2to3+` tool (see bellow).
|
||||
|
||||
As you can see in the `%install` section below, the order in which
|
||||
As you can see in the `+%install+` section below, the order in which
|
||||
you do the python2 versus python3 install can sometimes matter. You need to be
|
||||
aware of when the install is writing to the same file in both packages (in this
|
||||
example, a script in `%{_bindir}`) and make sure that you're getting
|
||||
example, a script in `+%{_bindir}+`) and make sure that you're getting
|
||||
the version you expect.
|
||||
|
||||
....
|
||||
|
|
@ -106,18 +106,18 @@ An python module which provides a convenient example.
|
|||
|
||||
Sometimes is it impossible to build both versions from the same source directory. Most often this happens when sources are "translated" to python3 in the source directory and made incompatible with python2 in the process. This used to be fairly common, but is fortunately much rarer now. Some things to look for are:
|
||||
|
||||
* Sources are not Python 3 compatible (`print` without parentheses is used, old module names like `ConfigParser` are imported),
|
||||
* `six` module is not used,
|
||||
* `2to3` is run in `setup.py` without creating a separate build directory.
|
||||
* Sources are not Python 3 compatible (`+print+` without parentheses is used, old module names like `+ConfigParser+` are imported),
|
||||
* `+six+` module is not used,
|
||||
* `+2to3+` is run in `+setup.py+` without creating a separate build directory.
|
||||
|
||||
Our method in building from the same code to make the two separate modules is to keep each build as independent as possible. To do that, we copy the source tree to python3 so that the python 2 sources are entirely independent from the python 3 sources.
|
||||
|
||||
Some things to watch out for:
|
||||
|
||||
* Make sure that you are copying the correct code. The example is copying the code from within the top directory of the untarred source. If the `%prep` has changed directory you will need to change back to the tarball location.
|
||||
* Patching the source code is done before copying to `python3`. Since you have both a python2 and a python3 directory you might be tempted to patch each one separately. *Resist!* Upstream for your package has chosen to distribute a single source tree that builds for both python2 and python3. For your patches to link:Staying_close_to_upstream_projects[ get into upstream], you need to write patches that work with both as well.
|
||||
* Make sure that you are copying the correct code. The example is copying the code from within the top directory of the untarred source. If the `+%prep+` has changed directory you will need to change back to the tarball location.
|
||||
* Patching the source code is done before copying to `+python3+`. Since you have both a python2 and a python3 directory you might be tempted to patch each one separately. *Resist!* Upstream for your package has chosen to distribute a single source tree that builds for both python2 and python3. For your patches to link:Staying_close_to_upstream_projects[ get into upstream], you need to write patches that work with both as well.
|
||||
|
||||
`rpmbuild` resets the directory at the end of each phase, so you don't need to restore the directory at the end of `%prep`.
|
||||
`+rpmbuild+` resets the directory at the end of each phase, so you don't need to restore the directory at the end of `+%prep+`.
|
||||
|
||||
....
|
||||
%prep
|
||||
|
|
@ -168,21 +168,21 @@ pushd python3
|
|||
popd
|
||||
....
|
||||
|
||||
You'll notice that the `%build`, `%install`, and `%check` sections again follow a pattern similar to the previous example. They switch to the python2 directory and do the normal steps for building the python2 module, and then switch to the python3 directory and run the same steps for python3. The usage of `pushd/popd` commands will ensure that the directories are logged.
|
||||
You'll notice that the `+%build+`, `+%install+`, and `+%check+` sections again follow a pattern similar to the previous example. They switch to the python2 directory and do the normal steps for building the python2 module, and then switch to the python3 directory and run the same steps for python3. The usage of `+pushd/popd+` commands will ensure that the directories are logged.
|
||||
|
||||
=== Avoiding collisions between the python 2 and python 3 stacks
|
||||
|
||||
The python 2 and python 3 stacks are intended to be fully-installable in parallel. When generalizing the package for both python 2 and python 3, it is important to ensure that two different built packages do not attempt to place different payloads into the same path.
|
||||
|
||||
==== Executables in `/usr/bin`
|
||||
==== Executables in `+/usr/bin+`
|
||||
|
||||
Many existing python packages install executables into `/usr/bin`.
|
||||
Many existing python packages install executables into `+/usr/bin+`.
|
||||
|
||||
For example if we have a `console_scripts` in a `setup.py` shared between
|
||||
python 2 and python 3 builds: these will spit out files in `/usr/bin/`,
|
||||
For example if we have a `+console_scripts+` in a `+setup.py+` shared between
|
||||
python 2 and python 3 builds: these will spit out files in `+/usr/bin/+`,
|
||||
and these will collide.
|
||||
|
||||
For example `python-coverage` has a `setup.py` that contains:
|
||||
For example `+python-coverage+` has a `+setup.py+` that contains:
|
||||
|
||||
....
|
||||
entry_points = {
|
||||
|
|
@ -192,36 +192,36 @@ For example `python-coverage` has a `setup.py` that contains:
|
|||
},
|
||||
....
|
||||
|
||||
which thus generates a `/usr/bin/coverage` executable (this is a python
|
||||
which thus generates a `+/usr/bin/coverage+` executable (this is a python
|
||||
script that runs another python script whilst generating code-coverage
|
||||
information on the latter).
|
||||
|
||||
Similarly for the 'scripts' clause; see e.g. `python-pygments`:
|
||||
`Pygments-1.1.1/setup.py` has:
|
||||
Similarly for the 'scripts' clause; see e.g. `+python-pygments+`:
|
||||
`+Pygments-1.1.1/setup.py+` has:
|
||||
|
||||
....
|
||||
scripts = ['pygmentize'],
|
||||
....
|
||||
|
||||
which generates a `/usr/bin/pygmentize` (this is a python script that leverages the pygments syntax-highlighting module, giving a simple command-line interface for generating syntax-highlighted files)
|
||||
which generates a `+/usr/bin/pygmentize+` (this is a python script that leverages the pygments syntax-highlighting module, giving a simple command-line interface for generating syntax-highlighted files)
|
||||
|
||||
If the executables provide the same functionality independent of whether they are run on top of Python 2 or Python 3, then only the Python 3 version of the executable SHOULD be packaged, the python2 version MUST NOT be packaged.
|
||||
|
||||
Examples of this:
|
||||
|
||||
* `/usr/bin/pygmentize` ought to generate the same output regardless of whether it's implemented via Python 2 or Python 3, so only one version needs to be shipped.
|
||||
* `+/usr/bin/pygmentize+` ought to generate the same output regardless of whether it's implemented via Python 2 or Python 3, so only one version needs to be shipped.
|
||||
|
||||
If the executables provide different functionality for Python 2 and Python 3, then Python 2 version MAY be packaged.
|
||||
|
||||
Examples of this:
|
||||
|
||||
* `/usr/bin/coverage` runs a python script, augmenting the interpreter with code-coverage information. Given that the interpreter itself is the thing being worked with, it's reasonable to package both versions of the executable.
|
||||
* `/usr/bin/bpython` augments the interpreter with a "curses" interface. Again, it's reasonable to package both versions of this.
|
||||
* `/usr/bin/easy_install` installs a module into one of the Python runtimes: we need a version for each runtime.
|
||||
* `+/usr/bin/coverage+` runs a python script, augmenting the interpreter with code-coverage information. Given that the interpreter itself is the thing being worked with, it's reasonable to package both versions of the executable.
|
||||
* `+/usr/bin/bpython+` augments the interpreter with a "curses" interface. Again, it's reasonable to package both versions of this.
|
||||
* `+/usr/bin/easy_install+` installs a module into one of the Python runtimes: we need a version for each runtime.
|
||||
|
||||
==== Naming
|
||||
|
||||
Many executables already contain a "-MAJOR.MINOR" suffix, for example `/usr/bin/easy_install-3.4`. These obviously can be used as-is, as they won't conflict.
|
||||
Many executables already contain a "-MAJOR.MINOR" suffix, for example `+/usr/bin/easy_install-3.4+`. These obviously can be used as-is, as they won't conflict.
|
||||
|
||||
For other executables, the general rule is:
|
||||
|
||||
|
|
@ -229,66 +229,66 @@ For other executables, the general rule is:
|
|||
* If executables are to be shipped for both python 2 and python 3:
|
||||
** Both python 2 and python 3 variants must provide symlinks with a '-X' and '-X.Y' suffix (python runtime major version, or python runtime major.minor version), unless upstream already provides appropriately versioned executables without the dash.
|
||||
** The unversioned executable *should* be the python3 version, unless it would break users expectations, in that case it *may* be the python2 version.
|
||||
** For example, the python3 version of "twisted" *must* ship executables `/usr/bin/twistd-3` and `/usr/bin/twistd-3.7` (assuming python3 is currently version 3.7) and it *should* ship `/usr/bin/twistd`; while the python2 version *must* provide `/usr/bin/twistd-2` and `/usr/bin/coverage-2.7`.
|
||||
** As an example of the exception, users might except that the `ipython` command will run the same Python version as `python`.
|
||||
** For compatibility packages, the Python version is appended *after* the specific package version, for example `/usr/bin/coverage-v1.2-3` and `/usr/bin/coverage-v1.2-3.4` for python3-coverage1.2 compat package.
|
||||
** For example, the python3 version of "twisted" *must* ship executables `+/usr/bin/twistd-3+` and `+/usr/bin/twistd-3.7+` (assuming python3 is currently version 3.7) and it *should* ship `+/usr/bin/twistd+`; while the python2 version *must* provide `+/usr/bin/twistd-2+` and `+/usr/bin/coverage-2.7+`.
|
||||
** As an example of the exception, users might except that the `+ipython+` command will run the same Python version as `+python+`.
|
||||
** For compatibility packages, the Python version is appended *after* the specific package version, for example `+/usr/bin/coverage-v1.2-3+` and `+/usr/bin/coverage-v1.2-3.4+` for python3-coverage1.2 compat package.
|
||||
|
||||
=== Running 2to3 from the spec file
|
||||
|
||||
Sometimes, upstream hasn't integrated running 2to3 on the code into their build scripts but they support making a python3 module from it if you manually run 2to3 on the source. This is the case when it's documented on the upstream's website, in a file in the tarball, or even when email with the module's author has instructions for building a python3 module from the python2 source and the authors are willing to support the result. In these cases it's usually just a matter of the upstream not having written the build script that can turn the python2 source into python3. When this happens you can run `2to3` from the spec file. Once you have it working, you can also help upstream integrate it into their build scripts which will benefit everyone in the long term.
|
||||
Sometimes, upstream hasn't integrated running 2to3 on the code into their build scripts but they support making a python3 module from it if you manually run 2to3 on the source. This is the case when it's documented on the upstream's website, in a file in the tarball, or even when email with the module's author has instructions for building a python3 module from the python2 source and the authors are willing to support the result. In these cases it's usually just a matter of the upstream not having written the build script that can turn the python2 source into python3. When this happens you can run `+2to3+` from the spec file. Once you have it working, you can also help upstream integrate it into their build scripts which will benefit everyone in the long term.
|
||||
|
||||
You should usually follow upstream's directions on how to run `2to3` and build the python3 module in these cases but there's a few things you should check to make sure upstream is doing it correctly.
|
||||
You should usually follow upstream's directions on how to run `+2to3+` and build the python3 module in these cases but there's a few things you should check to make sure upstream is doing it correctly.
|
||||
|
||||
* Since the code is being built from a unified source, you need to copy the code to a new directory before invoking 2to3 just like the link:#Building_more_than_once[ building more than once] method.
|
||||
* If the `2to3` program is invoked instead of using the `lib2to3` library functions, make sure it's invoked with `--write --nobackups`. `--write` is needed to make `2to3` actually change the files. `--nobackups` avoids leaving `foo.py.bak` files in the module directories that then make it into the final package payload.
|
||||
* Be sure to run 2to3 on the correct directory. When you run `2to3` you need to run it on the whole tree. A common mistake here for distutils packages has been to run it on the directory below `setup.py`, missing the `setup.py` file itself. This leads to errors when `python3` tries to execute `setup.py`
|
||||
* If you need to run `2to3` to fix code, use `2to3` or `/usr/bin/2to3`. At the moment, this program is coming from the `python-tools` rpm. Using `2to3` means that you'll be using a name that is supported upstream and across distros rather than `/usr/bin/python3-2to3` which we have renamed in Fedora to avoid filesystem conflicts. This also makes it easier for us to test and eventually change from using the python2 `2to3` to the python3 `2to3`. We just need to change the python3 package to provide the `/usr/bin/2to3` program instead of python and all of our python packages will start using that version instead.
|
||||
* If `2to3` runs into a problem, please https://bugzilla.redhat.com/enter_bug.cgi?component=python&product=Fedora[file a Fedora bug]. Please try to isolate a minimal test case that reproduces the problem when doing so.
|
||||
* If the `+2to3+` program is invoked instead of using the `+lib2to3+` library functions, make sure it's invoked with `+--write --nobackups+`. `+--write+` is needed to make `+2to3+` actually change the files. `+--nobackups+` avoids leaving `+foo.py.bak+` files in the module directories that then make it into the final package payload.
|
||||
* Be sure to run 2to3 on the correct directory. When you run `+2to3+` you need to run it on the whole tree. A common mistake here for distutils packages has been to run it on the directory below `+setup.py+`, missing the `+setup.py+` file itself. This leads to errors when `+python3+` tries to execute `+setup.py+`
|
||||
* If you need to run `+2to3+` to fix code, use `+2to3+` or `+/usr/bin/2to3+`. At the moment, this program is coming from the `+python-tools+` rpm. Using `+2to3+` means that you'll be using a name that is supported upstream and across distros rather than `+/usr/bin/python3-2to3+` which we have renamed in Fedora to avoid filesystem conflicts. This also makes it easier for us to test and eventually change from using the python2 `+2to3+` to the python3 `+2to3+`. We just need to change the python3 package to provide the `+/usr/bin/2to3+` program instead of python and all of our python packages will start using that version instead.
|
||||
* If `+2to3+` runs into a problem, please https://bugzilla.redhat.com/enter_bug.cgi?component=python&product=Fedora[file a Fedora bug]. Please try to isolate a minimal test case that reproduces the problem when doing so.
|
||||
|
||||
== Manual byte compilation
|
||||
|
||||
When byte compiling a .py file, python embeds a magic number in the byte compiled files that correspond to the runtime. Files in `%{python?_sitelib}` and `%{python?_sitearch}` MUST correspond to the runtime for which they were built. For instance, a pure python module compiled for the 3.4 runtime MUST be below `%{_usr}/lib/python3.4/site-packages`
|
||||
When byte compiling a .py file, python embeds a magic number in the byte compiled files that correspond to the runtime. Files in `+%{python?_sitelib}+` and `+%{python?_sitearch}+` MUST correspond to the runtime for which they were built. For instance, a pure python module compiled for the 3.4 runtime MUST be below `+%{_usr}/lib/python3.4/site-packages+`
|
||||
|
||||
The `brp-python-bytecompile` script tries to figure this out for you. The script determines which interpreter to use when byte compiling the module by following these steps:
|
||||
The `+brp-python-bytecompile+` script tries to figure this out for you. The script determines which interpreter to use when byte compiling the module by following these steps:
|
||||
|
||||
1. What directory is the module installed in? If it's `/usr/lib{,64}/pythonX.Y`, then `pythonX.Y` is used to byte compile the module. If `pythonX.Y` is not installed, then an error is returned and the rpm build process will exit on an error so remember to `BuildRequire` the proper python package.
|
||||
2. By default the script interpreter defined in `%{__python}` is used to compile the modules outside of those directories. This defaults to `/usr/bin/python` (that's Python 2.7 on Fedora). This only happens for backwards compatibility reasons.
|
||||
1. What directory is the module installed in? If it's `+/usr/lib{,64}/pythonX.Y+`, then `+pythonX.Y+` is used to byte compile the module. If `+pythonX.Y+` is not installed, then an error is returned and the rpm build process will exit on an error so remember to `+BuildRequire+` the proper python package.
|
||||
2. By default the script interpreter defined in `+%{__python}+` is used to compile the modules outside of those directories. This defaults to `+/usr/bin/python+` (that's Python 2.7 on Fedora). This only happens for backwards compatibility reasons.
|
||||
|
||||
If you have `*.py` files outside of the `/usr/lib(64)?/pythonX.Y/` directories, you *MUST* disable their automatic compilation. If you require those files to be byte compiled (e.g. it's an importable Python module) you can then compile them explicitly using the `%py_byte_compile` macro.
|
||||
If you have `+*.py+` files outside of the `+/usr/lib(64)?/pythonX.Y/+` directories, you *MUST* disable their automatic compilation. If you require those files to be byte compiled (e.g. it's an importable Python module) you can then compile them explicitly using the `+%py_byte_compile+` macro.
|
||||
|
||||
Example for package that has both Python versions:
|
||||
|
||||
`# Disable automatic compilation of Python files in extra directories` +
|
||||
`%global _python_bytecompile_extra 0` +
|
||||
`+# Disable automatic compilation of Python files in extra directories+` +
|
||||
`+%global _python_bytecompile_extra 0+` +
|
||||
+
|
||||
`# Buildrequire both python2 and python3` +
|
||||
`BuildRequires: python2-devel python3-devel` +
|
||||
`+# Buildrequire both python2 and python3+` +
|
||||
`+BuildRequires: python2-devel python3-devel+` +
|
||||
+
|
||||
`%install` +
|
||||
`# Installs a python2 private module into %{buildroot}%{_datadir}/mypackage/foo` +
|
||||
`# and installs a python3 private module into %{buildroot}%{_datadir}/mypackage/bar` +
|
||||
`make install DESTDIR=%{buildroot}` +
|
||||
`+%install+` +
|
||||
`+# Installs a python2 private module into %{buildroot}%{_datadir}/mypackage/foo+` +
|
||||
`+# and installs a python3 private module into %{buildroot}%{_datadir}/mypackage/bar+` +
|
||||
`+make install DESTDIR=%{buildroot}+` +
|
||||
+
|
||||
`# Manually invoke the python byte compile macro for each path that needs byte` +
|
||||
`# compilation.` +
|
||||
`%py_byte_compile %{__python2} %{buildroot}%{_datadir}/mypackage/foo` +
|
||||
`%py_byte_compile %{__python3} %{buildroot}%{_datadir}/mypackage/bar`
|
||||
`+# Manually invoke the python byte compile macro for each path that needs byte+` +
|
||||
`+# compilation.+` +
|
||||
`+%py_byte_compile %{__python2} %{buildroot}%{_datadir}/mypackage/foo+` +
|
||||
`+%py_byte_compile %{__python3} %{buildroot}%{_datadir}/mypackage/bar+`
|
||||
|
||||
Note that this *does not* disable the compilation of files in `/usr/lib(64)?/pythonX.Y/`.
|
||||
Note that this *does not* disable the compilation of files in `+/usr/lib(64)?/pythonX.Y/+`.
|
||||
|
||||
The `%py_byte_compile` macro takes two arguments. The first is the python interpreter to use for byte compiling. The second is a file or directory to byte compile. If the second argument is a directory, the macro will recursively byte compile any *.py file in the directory.
|
||||
The `+%py_byte_compile+` macro takes two arguments. The first is the python interpreter to use for byte compiling. The second is a file or directory to byte compile. If the second argument is a directory, the macro will recursively byte compile any *.py file in the directory.
|
||||
|
||||
== Manual byte compilation for Fedora 28 or earlier (including EPEL)
|
||||
|
||||
The script interpreter defined in `%{__python}` is used to compile the modules outside of `/usr/lib(64)?/pythonX.Y/` directories. This defaults to `/usr/bin/python` (that's Python 2.7 on Fedora). If you need to compile the modules for python3, set it to `/usr/bin/python3` instead:
|
||||
The script interpreter defined in `+%{__python}+` is used to compile the modules outside of `+/usr/lib(64)?/pythonX.Y/+` directories. This defaults to `+/usr/bin/python+` (that's Python 2.7 on Fedora). If you need to compile the modules for python3, set it to `+/usr/bin/python3+` instead:
|
||||
|
||||
....
|
||||
%global __python %{__python3}
|
||||
....
|
||||
|
||||
Doing this is useful when you have a python3 application that's installing a private module into its own directory. For instance, if the foobar application installs a module for use only by the command line application in `%{_datadir}/foobar`. Since these files are not in one of the python3 library paths (ie. `/usr/lib/python3.1`) you have to override `%{__python}` to tell `brp-python-bytecompile` to use the python3 interpreter for byte compiling.
|
||||
Doing this is useful when you have a python3 application that's installing a private module into its own directory. For instance, if the foobar application installs a module for use only by the command line application in `+%{_datadir}/foobar+`. Since these files are not in one of the python3 library paths (ie. `+/usr/lib/python3.1+`) you have to override `+%{__python}+` to tell `+brp-python-bytecompile+` to use the python3 interpreter for byte compiling.
|
||||
|
||||
These settings are enough to properly byte compile any package that builds python modules in `%{python?_sitelib}` or `%{python?_sitearch}` or builds for only a single python interpreter. However, if the application you're packaging needs to build with both python2 and python3 and install into a private module directory (perhaps because it provides one utility written in python2 and a second utility written in python3) then you need to do this manually. Here's a sample spec file snippet that shows what to do:
|
||||
These settings are enough to properly byte compile any package that builds python modules in `+%{python?_sitelib}+` or `+%{python?_sitearch}+` or builds for only a single python interpreter. However, if the application you're packaging needs to build with both python2 and python3 and install into a private module directory (perhaps because it provides one utility written in python2 and a second utility written in python3) then you need to do this manually. Here's a sample spec file snippet that shows what to do:
|
||||
|
||||
....
|
||||
# Turn off the brp-python-bytecompile script
|
||||
|
|
@ -308,9 +308,9 @@ make install DESTDIR=%{buildroot}
|
|||
%py_byte_compile %{__python3} %{buildroot}%{_datadir}/mypackage/bar
|
||||
....
|
||||
|
||||
Note that this *does disable* the compilation of files in `/usr/lib(64)?/pythonX.Y/`.
|
||||
Note that this *does disable* the compilation of files in `+/usr/lib(64)?/pythonX.Y/+`.
|
||||
|
||||
In Fedora 27 or earlier, use `%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile`:space:[`:space:`]`.*$!!g')`
|
||||
instead of the `%undefine` line above.
|
||||
In Fedora 27 or earlier, use `+%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile+`:space:[`+:space:+`]`+.*$!!g')+`
|
||||
instead of the `+%undefine+` line above.
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines] Category:Python
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ It is highly recommended that any such compatibility packages install a README.f
|
|||
|
||||
There are several other methods of invoking scripts so that they might take the right version but they suffer from various problems. They are listed here because a program you're packaging may use them and you need to know about them if they break. If you mention them in README.fedora, please also add why they are dangerous to use.
|
||||
|
||||
* `pkg_resources.requires('MODULE[VERSIONINFO] ')`: Does not work with a default version (able to be imported via import MODULE). The setuptools author refuses to remove this limitation and refuses to document that it is a limitation. Therefore you may run across scripts that use this method and need to patch them to use one of the above, supported methods instead.
|
||||
* `__requires__='MODULE[VERSIONINFO] '`: This works but the setuptools author feels that it is only a workaround and will not support it. It works presently but could stop in a future version of setuptools. Some upstreams use this method and may need to be fixed if the setuptools author ever changes the interface.
|
||||
* `+pkg_resources.requires('MODULE[VERSIONINFO] ')+`: Does not work with a default version (able to be imported via import MODULE). The setuptools author refuses to remove this limitation and refuses to document that it is a limitation. Therefore you may run across scripts that use this method and need to patch them to use one of the above, supported methods instead.
|
||||
* `+__requires__='MODULE[VERSIONINFO] '+`: This works but the setuptools author feels that it is only a workaround and will not support it. It works presently but could stop in a future version of setuptools. Some upstreams use this method and may need to be fixed if the setuptools author ever changes the interface.
|
||||
|
||||
== Egg "Features" to avoid
|
||||
|
||||
|
|
|
|||
|
|
@ -8,16 +8,16 @@ In Fedora we have multiple python runtimes, one for each supported major release
|
|||
|
||||
== Multiple Python Runtimes
|
||||
|
||||
Each runtime corresponds to a binary of the form `/usr/bin/python$MAJOR.$MINOR` One of these python runtimes is the "system runtime" which is what is run when invoking `/usr/bin/python`. On Fedora 21 this is a link to `/usr/bin/python2` (which itself is a link to `/usr/bin/python2.7`).
|
||||
Each runtime corresponds to a binary of the form `+/usr/bin/python$MAJOR.$MINOR+` One of these python runtimes is the "system runtime" which is what is run when invoking `+/usr/bin/python+`. On Fedora 21 this is a link to `+/usr/bin/python2+` (which itself is a link to `+/usr/bin/python2.7+`).
|
||||
|
||||
However, packages in Fedora should not depend on where `/usr/bin/python` happens to point but instead should call the proper executable for the needed python major version directly, either `/usr/bin/python2` or `/usr/bin/python3` as appropriate.
|
||||
However, packages in Fedora should not depend on where `+/usr/bin/python+` happens to point but instead should call the proper executable for the needed python major version directly, either `+/usr/bin/python2+` or `+/usr/bin/python3+` as appropriate.
|
||||
|
||||
All python runtimes have a virtual provide for `python(abi) = $MAJOR-$MINOR`. For example, the python-3.1 runtime rpm has:
|
||||
All python runtimes have a virtual provide for `+python(abi) = $MAJOR-$MINOR+`. For example, the python-3.1 runtime rpm has:
|
||||
|
||||
` $ rpm -q --provides python3 |grep -i abi` +
|
||||
` python(abi) = 3.1`
|
||||
`+ $ rpm -q --provides python3 |grep -i abi+` +
|
||||
`+ python(abi) = 3.1+`
|
||||
|
||||
python modules using these runtimes should have a corresponding "Requires" line on the python runtime that they are used with. This is done automatically for files below `/usr/lib[^/]*/python${PYVER}`
|
||||
python modules using these runtimes should have a corresponding "Requires" line on the python runtime that they are used with. This is done automatically for files below `+/usr/lib[^/]*/python${PYVER}+`
|
||||
|
||||
== BuildRequires
|
||||
|
||||
|
|
@ -37,11 +37,11 @@ A package that has both python2 and python3 files will need to BuildRequire both
|
|||
|
||||
== Provides
|
||||
|
||||
Python2 packages need to provide a python2 version of their name. So, for example, a python package of the "foo" module needs to include `Provides: python2-foo`.
|
||||
Python2 packages need to provide a python2 version of their name. So, for example, a python package of the "foo" module needs to include `+Provides: python2-foo+`.
|
||||
|
||||
== Macros
|
||||
|
||||
In RHEL 6 and older, python2 packages that install python modules need to define `__python2`, `python2_sitelib`, and `python2_sitearch` macros. This is not needed in current Fedora or with python3 modules as the macros are defined by `rpm` and the `python3-devel` package. To define those conditionally you can use this:
|
||||
In RHEL 6 and older, python2 packages that install python modules need to define `+__python2+`, `+python2_sitelib+`, and `+python2_sitearch+` macros. This is not needed in current Fedora or with python3 modules as the macros are defined by `+rpm+` and the `+python3-devel+` package. To define those conditionally you can use this:
|
||||
|
||||
....
|
||||
%if 0%{?rhel} && 0%{?rhel} <= 6
|
||||
|
|
@ -51,18 +51,18 @@ In RHEL 6 and older, python2 packages that install python modules need to define
|
|||
%endif
|
||||
....
|
||||
|
||||
Note that the use of `%{!? [...]}` does allow this to work without the check for rhel versions but putting the conditional in documents when we can remove the entire stanza from the spec file.
|
||||
Note that the use of `+%{!? [...]}+` does allow this to work without the check for rhel versions but putting the conditional in documents when we can remove the entire stanza from the spec file.
|
||||
|
||||
In Fedora, the following macros are defined for you:
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|====================================================================================================================================================================================================================
|
||||
|Macro |Normal Definition |Notes
|
||||
|__python |`%{__python2}` |Default Python interpreter. Currently links to Python2 interpreter
|
||||
|__python |`+%{__python2}+` |Default Python interpreter. Currently links to Python2 interpreter
|
||||
|__python2 |/usr/bin/python2 |Python 2 interpreter. Also the current default python interpreter
|
||||
|__python3 |/usr/bin/python3 |Python 3 interpreter
|
||||
|python_sitelib |`%{python2_sitelib}` |Where pure python modules are installed for the default Python implementation
|
||||
|python_sitearch |`%{python2_sitearch}` |Where python extension modules that are compiled C are installed for the default Python implementation
|
||||
|python_sitelib |`+%{python2_sitelib}+` |Where pure python modules are installed for the default Python implementation
|
||||
|python_sitearch |`+%{python2_sitearch}+` |Where python extension modules that are compiled C are installed for the default Python implementation
|
||||
|python2_sitelib |/usr/lib/python2.X/site-packages |Where pure python2 modules are installed
|
||||
|python2_sitearch |/usr/lib64/python2.X/site-packages on x86_64 +
|
||||
/usr/lib/python2.X/site-packages on x86 |Where python2 extension modules that are compiled C are installed
|
||||
|
|
@ -74,7 +74,7 @@ In Fedora, the following macros are defined for you:
|
|||
|python3_version_nodots |3X |Defined in python3-devel since Fedora 21 / Python 3.4. Useful when listing files explicitly in %files section , such as %\{python3_sitelib}/foo/*.cpython-%\{python3_version_nodots}.pyo
|
||||
|====================================================================================================================================================================================================================
|
||||
|
||||
During `%install` or when listing `%files` you can use the `python2_sitearch` and `python2_sitelib` macros to specify where the installed modules are to be found. For instance:
|
||||
During `+%install+` or when listing `+%files+` you can use the `+python2_sitearch+` and `+python2_sitelib+` macros to specify where the installed modules are to be found. For instance:
|
||||
|
||||
....
|
||||
%files
|
||||
|
|
@ -89,7 +89,7 @@ During `%install` or when listing `%files` you can use the `python2_sitearch` an
|
|||
Using the macros has several benefits.
|
||||
|
||||
1. It ensures that the packages are installed correctly on multilib architectures.
|
||||
2. Using these macros instead of hardcoding the directory in the specfile ensures your spec remains compatible with the installed python version even if the directory structure changes radically (for instance, if `python2_sitelib` moves into `%{_datadir}`)
|
||||
2. Using these macros instead of hardcoding the directory in the specfile ensures your spec remains compatible with the installed python version even if the directory structure changes radically (for instance, if `+python2_sitelib+` moves into `+%{_datadir}+`)
|
||||
|
||||
== Files to include
|
||||
|
||||
|
|
@ -110,13 +110,13 @@ versions of them.
|
|||
|
||||
== Byte compiling
|
||||
|
||||
Python will automatically try to byte compile files when it runs in order to speed up startup the next time it is run. These files are saved in files with the extension of .pyc (compiled python) or .pyo (optimized compiled python). With current versions of python 3, these files will be located inside a directory named `__pycache__`. Older versions of python will simply place them alongside the .py files.
|
||||
Python will automatically try to byte compile files when it runs in order to speed up startup the next time it is run. These files are saved in files with the extension of .pyc (compiled python) or .pyo (optimized compiled python). With current versions of python 3, these files will be located inside a directory named `+__pycache__+`. Older versions of python will simply place them alongside the .py files.
|
||||
|
||||
The .pyc and .pyo files contain byte code that is portable across OSes. If you do not include them in your packages, python will try (and generally fail) to create them when the user runs the program. If the system administrator runs the program, then the files will be successfully written, causing stray .pyc and .pyo files which will not be removed when the package is removed. To prevent that the byte compiled files need to be compiled and included in the `%files` section. Normally, byte compilation is done for you by the `brp-python-bytecompile` script. This script runs after the `%install` section of the spec file has been processed and byte compiles any .py files that it finds (this recompilation puts the proper filesystem paths into the modules otherwise tracebacks would include the `%{buildroot}` in them).
|
||||
The .pyc and .pyo files contain byte code that is portable across OSes. If you do not include them in your packages, python will try (and generally fail) to create them when the user runs the program. If the system administrator runs the program, then the files will be successfully written, causing stray .pyc and .pyo files which will not be removed when the package is removed. To prevent that the byte compiled files need to be compiled and included in the `+%files+` section. Normally, byte compilation is done for you by the `+brp-python-bytecompile+` script. This script runs after the `+%install+` section of the spec file has been processed and byte compiles any .py files that it finds (this recompilation puts the proper filesystem paths into the modules otherwise tracebacks would include the `+%{buildroot}+` in them).
|
||||
|
||||
You must include in your package the .pyc and .pyo files. If the build process creates a __pycache__ directory in a subdirectory of %\{python3_sitearch} or %\{python3_sitelib}, you must also include all items in the __pycache__ directory. (You should not include the directories %\{python3_sitearch}/__pycache__ or %\{python3_sitelib}/__pycache__ because they are already owned by the python3-libs package.)
|
||||
|
||||
All that you need to do is include the files in the `%files` section (replacing %\{python3_sitelib} with the appropriate macro for your package):
|
||||
All that you need to do is include the files in the `+%files+` section (replacing %\{python3_sitelib} with the appropriate macro for your package):
|
||||
|
||||
....
|
||||
%files
|
||||
|
|
@ -133,26 +133,26 @@ or, if the python code installs directly into %\{python3_sitelib}:
|
|||
|
||||
=== Optimization
|
||||
|
||||
Fedora packages running with python < 3.5 (including any version of python 2) *must not* invoke python with the `-OO` option or set the environment variable `PYTHONOPTIMIZE` to 2 or greater. (Using -O or `PYTHONOPTIMIZE` less than 2 is fine, though unnecesary.)
|
||||
Fedora packages running with python < 3.5 (including any version of python 2) *must not* invoke python with the `+-OO+` option or set the environment variable `+PYTHONOPTIMIZE+` to 2 or greater. (Using -O or `+PYTHONOPTIMIZE+` less than 2 is fine, though unnecesary.)
|
||||
|
||||
Similarly, any `.pyo` shipped in a Fedora package for python < 3.5 *must no* have been byte compiled using optimization level 2 or higher.
|
||||
Similarly, any `+.pyo+` shipped in a Fedora package for python < 3.5 *must no* have been byte compiled using optimization level 2 or higher.
|
||||
|
||||
=== Bytecompiling with the correct python version
|
||||
|
||||
When byte compiling a .py file, python embeds a magic number in the byte compiled files that correspond to the runtime. Files in `%{python?_sitelib}` and `%{python?_sitearch}` must correspond to the runtime for which they were built. For instance, a pure python module compiled for the 3.1 runtime needs to be below `%{_usr}/lib/python3.1/site-packages`
|
||||
When byte compiling a .py file, python embeds a magic number in the byte compiled files that correspond to the runtime. Files in `+%{python?_sitelib}+` and `+%{python?_sitearch}+` must correspond to the runtime for which they were built. For instance, a pure python module compiled for the 3.1 runtime needs to be below `+%{_usr}/lib/python3.1/site-packages+`
|
||||
|
||||
The `brp-python-bytecompile` script tries to figure this out for you. The script determines which interpreter to use when byte compiling the module by following these steps:
|
||||
The `+brp-python-bytecompile+` script tries to figure this out for you. The script determines which interpreter to use when byte compiling the module by following these steps:
|
||||
|
||||
1. what directory is the module installed in? If it's `/usr/lib{,64}/pythonX.Y`, then `pythonX.Y` is used to byte compile the module. If `pythonX.Y` is not installed, then an error is returned and the rpm build process will exit on an error so remember to `BuildRequire` the proper python package.
|
||||
2. the script interpreter defined in `%{__python}` is used to compile the modules. This defaults to the latest python2 version on Fedora. If you need to compile this module for python3, set it to `/usr/bin/python3` instead:
|
||||
1. what directory is the module installed in? If it's `+/usr/lib{,64}/pythonX.Y+`, then `+pythonX.Y+` is used to byte compile the module. If `+pythonX.Y+` is not installed, then an error is returned and the rpm build process will exit on an error so remember to `+BuildRequire+` the proper python package.
|
||||
2. the script interpreter defined in `+%{__python}+` is used to compile the modules. This defaults to the latest python2 version on Fedora. If you need to compile this module for python3, set it to `+/usr/bin/python3+` instead:
|
||||
+
|
||||
....
|
||||
%global __python %{__python3}
|
||||
....
|
||||
+
|
||||
Doing this is useful when you have a python3 application that's installing a private module into its own directory. For instance, if the foobar application installs a module for use only by the command line application in `%{_datadir}/foobar`. Since these files are not in one of the python3 library paths (ie. `/usr/lib/python3.1`) you have to override `%{__python}` to tell `brp-python-bytecompile` to use the python3 interpreter for byte compiling.
|
||||
Doing this is useful when you have a python3 application that's installing a private module into its own directory. For instance, if the foobar application installs a module for use only by the command line application in `+%{_datadir}/foobar+`. Since these files are not in one of the python3 library paths (ie. `+/usr/lib/python3.1+`) you have to override `+%{__python}+` to tell `+brp-python-bytecompile+` to use the python3 interpreter for byte compiling.
|
||||
|
||||
These settings are enough to properly byte compile any package that builds python modules in `%{python?_sitelib}` or `%{python?_sitearch}` or builds for only a single python interpreter. However, if the application you're packaging needs to build with both python2 and python3 and install into a private module directory (perhaps because it provides one utility written in python2 and a second utility written in python3) then you need to do this manually. Here's a sample spec file snippet that shows what to do:
|
||||
These settings are enough to properly byte compile any package that builds python modules in `+%{python?_sitelib}+` or `+%{python?_sitearch}+` or builds for only a single python interpreter. However, if the application you're packaging needs to build with both python2 and python3 and install into a private module directory (perhaps because it provides one utility written in python2 and a second utility written in python3) then you need to do this manually. Here's a sample spec file snippet that shows what to do:
|
||||
|
||||
....
|
||||
# Turn off the brp-python-bytecompile script
|
||||
|
|
@ -172,11 +172,11 @@ make install DESTDIR=%{buildroot}
|
|||
%py_byte_compile %{__python3} %{buildroot}%{_datadir}/mypackage/bar
|
||||
....
|
||||
|
||||
The `%py_byte_compile` macro takes two arguments. The first is the python interpreter to use for byte compiling. The second is a file or directory to byte compile. If the second argument is a directory, the macro will recursively byte compile any *.py file in the directory.
|
||||
The `+%py_byte_compile+` macro takes two arguments. The first is the python interpreter to use for byte compiling. The second is a file or directory to byte compile. If the second argument is a directory, the macro will recursively byte compile any *.py file in the directory.
|
||||
|
||||
== Common SRPM vs split SRPMs
|
||||
|
||||
Many times when you package a python module you will want to create a module for python2 and a module for python3. There are two ways of doing this: either from a single SRPM or from multiple. The rule to choose which method is simple: if the python2 and python3 modules are distributed as a single tarball (many times as a single directory of source where the `/usr/bin/2to3` program is used to transform the code at buildtime) then you must package them as subpackages built from a single SRPM. If they come in multiple tarballs then package them from multiple SRPMs.
|
||||
Many times when you package a python module you will want to create a module for python2 and a module for python3. There are two ways of doing this: either from a single SRPM or from multiple. The rule to choose which method is simple: if the python2 and python3 modules are distributed as a single tarball (many times as a single directory of source where the `+/usr/bin/2to3+` program is used to transform the code at buildtime) then you must package them as subpackages built from a single SRPM. If they come in multiple tarballs then package them from multiple SRPMs.
|
||||
|
||||
=== Multiple SRPMS
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ The following practices are designed to help mitigate the disadvantages listed a
|
|||
|
||||
=== Subpackages
|
||||
|
||||
Sometimes upstream will ship one tarball that builds both a python2 and a python3 module. There's several ways that upstream can structure this. When upstream writes their build scripts to build both python2 and python3 modules in a single build this is just like building subpackages for any other package. You expand the tarball and patch the source in `%prep`, run upstream's build scripts to build the package in `%build`, and then run upstream's build scripts to install it in `%install`.
|
||||
Sometimes upstream will ship one tarball that builds both a python2 and a python3 module. There's several ways that upstream can structure this. When upstream writes their build scripts to build both python2 and python3 modules in a single build this is just like building subpackages for any other package. You expand the tarball and patch the source in `+%prep+`, run upstream's build scripts to build the package in `+%build+`, and then run upstream's build scripts to install it in `+%install+`.
|
||||
|
||||
*Advantages*:
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ One way that's currently very common is for the build scripts to create either a
|
|||
%global srcname distribute
|
||||
....
|
||||
|
||||
At the top of our spec file we have the standard define for `python2_sitelib` on older RHEL releases. We also define `with_python3` which we'll use to conditionalize the build whenever we have a section that is only useful when building a python3 module. Using `with_python3` allows us to do two things:
|
||||
At the top of our spec file we have the standard define for `+python2_sitelib+` on older RHEL releases. We also define `+with_python3+` which we'll use to conditionalize the build whenever we have a section that is only useful when building a python3 module. Using `+with_python3+` allows us to do two things:
|
||||
|
||||
1. It makes it easy to turn off the python3 build when tracking down problems.
|
||||
2. The conditionals also make it easy to use the same spec for older releases of Fedora and EPEL.
|
||||
|
|
@ -261,7 +261,7 @@ BuildRequires: python3-devel
|
|||
Provides: python2-setuptools
|
||||
....
|
||||
|
||||
When we build the python3 module in addition to the python2 module we need both `python2-devel` and `python3-devel`.
|
||||
When we build the python3 module in addition to the python2 module we need both `+python2-devel+` and `+python3-devel+`.
|
||||
|
||||
....
|
||||
%description
|
||||
|
|
@ -287,7 +287,7 @@ execute the software that requires pkg_resources.py.
|
|||
%endif # with_python3
|
||||
....
|
||||
|
||||
Here we define the python3 subpackage. Note that we use `%package -n` to name the module appropriately.
|
||||
Here we define the python3 subpackage. Note that we use `+%package -n+` to name the module appropriately.
|
||||
|
||||
....
|
||||
%prep
|
||||
|
|
@ -309,12 +309,12 @@ find python3 -name '*.py' | xargs sed -i '1s|^#!python|#!%{__python3}|'
|
|||
find python2 -name '*.py' | xargs sed -i '1s|^#!python|#!%{__python2}|'
|
||||
....
|
||||
|
||||
Our method in building from the same code to make the two separate modules is to keep each build as independent as possible. To do that, we copy the source tree to `python3` so that the python 2 sources are entirely independent from the python 3 sources. Some things to watch out for:
|
||||
Our method in building from the same code to make the two separate modules is to keep each build as independent as possible. To do that, we copy the source tree to `+python3+` so that the python 2 sources are entirely independent from the python 3 sources. Some things to watch out for:
|
||||
|
||||
* Make sure that you are copying the correct code. The example is copying the code from within the top directory of the untarred source. If the `%prep` has changed directory you will need to change back to the tarball location.
|
||||
* Patching the source code is done before copying to `python3`. Since you have both a python2 and a python3 directory you might be tempted to patch each one separately. *Resist!* Upstream for your package has chosen to distribute a single source tree that builds for both python2 and python3. For your patches to link:Staying_close_to_upstream_projects[ get into upstream], you need to write patches that work with both as well.}}
|
||||
* Make sure that you are copying the correct code. The example is copying the code from within the top directory of the untarred source. If the `+%prep+` has changed directory you will need to change back to the tarball location.
|
||||
* Patching the source code is done before copying to `+python3+`. Since you have both a python2 and a python3 directory you might be tempted to patch each one separately. *Resist!* Upstream for your package has chosen to distribute a single source tree that builds for both python2 and python3. For your patches to link:Staying_close_to_upstream_projects[ get into upstream], you need to write patches that work with both as well.}}
|
||||
|
||||
`rpmbuild` resets the directory at the end of each phase, so you don't need to restore the directory at the end of `%prep`.
|
||||
`+rpmbuild+` resets the directory at the end of each phase, so you don't need to restore the directory at the end of `+%prep+`.
|
||||
|
||||
....
|
||||
%build
|
||||
|
|
@ -364,11 +364,11 @@ popd
|
|||
%endif # with_python3
|
||||
....
|
||||
|
||||
You'll notice that the `%build`, `%install`, and `%check` sections follow a common pattern. They do the normal steps for building the python2 module but then they switch to `python3` and run the same steps for python3. Creating the new sections is generally pretty easy. First copy the existing code. Then wrap it with a `pushd/popd` to `python3`. The usage of `pushd/popd` commands will ensure that the directories are logged. Finally, convert all macro references:
|
||||
You'll notice that the `+%build+`, `+%install+`, and `+%check+` sections follow a common pattern. They do the normal steps for building the python2 module but then they switch to `+python3+` and run the same steps for python3. Creating the new sections is generally pretty easy. First copy the existing code. Then wrap it with a `+pushd/popd+` to `+python3+`. The usage of `+pushd/popd+` commands will ensure that the directories are logged. Finally, convert all macro references:
|
||||
|
||||
* `%{__python2}` becomes `%{__python3}`
|
||||
* `%{python2_sitelib}` becomes `%{python3_sitelib}`
|
||||
* `%{python2_sitearch}` becomes `%{python3_sitearch}`
|
||||
* `+%{__python2}+` becomes `+%{__python3}+`
|
||||
* `+%{python2_sitelib}+` becomes `+%{python3_sitelib}+`
|
||||
* `+%{python2_sitearch}+` becomes `+%{python3_sitearch}+`
|
||||
|
||||
....
|
||||
%files
|
||||
|
|
@ -389,35 +389,35 @@ You'll notice that the `%build`, `%install`, and `%check` sections follow a comm
|
|||
%changelog
|
||||
....
|
||||
|
||||
In this final section, you can see that we once again switch macros from `%{python2_sitelib}` to `%{python3_sitelib}`. Since we chose to install the python2 version of `%{_bindir}/easy_install` earlier we need to include that file in the python2 package rather than the python3 subpackage.
|
||||
In this final section, you can see that we once again switch macros from `+%{python2_sitelib}+` to `+%{python3_sitelib}+`. Since we chose to install the python2 version of `+%{_bindir}/easy_install+` earlier we need to include that file in the python2 package rather than the python3 subpackage.
|
||||
|
||||
==== Running 2to3 from the spec file
|
||||
|
||||
Sometimes, upstream hasn't integrated running 2to3 on the code into their build scripts but they support making a python3 module from it if you manually run 2to3 on the source. This is the case when it's documented on the upstream's website, in a file in the tarball, or even when email with the module's author has instructions for building a python3 module from the python2 source and the authors are willing to support the result. In these cases it's usually just a matter of the upstream not having written the build script that can turn the python2 source into python3. When this happens you can run `2to3` from the spec file. Once you have it working, you can also help upstream integrate it into their build scripts which will benefit everyone in the long term.
|
||||
Sometimes, upstream hasn't integrated running 2to3 on the code into their build scripts but they support making a python3 module from it if you manually run 2to3 on the source. This is the case when it's documented on the upstream's website, in a file in the tarball, or even when email with the module's author has instructions for building a python3 module from the python2 source and the authors are willing to support the result. In these cases it's usually just a matter of the upstream not having written the build script that can turn the python2 source into python3. When this happens you can run `+2to3+` from the spec file. Once you have it working, you can also help upstream integrate it into their build scripts which will benefit everyone in the long term.
|
||||
|
||||
You should usually follow upstream's directions on how to run `2to3` and build the python3 module in these cases but there's a few things you should check to make sure upstream is doing it correctly.
|
||||
You should usually follow upstream's directions on how to run `+2to3+` and build the python3 module in these cases but there's a few things you should check to make sure upstream is doing it correctly.
|
||||
|
||||
* Since the code is being built from a unified source, you need to copy the code to a new directory before invoking 2to3 just like the link:#Building_more_than_once[ building more than once] method.
|
||||
* If the `2to3` program is invoked instead of using the `lib2to3` library functions, make sure it's invoked with `--write --nobackups`. `--write` is needed to make `2to3` actually change the files. `--nobackups` avoids leaving `foo.py.bak` files in the module directories that then make it into the final package payload.
|
||||
* Be sure to run 2to3 on the correct directory. When you run `2to3` you need to run it on the whole tree. A common mistake here for distutils packages has been to run it on the directory below `setup.py`, missing the `setup.py` file itself. This leads to errors when `python3` tries to execute `setup.py`
|
||||
* If you need to run `2to3` to fix code, use `2to3` or `/usr/bin/2to3`. At the moment, this program is coming from the `python-tools` rpm. Using `2to3` means that you'll be using a name that is supported upstream and across distros rather than `/usr/bin/python3-2to3` which we have renamed in Fedora to avoid filesystem conflicts. This also makes it easier for us to test and eventually change from using the python2 `2to3` to the python3 `2to3`. We just need to change the python3 package to provide the `/usr/bin/2to3` program instead of python and all of our python packages will start using that version instead.
|
||||
* If `2to3` runs into a problem, please https://bugzilla.redhat.com/enter_bug.cgi?component=python&product=Fedora[file a Fedora bug]. Please try to isolate a minimal test case that reproduces the problem when doing so.
|
||||
* If the `+2to3+` program is invoked instead of using the `+lib2to3+` library functions, make sure it's invoked with `+--write --nobackups+`. `+--write+` is needed to make `+2to3+` actually change the files. `+--nobackups+` avoids leaving `+foo.py.bak+` files in the module directories that then make it into the final package payload.
|
||||
* Be sure to run 2to3 on the correct directory. When you run `+2to3+` you need to run it on the whole tree. A common mistake here for distutils packages has been to run it on the directory below `+setup.py+`, missing the `+setup.py+` file itself. This leads to errors when `+python3+` tries to execute `+setup.py+`
|
||||
* If you need to run `+2to3+` to fix code, use `+2to3+` or `+/usr/bin/2to3+`. At the moment, this program is coming from the `+python-tools+` rpm. Using `+2to3+` means that you'll be using a name that is supported upstream and across distros rather than `+/usr/bin/python3-2to3+` which we have renamed in Fedora to avoid filesystem conflicts. This also makes it easier for us to test and eventually change from using the python2 `+2to3+` to the python3 `+2to3+`. We just need to change the python3 package to provide the `+/usr/bin/2to3+` program instead of python and all of our python packages will start using that version instead.
|
||||
* If `+2to3+` runs into a problem, please https://bugzilla.redhat.com/enter_bug.cgi?component=python&product=Fedora[file a Fedora bug]. Please try to isolate a minimal test case that reproduces the problem when doing so.
|
||||
|
||||
== Avoiding collisions between the python 2 and python 3 stacks
|
||||
|
||||
The python 2 and python 3 stacks are intended to be fully-installable in parallel. When generalizing the package for both python 2 and python 3, it is important to ensure that two different built packages do not attempt to place different payloads into the same path.
|
||||
|
||||
=== Executables in `/usr/bin`
|
||||
=== Executables in `+/usr/bin+`
|
||||
|
||||
==== The problem
|
||||
|
||||
Many existing python packages install executables into `/usr/bin`.
|
||||
Many existing python packages install executables into `+/usr/bin+`.
|
||||
|
||||
For example if we have a `console_scripts` in a `setup.py` shared between
|
||||
python 2 and python 3 builds: these will spit out files in `/usr/bin/`,
|
||||
For example if we have a `+console_scripts+` in a `+setup.py+` shared between
|
||||
python 2 and python 3 builds: these will spit out files in `+/usr/bin/+`,
|
||||
and these will collide.
|
||||
|
||||
For example `python-coverage` has a `setup.py` that contains:
|
||||
For example `+python-coverage+` has a `+setup.py+` that contains:
|
||||
|
||||
....
|
||||
entry_points = {
|
||||
|
|
@ -427,18 +427,18 @@ For example `python-coverage` has a `setup.py` that contains:
|
|||
},
|
||||
....
|
||||
|
||||
which thus generates a `/usr/bin/coverage` executable (this is a python
|
||||
which thus generates a `+/usr/bin/coverage+` executable (this is a python
|
||||
script that runs another python script whilst generating code-coverage
|
||||
information on the latter).
|
||||
|
||||
Similarly for the 'scripts' clause; see e.g. `python-pygments`:
|
||||
`Pygments-1.1.1/setup.py` has:
|
||||
Similarly for the 'scripts' clause; see e.g. `+python-pygments+`:
|
||||
`+Pygments-1.1.1/setup.py+` has:
|
||||
|
||||
....
|
||||
scripts = ['pygmentize'],
|
||||
....
|
||||
|
||||
which generates a `/usr/bin/pygmentize` (this is a python script that leverages the pygments syntax-highlighting module, giving a simple command-line interface for generating syntax-highlighted files)
|
||||
which generates a `+/usr/bin/pygmentize+` (this is a python script that leverages the pygments syntax-highlighting module, giving a simple command-line interface for generating syntax-highlighted files)
|
||||
|
||||
==== Guidelines
|
||||
|
||||
|
|
@ -446,21 +446,21 @@ If the executables provide the same functionality independent of whether they ar
|
|||
|
||||
Examples of this:
|
||||
|
||||
* `/usr/bin/pygmentize` ought to generate the same output regardless of whether it's implemented via Python 2 or Python 3, so only one version needs to be shipped.
|
||||
* `+/usr/bin/pygmentize+` ought to generate the same output regardless of whether it's implemented via Python 2 or Python 3, so only one version needs to be shipped.
|
||||
|
||||
If the executables provide different functionality for Python 2 and Python 3, then both versions should be packaged.
|
||||
|
||||
Examples of this:
|
||||
|
||||
* `/usr/bin/coverage` runs a python script, augmenting the interpreter with code-coverage information. Given that the interpreter itself is the thing being worked with, it's reasonable to package both versions of the executable.
|
||||
* `/usr/bin/bpython` augments the interpreter with a "curses" interface. Again, it's reasonable to package both versions of this.
|
||||
* `/usr/bin/easy_install` installs a module into one of the Python runtimes: we need a version for each runtime.
|
||||
* `+/usr/bin/coverage+` runs a python script, augmenting the interpreter with code-coverage information. Given that the interpreter itself is the thing being worked with, it's reasonable to package both versions of the executable.
|
||||
* `+/usr/bin/bpython+` augments the interpreter with a "curses" interface. Again, it's reasonable to package both versions of this.
|
||||
* `+/usr/bin/easy_install+` installs a module into one of the Python runtimes: we need a version for each runtime.
|
||||
|
||||
As an exception, for the rpms that are part of a python runtime itself, we plan to package both versions of the executables, so that e.g. both the python 2 and python 3 versions of `2to3` are packaged.
|
||||
As an exception, for the rpms that are part of a python runtime itself, we plan to package both versions of the executables, so that e.g. both the python 2 and python 3 versions of `+2to3+` are packaged.
|
||||
|
||||
==== Naming
|
||||
|
||||
Many executables already contain a "-MAJOR.MINOR" suffix, for example `/usr/bin/easy_install-3.1`. These obviously can be used as-is, as they won't conflict.
|
||||
Many executables already contain a "-MAJOR.MINOR" suffix, for example `+/usr/bin/easy_install-3.1+`. These obviously can be used as-is, as they won't conflict.
|
||||
|
||||
For other executables, the general rule is:
|
||||
|
||||
|
|
@ -468,8 +468,8 @@ For other executables, the general rule is:
|
|||
* If executables are to be shipped for both python 2 and python 3:
|
||||
** Both python 2 and python 3 variants must provide symlinks with a '-X' and '-X.Y' suffix (python runtime major version, or python runtime major.minor version), unless upstream already provides appropriately versioned executables without the dash.
|
||||
** The unversioned executable *must* be the python 2 version.
|
||||
** For example, the python 2 version of "coverage" *must* ship executables `/usr/bin/coverage`, `/usr/bin/coverage-2` and `/usr/bin/coverage-2.7`, while the python 3 version *must* provide `/usr/bin/coverage-3` and `/usr/bin/coverage-3.4` (assuming python3 is Python 3.4).
|
||||
** For compatibility packages, the Python version is appended *after* the specific package version, for example `/usr/bin/coverage-v1.2-3` and `/usr/bin/coverage-v1.2-3.4` for python3-coverage1.2 compat package.
|
||||
** For example, the python 2 version of "coverage" *must* ship executables `+/usr/bin/coverage+`, `+/usr/bin/coverage-2+` and `+/usr/bin/coverage-2.7+`, while the python 3 version *must* provide `+/usr/bin/coverage-3+` and `+/usr/bin/coverage-3.4+` (assuming python3 is Python 3.4).
|
||||
** For compatibility packages, the Python version is appended *after* the specific package version, for example `+/usr/bin/coverage-v1.2-3+` and `+/usr/bin/coverage-v1.2-3.4+` for python3-coverage1.2 compat package.
|
||||
|
||||
See http://lists.fedoraproject.org/pipermail/devel/2010-January/129217.html[this thread] and a newer thread https://lists.fedoraproject.org/pipermail/packaging/2014-December/010360.html[1] for discussions of this.
|
||||
|
||||
|
|
|
|||
|
|
@ -131,9 +131,9 @@ rm -rf %{buildroot}%{_datadir}/R/library/R.css
|
|||
|
||||
=== Summary of differences between arch-specific and noarch R packages
|
||||
|
||||
* Noarch packages set `BuildArch: noarch`.
|
||||
* Noarch packages install into `%{_datadir}/R/library/%{packname}`; arch-specific packages install into `%{_libdir}/R/library/%{packname}`.
|
||||
* Noarch packages have `Requires: R-core`. For arch-specific packages, RPM will automatically add an appropriate dependency on the needed shared libraries but noarch packages need this added manually.
|
||||
* Noarch packages set `+BuildArch: noarch+`.
|
||||
* Noarch packages install into `+%{_datadir}/R/library/%{packname}+`; arch-specific packages install into `+%{_libdir}/R/library/%{packname}+`.
|
||||
* Noarch packages have `+Requires: R-core+`. For arch-specific packages, RPM will automatically add an appropriate dependency on the needed shared libraries but noarch packages need this added manually.
|
||||
|
||||
=== R2spec
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ More information here : https://pagure.io/r2spec/
|
|||
|
||||
=== Naming of R packages
|
||||
|
||||
Packages of R modules (thus they rely on R as a parent) have their own naming scheme. They should take into account the upstream name of the R module. This makes a package name format of `R-$NAME`. When in doubt, use the name of the module that you type to import it in R.
|
||||
Packages of R modules (thus they rely on R as a parent) have their own naming scheme. They should take into account the upstream name of the R module. This makes a package name format of `+R-$NAME+`. When in doubt, use the name of the module that you type to import it in R.
|
||||
|
||||
'''Examples: '''
|
||||
|
||||
|
|
@ -169,19 +169,19 @@ Fedora Version: 0.5.8
|
|||
|
||||
=== Empty %build section
|
||||
|
||||
Unlike normal Fedora packages, there is normally no separate `%build` actions (e.g. `%configure`)that need to be taken for an R package. However, it is important that all R module packages include an empty `%build` section, as shown in the spec templates.
|
||||
Unlike normal Fedora packages, there is normally no separate `+%build+` actions (e.g. `+%configure+`)that need to be taken for an R package. However, it is important that all R module packages include an empty `+%build+` section, as shown in the spec templates.
|
||||
|
||||
=== Installing the R addon bits
|
||||
|
||||
Instead of calling make install, to install the R addon components, you need to run `R CMD INSTALL -l %{buildroot}%{_datadir}/R/library %{packname}` (noarch) or `R CMD INSTALL -l %{buildroot}%{_libdir}/R/library %{packname}` (arch-specific). Proper `%install` sections for Fedora R packages are demonstrated in the spec templates.
|
||||
Instead of calling make install, to install the R addon components, you need to run `+R CMD INSTALL -l %{buildroot}%{_datadir}/R/library %{packname}+` (noarch) or `+R CMD INSTALL -l %{buildroot}%{_libdir}/R/library %{packname}+` (arch-specific). Proper `+%install+` sections for Fedora R packages are demonstrated in the spec templates.
|
||||
|
||||
=== Deleting the R.css file
|
||||
|
||||
Most R addon modules generate a new `R.css file`, but it would conflict with the master `R.css` file, included in the main R package. You must delete this file, and do not include it in your package.
|
||||
Most R addon modules generate a new `+R.css file+`, but it would conflict with the master `+R.css+` file, included in the main R package. You must delete this file, and do not include it in your package.
|
||||
|
||||
=== Cleaning the R directory of binaries
|
||||
|
||||
It is important to clean the R directory of binary files (`*.o *.so`) before running `R CMD CHECK`. Otherwise, the CHECK command will throw a warning about finding binaries in the source dir. This is accomplished by running (in `%install`):
|
||||
It is important to clean the R directory of binary files (`+*.o *.so+`) before running `+R CMD CHECK+`. Otherwise, the CHECK command will throw a warning about finding binaries in the source dir. This is accomplished by running (in `+%install+`):
|
||||
|
||||
....
|
||||
test -d %{packname}/src && (cd %{packname}/src; rm -f *.o *.so)
|
||||
|
|
@ -191,19 +191,19 @@ This is demonstrated in the spec templates.
|
|||
|
||||
=== Running %check
|
||||
|
||||
Most (if not all) R addon modules come with a built-in check. This can be triggered by running `R CMD check`. In Fedora, the check should be run in the `%check` section. Here is an example `%check` section for a Fedora R package:
|
||||
Most (if not all) R addon modules come with a built-in check. This can be triggered by running `+R CMD check+`. In Fedora, the check should be run in the `+%check+` section. Here is an example `+%check+` section for a Fedora R package:
|
||||
|
||||
....
|
||||
%check
|
||||
%{_bindir}/R CMD check %{packname}
|
||||
....
|
||||
|
||||
Note that frequently, R packages have circular dependency loops when running `R CMD check`. If you hit such a case, you can comment out the check to break the dependency loop, and leave a comment explaining the circular dependency problem.
|
||||
Note that frequently, R packages have circular dependency loops when running `+R CMD check+`. If you hit such a case, you can comment out the check to break the dependency loop, and leave a comment explaining the circular dependency problem.
|
||||
|
||||
=== Documentation files
|
||||
|
||||
The `R CMD INSTALL` operation will install all of the files, including documentation files. The doc, html and NEWS files/directories need to be marked as `%doc`.
|
||||
Note that other files, such as DESCRIPTION, INDEX, NAMESPACE, and help/ are not `%doc`, since proper R functionality depends on their presence. Be careful not to duplicate `%doc` files in the package, the spec templates provide good examples on how to package the R addon files without duplications.
|
||||
The `+R CMD INSTALL+` operation will install all of the files, including documentation files. The doc, html and NEWS files/directories need to be marked as `+%doc+`.
|
||||
Note that other files, such as DESCRIPTION, INDEX, NAMESPACE, and help/ are not `+%doc+`, since proper R functionality depends on their presence. Be careful not to duplicate `+%doc+` files in the package, the spec templates provide good examples on how to package the R addon files without duplications.
|
||||
|
||||
==== R documentation
|
||||
|
||||
|
|
@ -211,11 +211,11 @@ R documentation is written in TeX. rpmlint sometimes complains that these TeX fi
|
|||
|
||||
=== Optimization flags
|
||||
|
||||
R packages inherit their optimization flags from the main R package, which stores them in `%{_libdir}/R/etc/Makeconf`. The design of R is such that all R addon library modules use the same optimization flags that the main R package was built with. Accordingly, this is why R addon packages do not pass `%{optflags}`. Also, there is no simple way to pass special optimization flags to `R CMD INSTALL`.
|
||||
R packages inherit their optimization flags from the main R package, which stores them in `+%{_libdir}/R/etc/Makeconf+`. The design of R is such that all R addon library modules use the same optimization flags that the main R package was built with. Accordingly, this is why R addon packages do not pass `+%{optflags}+`. Also, there is no simple way to pass special optimization flags to `+R CMD INSTALL+`.
|
||||
|
||||
=== R headers
|
||||
|
||||
R packages usually expect to find their header files in `%{_libdir}/R/library/*/`. rpmlint will complain that these files are misplaced, but this is safe to ignore.
|
||||
R packages usually expect to find their header files in `+%{_libdir}/R/library/*/+`. rpmlint will complain that these files are misplaced, but this is safe to ignore.
|
||||
|
||||
You should still separate these header files into a -devel subpackage.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
== Valid RPM Macros
|
||||
|
||||
Here are the definitions for some common specfile macros as they are defined on Fedora 13 (rpm-4.8.0-14.fc13). For definitions of more macros, examine the output of "`rpm --showrc`". To see the expanded definition of a macro use the command `rpm --eval "%{macro}"`. Note that neither command will take into account macros defined inside specfiles, but both will take into account macros defined in your `~/.rpmmacros` file and macros defined on the command line.
|
||||
Here are the definitions for some common specfile macros as they are defined on Fedora 13 (rpm-4.8.0-14.fc13). For definitions of more macros, examine the output of "`+rpm --showrc+`". To see the expanded definition of a macro use the command `+rpm --eval "%{macro}"+`. Note that neither command will take into account macros defined inside specfiles, but both will take into account macros defined in your `+~/.rpmmacros+` file and macros defined on the command line.
|
||||
|
||||
Keep in mind that some of these macros may evaluate differently on older Fedora or EPEL releases.
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ Keep in mind that some of these macros may evaluate differently on older Fedora
|
|||
|
||||
=== Other macros and variables for paths
|
||||
|
||||
These macros should be used for paths that are not covered by the macros mimicking autoconf variables. The `%{buildroot}` macro or the `$RPM_BUILD_ROOT` variable is the directory that should be assumed to be the root file system when installing files. It is used as the value for the `DESTDIR` variable.
|
||||
These macros should be used for paths that are not covered by the macros mimicking autoconf variables. The `+%{buildroot}+` macro or the `+$RPM_BUILD_ROOT+` variable is the directory that should be assumed to be the root file system when installing files. It is used as the value for the `+DESTDIR+` variable.
|
||||
|
||||
....
|
||||
%{_var} /var
|
||||
|
|
@ -51,7 +51,7 @@ $RPM_OPT_FLAGS %{optflags}
|
|||
|
||||
=== RPM directory macros
|
||||
|
||||
The macros are usually used with `rpmbuild --define` to specify which directories rpmbuild should use, it is unusual to use them within SPEC files.
|
||||
The macros are usually used with `+rpmbuild --define+` to specify which directories rpmbuild should use, it is unusual to use them within SPEC files.
|
||||
|
||||
....
|
||||
%{_topdir} %{getenv:HOME}/rpmbuild
|
||||
|
|
|
|||
|
|
@ -15,19 +15,19 @@ There are many many things to check for a review. This list is provided to assis
|
|||
|
||||
* *MUST*: rpmlint must be run on the source rpm and all binary rpms the build produces. The output should be posted in the review.footnote:[link:Packaging/Guidelines#rpmlint[Packaging Guidelines: Use rpmlint]] +
|
||||
* *MUST*: The package must be named according to the link:Packaging/NamingGuidelines[ Package Naming Guidelines] . +
|
||||
* *MUST*: The spec file name must match the base package `%{name}`, in the format `%{name}.spec` unless your package has an exemption. footnote:[link:Packaging/NamingGuidelines#Spec_file_name[ Naming Guidelines: Spec File Naming]] . +
|
||||
* *MUST*: The spec file name must match the base package `+%{name}+`, in the format `+%{name}.spec+` unless your package has an exemption. footnote:[link:Packaging/NamingGuidelines#Spec_file_name[ Naming Guidelines: Spec File Naming]] . +
|
||||
* *MUST*: The package must meet the link:Packaging/Guidelines[ Packaging Guidelines] . +
|
||||
* *MUST*: The package must be licensed with a Fedora approved license and meet the link:Packaging/LicensingGuidelines[ Licensing Guidelines] . +
|
||||
* *MUST*: The License field in the package spec file must match the actual license. footnote:[link:Packaging/LicensingGuidelines#ValidLicenseShortNames[ Licensing Guidelines: Valid License Short Names]] +
|
||||
* *MUST*: If (and only if) the source package includes the text of the license(s) in its own file, then that file, containing the text of the license(s) for the package must be included in `%license`.footnote:[link:Packaging/LicensingGuidelines#License_Text[Licensing Guidelines: License Text]] +
|
||||
* *MUST*: If (and only if) the source package includes the text of the license(s) in its own file, then that file, containing the text of the license(s) for the package must be included in `+%license+`.footnote:[link:Packaging/LicensingGuidelines#License_Text[Licensing Guidelines: License Text]] +
|
||||
* *MUST*: The spec file must be written in American English. footnote:[link:Packaging/Guidelines#summary[Packaging Guidelines: Summary]] +
|
||||
* *MUST*: The spec file for the package *MUST* be legible. footnote:[link:Packaging/Guidelines#Spec_Legibility[Packaging Guidelines: Spec Legibility]] +
|
||||
* *MUST*: The sources used to build the package must match the upstream source, as provided in the spec URL. Reviewers should use sha256sum for this task as it is used by the `sources` file once imported into git. If no upstream URL can be specified for this package, please see the link:Packaging/SourceURL[ Source URL Guidelines] for how to deal with this. +
|
||||
* *MUST*: The sources used to build the package must match the upstream source, as provided in the spec URL. Reviewers should use sha256sum for this task as it is used by the `+sources+` file once imported into git. If no upstream URL can be specified for this package, please see the link:Packaging/SourceURL[ Source URL Guidelines] for how to deal with this. +
|
||||
* *MUST*: The package *MUST* successfully compile and build into binary rpms on at least one primary architecture. footnote:[link:Packaging/Guidelines#Architecture_Support[Packaging Guidelines: Architecture Support]] +
|
||||
* *MUST*: If the package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in `ExcludeArch`. Each architecture listed in `ExcludeArch` *MUST* have a bug filed in bugzilla, describing the reason that the package does not compile/build/work on that architecture. The bug number *MUST* be placed in a comment, next to the corresponding `ExcludeArch` line. footnote:[link:Packaging/Guidelines#Architecture_Build_Failures[Packaging Guidelines: Architecture Build Failures]] +
|
||||
* *MUST*: All build dependencies must be listed in `BuildRequires`, except for any that are listed in the link:Packaging/Guidelines#Exceptions_2[exceptions section of the Packaging Guidelines] ; inclusion of those as `BuildRequires` is optional. Apply common sense. +
|
||||
* *MUST*: The spec file MUST handle locales properly. This is done by using the `%find_lang` macro. Using `%{_datadir}/locale/*` is strictly forbidden.footnote:[link:Packaging/Guidelines#Handling_Locale_Files[Packaging Guidelines: Handling Locale Files]] +
|
||||
* *MUST*: Every binary RPM package (or subpackage) which stores shared library files (not just symlinks) in any of the dynamic linker's default paths, must call ldconfig in `%post` and `%postun`. footnote:[link:Packaging/Guidelines#Shared_Libraries[Packaging Guidelines: Shared Libraries]] +
|
||||
* *MUST*: If the package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in `+ExcludeArch+`. Each architecture listed in `+ExcludeArch+` *MUST* have a bug filed in bugzilla, describing the reason that the package does not compile/build/work on that architecture. The bug number *MUST* be placed in a comment, next to the corresponding `+ExcludeArch+` line. footnote:[link:Packaging/Guidelines#Architecture_Build_Failures[Packaging Guidelines: Architecture Build Failures]] +
|
||||
* *MUST*: All build dependencies must be listed in `+BuildRequires+`, except for any that are listed in the link:Packaging/Guidelines#Exceptions_2[exceptions section of the Packaging Guidelines] ; inclusion of those as `+BuildRequires+` is optional. Apply common sense. +
|
||||
* *MUST*: The spec file MUST handle locales properly. This is done by using the `+%find_lang+` macro. Using `+%{_datadir}/locale/*+` is strictly forbidden.footnote:[link:Packaging/Guidelines#Handling_Locale_Files[Packaging Guidelines: Handling Locale Files]] +
|
||||
* *MUST*: Every binary RPM package (or subpackage) which stores shared library files (not just symlinks) in any of the dynamic linker's default paths, must call ldconfig in `+%post+` and `+%postun+`. footnote:[link:Packaging/Guidelines#Shared_Libraries[Packaging Guidelines: Shared Libraries]] +
|
||||
* *MUST*: Packages must NOT bundle copies of system libraries.footnote:[Packaging:Guidelines#Duplication_of_system_libraries[Packaging Guidelines: Duplication of System Libraries]] +
|
||||
* *MUST*: If the package is designed to be relocatable, the packager must state this fact in the request for review, along with the rationalization for relocation of that specific package. Without this, use of Prefix: /usr is considered a blocker. footnote:[link:Packaging/Guidelines#RelocatablePackages[Packaging Guidelines: Relocatable Packages]] +
|
||||
* *MUST*: A package must own all directories that it creates. If it does not create a directory that it uses, then it should require a package which does create that directory. footnote:[link:Packaging/Guidelines#FileAndDirectoryOwnership[Packaging Guidelines: File And Directory Ownership]] +
|
||||
|
|
@ -39,10 +39,10 @@ There are many many things to check for a review. This list is provided to assis
|
|||
* *MUST*: If a package includes something as %doc, it must not affect the runtime of the application. To summarize: If it is in %doc, the program must run properly if it is not present. footnote:[link:Packaging/Guidelines#PackageDocumentation[Packaging Guidelines: Package Documentation]] +
|
||||
* *MUST*: Static libraries must be in a -static package. footnote:[link:Packaging/Guidelines#StaticLibraries[Packaging Guidelines: Packaging Static Libraries]] +
|
||||
* *MUST*: Development files must be in a -devel package. footnote:[link:Packaging/Guidelines#DevelPackages[Packaging Guidelines: Devel Packages]] +
|
||||
* *MUST*: In the vast majority of cases, devel packages must require the base package using a fully versioned dependency: `Requires: %{name}%{?_isa} = %{version}-%{release}` footnote:[link:Packaging/Guidelines#RequiringBasePackage[Packaging Guidelines: Requiring Base Package]] +
|
||||
* *MUST*: In the vast majority of cases, devel packages must require the base package using a fully versioned dependency: `+Requires: %{name}%{?_isa} = %{version}-%{release}+` footnote:[link:Packaging/Guidelines#RequiringBasePackage[Packaging Guidelines: Requiring Base Package]] +
|
||||
* *MUST*: Packages must NOT contain any .la libtool archives, these must be removed in the spec if they are built.footnote:[link:Packaging/Guidelines#StaticLibraries[Packaging Guidelines: Packaging Static Libraries]] +
|
||||
* *MUST*: Packages containing GUI applications must include a %\{name}.desktop file, and that file must be properly installed with desktop-file-install in the %install section. If you feel that your packaged GUI application does not need a .desktop file, you must put a comment in the spec file with your explanation. footnote:[link:Packaging/Guidelines#desktop[Packaging Guidelines: Desktop files]] +
|
||||
* *MUST*: Packages must not own files or directories already owned by other packages. The rule of thumb here is that the first package to be installed should own the files or directories that other packages may rely upon. This means, for example, that no package in Fedora should ever share ownership with any of the files or directories owned by the `filesystem` or `man` package. If you feel that you have a good reason to own a file or directory that another package owns, then please present that at package review time. footnote:[link:Packaging/Guidelines#FileAndDirectoryOwnership[Packaging Guidelines: File And Directory Ownership]] +
|
||||
* *MUST*: Packages must not own files or directories already owned by other packages. The rule of thumb here is that the first package to be installed should own the files or directories that other packages may rely upon. This means, for example, that no package in Fedora should ever share ownership with any of the files or directories owned by the `+filesystem+` or `+man+` package. If you feel that you have a good reason to own a file or directory that another package owns, then please present that at package review time. footnote:[link:Packaging/Guidelines#FileAndDirectoryOwnership[Packaging Guidelines: File And Directory Ownership]] +
|
||||
* *MUST*: All filenames in rpm packages must be valid UTF-8. footnote:[link:Packaging/Guidelines#FilenameEncoding[Packaging Guidelines: Filename Encoding]] +
|
||||
* *MUST*: Packages being added to the distribution MUST NOT depend on any packages which have been marked as being deprecated. footnote:[Packaging:Deprecating_Packages] +
|
||||
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ Requires: ruby(release) >= 1.9.1
|
|||
|
||||
=== Different Interpreters Compatibility
|
||||
|
||||
Most of the pure Ruby packages will work on all Ruby interpreters. There are however cases, when the packages use interpreter-specific functions (like `fork()`) and won't run on other interpreters (JRuby). In this case, the package SHOULD require that interpreter. For example, a package that uses `fork` SHOULD explicitly specify `Requires: ruby`.
|
||||
Most of the pure Ruby packages will work on all Ruby interpreters. There are however cases, when the packages use interpreter-specific functions (like `+fork()+`) and won't run on other interpreters (JRuby). In this case, the package SHOULD require that interpreter. For example, a package that uses `+fork+` SHOULD explicitly specify `+Requires: ruby+`.
|
||||
In case of such package, packager SHOULD file a bug to ask upstream to provide support for other interpreter(s). This SHOULD be documented in specfile.
|
||||
|
||||
=== Shebang lines
|
||||
|
||||
On Fedora, `/usr/bin/ruby` is implemented via https://github.com/bkabrda/rubypick[Rubypick]. Rubypick is a tool similar to RVM or rbenv. It allows choosing interpreter to execute Ruby script. Rubypick routes anything executed via `/usr/bin/ruby` to `/usr/bin/ruby-mri` or `/usr/bin/jruby`. By default, it runs MRI (Matz's Ruby Implementation), but user can explicitly specify the interpreter by using `_mri_` or `_jruby_` as a first parameter. For example:
|
||||
On Fedora, `+/usr/bin/ruby+` is implemented via https://github.com/bkabrda/rubypick[Rubypick]. Rubypick is a tool similar to RVM or rbenv. It allows choosing interpreter to execute Ruby script. Rubypick routes anything executed via `+/usr/bin/ruby+` to `+/usr/bin/ruby-mri+` or `+/usr/bin/jruby+`. By default, it runs MRI (Matz's Ruby Implementation), but user can explicitly specify the interpreter by using `+_mri_+` or `+_jruby_+` as a first parameter. For example:
|
||||
|
||||
....
|
||||
ruby _jruby_ jruby_script.rb
|
||||
|
|
@ -31,7 +31,7 @@ gem _mri_ install foo
|
|||
rails _jruby_ s
|
||||
....
|
||||
|
||||
Using the `RUBYPICK` environment variable can achieve the same results. The environment variable can be used to set one interpreter as the global default:
|
||||
Using the `+RUBYPICK+` environment variable can achieve the same results. The environment variable can be used to set one interpreter as the global default:
|
||||
|
||||
....
|
||||
export RUBYPICK=_jruby_
|
||||
|
|
@ -39,43 +39,43 @@ ruby jruby_script.rb # Will use jruby
|
|||
gem install foo # Will also use jruby
|
||||
....
|
||||
|
||||
Ruby executables that are known to only run on one Ruby implementation SHOULD use that specific implementation in their shebang - `#!/usr/bin/ruby-mri` or `#!/usr/bin/jruby` to ensure that they run using that implementation. All other code SHOULD use `#!/usr/bin/ruby`.
|
||||
Ruby executables that are known to only run on one Ruby implementation SHOULD use that specific implementation in their shebang - `+#!/usr/bin/ruby-mri+` or `+#!/usr/bin/jruby+` to ensure that they run using that implementation. All other code SHOULD use `+#!/usr/bin/ruby+`.
|
||||
|
||||
== Naming Guidelines
|
||||
|
||||
* Packages that contain Ruby Gems MUST be called `rubygem-%{gem_name}`.
|
||||
* Packages that contain Ruby Gems MUST be called `+rubygem-%{gem_name}+`.
|
||||
|
||||
* The name of a ruby extension/library package MUST start with the interpreter it is built for (ruby, jruby, etc) and then the `UPSTREAM` name. For example: `ruby-UPSTREAM`. If the upstream name `UPSTREAM` contains `ruby`, that SHOULD be dropped from the name. For example, the SQLite database driver for ruby is called `sqlite3-ruby`. The corresponding Fedora package SHOULD be called `ruby-sqlite3`, and not `ruby-sqlite3-ruby`.
|
||||
* The name of a ruby extension/library package MUST start with the interpreter it is built for (ruby, jruby, etc) and then the `+UPSTREAM+` name. For example: `+ruby-UPSTREAM+`. If the upstream name `+UPSTREAM+` contains `+ruby+`, that SHOULD be dropped from the name. For example, the SQLite database driver for ruby is called `+sqlite3-ruby+`. The corresponding Fedora package SHOULD be called `+ruby-sqlite3+`, and not `+ruby-sqlite3-ruby+`.
|
||||
|
||||
* Application packages that mainly provide user-level tools that happen to be written in Ruby MUST follow the general link:Packaging/NamingGuidelines[ NamingGuidelines] instead.
|
||||
|
||||
== Macros
|
||||
|
||||
Non-gem ruby packages and ruby gem packages install to certain standard locations. The `ruby-devel` and `rubygems-devel` packages contain macros useful for the respective package types. Alternate ruby interpreters will have equivalent locations (To be added to this table later)
|
||||
Non-gem ruby packages and ruby gem packages install to certain standard locations. The `+ruby-devel+` and `+rubygems-devel+` packages contain macros useful for the respective package types. Alternate ruby interpreters will have equivalent locations (To be added to this table later)
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|===================================================================================================================
|
||||
|Macro |Expanded path |Usage
|
||||
|From ruby-devel; intended for non-gem packages.
|
||||
|`%{ruby_vendorarchdir}` |/usr/lib\{64}/ruby/vendor_ruby |Place for architecture specific (e.g. *.so) files.
|
||||
|`%{ruby_vendorlibdir}` |/usr/share/ruby/vendor_ruby |Place for architecture independent (e.g. *.rb) files.
|
||||
|`%{ruby_sitearchdir}` |/usr/local/lib\{64}/ruby/site_ruby |Place for local architecture specific (e.g. *.so) files.
|
||||
|`%{ruby_sitelibdir}` |/usr/local/share/ruby/site_ruby |Place for local architecture independent (e.g. *.rb) files.
|
||||
|`+%{ruby_vendorarchdir}+` |/usr/lib\{64}/ruby/vendor_ruby |Place for architecture specific (e.g. *.so) files.
|
||||
|`+%{ruby_vendorlibdir}+` |/usr/share/ruby/vendor_ruby |Place for architecture independent (e.g. *.rb) files.
|
||||
|`+%{ruby_sitearchdir}+` |/usr/local/lib\{64}/ruby/site_ruby |Place for local architecture specific (e.g. *.so) files.
|
||||
|`+%{ruby_sitelibdir}+` |/usr/local/share/ruby/site_ruby |Place for local architecture independent (e.g. *.rb) files.
|
||||
|From rubygems-devel; intended for gem packages
|
||||
|`%{gem_dir}` |/usr/share/gems |Top directory for the Gem structure.
|
||||
|`%{gem_instdir}` |%\{gem_dir}/gems/%\{gem_name}-%\{version} |Directory with the actual content of the Gem.
|
||||
|`%{gem_libdir}` |%\{gem_instdir}/lib |The `lib` folder of the Gem.
|
||||
|`%{gem_cache}` |%\{gem_dir}/cache/%\{gem_name}-%\{version}.gem |The cached Gem.
|
||||
|`%{gem_spec}` |%\{gem_dir}/specifications/%\{gem_name}-%\{version}.gemspec |The Gem specification file.
|
||||
|`%{gem_docdir}` |%\{gem_dir}/doc/%\{gem_name}-%\{version} |The rdoc documentation of the Gem.
|
||||
|`%{gem_extdir_mri}` |%\{_libdir}/gems/ruby/%\{gem_name}-%\{version} |The directory for MRI Ruby Gem extensions.
|
||||
|`+%{gem_dir}+` |/usr/share/gems |Top directory for the Gem structure.
|
||||
|`+%{gem_instdir}+` |%\{gem_dir}/gems/%\{gem_name}-%\{version} |Directory with the actual content of the Gem.
|
||||
|`+%{gem_libdir}+` |%\{gem_instdir}/lib |The `+lib+` folder of the Gem.
|
||||
|`+%{gem_cache}+` |%\{gem_dir}/cache/%\{gem_name}-%\{version}.gem |The cached Gem.
|
||||
|`+%{gem_spec}+` |%\{gem_dir}/specifications/%\{gem_name}-%\{version}.gemspec |The Gem specification file.
|
||||
|`+%{gem_docdir}+` |%\{gem_dir}/doc/%\{gem_name}-%\{version} |The rdoc documentation of the Gem.
|
||||
|`+%{gem_extdir_mri}+` |%\{_libdir}/gems/ruby/%\{gem_name}-%\{version} |The directory for MRI Ruby Gem extensions.
|
||||
|===================================================================================================================
|
||||
|
||||
=== Interpreter independence and directory macros
|
||||
|
||||
You might have noticed that the table above has different directories for non-gem libraries on different ruby interpreters but only a single set of directories for rubygem libraries. This is because code written for one ruby interpreter will often run on all ruby interpreters that Fedora ships (ruby, jruby, etc). However, some code uses methods that are not available on all interpreters (see link:#interpreter_compatibility[Different Interpreters Compatibility]). Rubygems have a facility to ship different versions of the code in the same gem so that the gem can run on all versions of the interpreter so we only need to have one common directory for rubygems that all the interpreters can use.
|
||||
|
||||
The standard ruby `%{vendorlib}` directories lack this facility. For this reason, non-gem libraries need to be placed in per-interpreter directories and MUST have a separate subpackage (or package depending on upstream) for each interpreter that they support.
|
||||
The standard ruby `+%{vendorlib}+` directories lack this facility. For this reason, non-gem libraries need to be placed in per-interpreter directories and MUST have a separate subpackage (or package depending on upstream) for each interpreter that they support.
|
||||
|
||||
== Libraries
|
||||
|
||||
|
|
@ -87,11 +87,11 @@ http://www.rubygems.org/[RubyGems] are Ruby's own packaging format. Gems contain
|
|||
|
||||
Both RPM's and Gems use similar terminology --- there are specfiles, package names, dependencies etc. for both. To keep confusion to a minimum, terms relating to Gem concepts will be explicitly refereed to with the word 'Gem' prefixed, eg 'Gem specification' (.gemspec). An unqualified 'package' in the following always means an RPM.
|
||||
|
||||
* Spec files MUST contain a definition of `%{gem_name}` which is the name from the Gem's specification.
|
||||
* The `Source` of the package MUST be the full URL to the released Gem archive; the version of the package MUST be the Gem's version.
|
||||
* The package MUST `BuildRequires: rubygems-devel` to pull in the macros needed to build.
|
||||
* There SHOULD NOT be any rubygem `Requires` nor `Provides` listed, since those are autogenerated.
|
||||
* There SHOULD NOT be `Requires: ruby(release)`, unless you want to explicitly specify Ruby version compatibility. Automatically generated dependency on RubyGems (`Requires: ruby(rubygems)`) is enough.
|
||||
* Spec files MUST contain a definition of `+%{gem_name}+` which is the name from the Gem's specification.
|
||||
* The `+Source+` of the package MUST be the full URL to the released Gem archive; the version of the package MUST be the Gem's version.
|
||||
* The package MUST `+BuildRequires: rubygems-devel+` to pull in the macros needed to build.
|
||||
* There SHOULD NOT be any rubygem `+Requires+` nor `+Provides+` listed, since those are autogenerated.
|
||||
* There SHOULD NOT be `+Requires: ruby(release)+`, unless you want to explicitly specify Ruby version compatibility. Automatically generated dependency on RubyGems (`+Requires: ruby(rubygems)+`) is enough.
|
||||
|
||||
==== Filtering Requires and Provides
|
||||
|
||||
|
|
@ -134,28 +134,28 @@ cp -a .%{gem_extdir_mri}/{gem.build_complete,*.so} %{buildroot}%{gem_extdir_mri}
|
|||
|
||||
===== %prep
|
||||
|
||||
RPM (as of 4.14) can directly unpack gem archives, so we can call `gem unpack` to extract the source from the gem. Then we call `%setup -n %{gem_name}-%{version}` to tell rpm what the directory the gem has unpacked into. At the same directory level, the %\{gem_name}-%\{version}.gemspec file is created automatically as well. This `.gemspec` file will be used to rebuild the gem later. If we need to modify the `.gemspec` (for instance, if the version of dependencies is wrong for Fedora or the `.gemspec` is using old, no longer supported fields) we would do it here. Patches to the code itself can also be done here.
|
||||
RPM (as of 4.14) can directly unpack gem archives, so we can call `+gem unpack+` to extract the source from the gem. Then we call `+%setup -n %{gem_name}-%{version}+` to tell rpm what the directory the gem has unpacked into. At the same directory level, the %\{gem_name}-%\{version}.gemspec file is created automatically as well. This `+.gemspec+` file will be used to rebuild the gem later. If we need to modify the `+.gemspec+` (for instance, if the version of dependencies is wrong for Fedora or the `+.gemspec+` is using old, no longer supported fields) we would do it here. Patches to the code itself can also be done here.
|
||||
|
||||
===== %build
|
||||
|
||||
Next we build the gem. Because `%gem_install` only operates on gem archives, we next recreate the gem with `gem build`. The gem file that is created is then used by `%gem_install` to build and install the code into the temporary directory, which is `./%{gem_dir}` by default. We do this because the `%gem_install` command both builds and installs the code in one step so we need to have a temporary directory to place the built sources before installing them in `%install` section.
|
||||
Next we build the gem. Because `+%gem_install+` only operates on gem archives, we next recreate the gem with `+gem build+`. The gem file that is created is then used by `+%gem_install+` to build and install the code into the temporary directory, which is `+./%{gem_dir}+` by default. We do this because the `+%gem_install+` command both builds and installs the code in one step so we need to have a temporary directory to place the built sources before installing them in `+%install+` section.
|
||||
|
||||
`%gem_install` macro accepts two additional options:
|
||||
`+%gem_install+` macro accepts two additional options:
|
||||
|
||||
`-n `::
|
||||
`+-n +`::
|
||||
Allows to override gem used for installation. This might get useful for converting legacy spec, so you might specify %\{SOURCE0} as a gem for installation.
|
||||
`-d `::
|
||||
`+-d +`::
|
||||
Might override the gem installation destination. However we do not suggest to use this option.
|
||||
|
||||
===== %install
|
||||
|
||||
Here we actually install into the `%{buildroot}`. We create the directories that we need and then copy what was installed into the temporary directories into the `%{buildroot}` hierarchy. Finally, if this ruby gem creates shared objects the shared objects are moved into the arch specific `%{gem_extdir_mri}` path.
|
||||
Here we actually install into the `+%{buildroot}+`. We create the directories that we need and then copy what was installed into the temporary directories into the `+%{buildroot}+` hierarchy. Finally, if this ruby gem creates shared objects the shared objects are moved into the arch specific `+%{gem_extdir_mri}+` path.
|
||||
|
||||
==== Patching required gem versions
|
||||
|
||||
One common patching need is to change overly strict version requirements in the upstream `.gemspec`. This could be because upstream's `.gemspec` only mentions versions that they've explicitly tested against but we know that a different version will also work or because we know that the packages we ship have applied fixes for problematic behavior without bumping the version number (for instance, backported fixes). To adjust such dependencies, you can use the `%gemspec_add_dep` and `%gemspec_remove_dep` macros.
|
||||
One common patching need is to change overly strict version requirements in the upstream `+.gemspec+`. This could be because upstream's `+.gemspec+` only mentions versions that they've explicitly tested against but we know that a different version will also work or because we know that the packages we ship have applied fixes for problematic behavior without bumping the version number (for instance, backported fixes). To adjust such dependencies, you can use the `+%gemspec_add_dep+` and `+%gemspec_remove_dep+` macros.
|
||||
|
||||
For example, if you wanted to use any version of Aruba instead of the overly specific version requested by upstream, you could use in `%prep` section following two lines:
|
||||
For example, if you wanted to use any version of Aruba instead of the overly specific version requested by upstream, you could use in `+%prep+` section following two lines:
|
||||
|
||||
....
|
||||
%gemspec_remove_dep -g aruba "~> 0.14.2"
|
||||
|
|
@ -166,31 +166,31 @@ For example, if you wanted to use any version of Aruba instead of the overly spe
|
|||
|
||||
=== Non-Gem Packages
|
||||
|
||||
Non-Gem Ruby packages MUST require ruby-devel package at build time with a `BuildRequires: ruby-devel`, and MAY indicate the minimal ruby version they need for building.
|
||||
Non-Gem Ruby packages MUST require ruby-devel package at build time with a `+BuildRequires: ruby-devel+`, and MAY indicate the minimal ruby version they need for building.
|
||||
|
||||
==== Build Architecture and File Placement
|
||||
|
||||
The following only affects the files that the package installs into `%{ruby_vendorarchdir}` and `%{ruby_vendorlibdir}` (the actual Ruby library files). All other files in a Ruby package MUST adhere to the general Fedora packaging conventions.
|
||||
The following only affects the files that the package installs into `+%{ruby_vendorarchdir}+` and `+%{ruby_vendorlibdir}+` (the actual Ruby library files). All other files in a Ruby package MUST adhere to the general Fedora packaging conventions.
|
||||
|
||||
==== Pure Ruby packages
|
||||
|
||||
Pure Ruby packages MUST be built as noarch packages.
|
||||
|
||||
The Ruby library files in a pure Ruby package MUST be placed into `%{ruby_vendorlibdir}` (or its proper subdirectory). The specfile MUST use this macro.
|
||||
The Ruby library files in a pure Ruby package MUST be placed into `+%{ruby_vendorlibdir}+` (or its proper subdirectory). The specfile MUST use this macro.
|
||||
|
||||
==== Ruby packages with binary content/shared libraries
|
||||
|
||||
For packages with binary content, e.g., database drivers or any other Ruby bindings to C libraries, the package MUST be architecture specific.
|
||||
|
||||
The binary files in a Ruby package with binary content MUST be placed into `%{ruby_vendorarchdir}` (or its proper subdirectory). The Ruby files in such a package SHOULD be placed into %\{ruby_vendorlibdir}. The specfile MUST use these macros.
|
||||
The binary files in a Ruby package with binary content MUST be placed into `+%{ruby_vendorarchdir}+` (or its proper subdirectory). The Ruby files in such a package SHOULD be placed into %\{ruby_vendorlibdir}. The specfile MUST use these macros.
|
||||
|
||||
For packages which create C shared libraries using `extconf.rb`
|
||||
For packages which create C shared libraries using `+extconf.rb+`
|
||||
|
||||
....
|
||||
export CONFIGURE_ARGS="--with-cflags='%{optflags}'"
|
||||
....
|
||||
|
||||
SHOULD be used to pass `CFLAGS` to `Makefile` correctly. Also, to place the files into the correct folders during build, pass `--vendor` to `extconf.rb` like this:
|
||||
SHOULD be used to pass `+CFLAGS+` to `+Makefile+` correctly. Also, to place the files into the correct folders during build, pass `+--vendor+` to `+extconf.rb+` like this:
|
||||
|
||||
....
|
||||
extconf.rb --vendor
|
||||
|
|
@ -203,13 +203,13 @@ Applications are
|
|||
* programs that provide user-level tools or
|
||||
* web applications, typically built using Rails, Sinatra or similar frameworks.
|
||||
|
||||
The RPM packages MUST obey FHS rules. They SHOULD be installed into `%{_datadir}`. The following macro can help you:
|
||||
The RPM packages MUST obey FHS rules. They SHOULD be installed into `+%{_datadir}+`. The following macro can help you:
|
||||
|
||||
....
|
||||
%global app_root %{_datadir}/%{name}
|
||||
....
|
||||
|
||||
These packages typically have no `Provides` section, since no other libraries or applications depend on them.
|
||||
These packages typically have no `+Provides+` section, since no other libraries or applications depend on them.
|
||||
|
||||
Here's an abbreviated example:
|
||||
|
||||
|
|
@ -284,15 +284,15 @@ rdoc --op %{buildroot}%{_defaultdocdir}/%{name}
|
|||
#...
|
||||
....
|
||||
|
||||
Note, that although the source is a RubyGem, we have to install the files manually under %\{_datadir}/%\{name}, %\{_bindir}, etc. to follow FHS and general packaging guidelines. If additional Fedora specific files (systemd `.service` files, configurations) are required, they SHOULD be
|
||||
Note, that although the source is a RubyGem, we have to install the files manually under %\{_datadir}/%\{name}, %\{_bindir}, etc. to follow FHS and general packaging guidelines. If additional Fedora specific files (systemd `+.service+` files, configurations) are required, they SHOULD be
|
||||
|
||||
* added via another `%SOURCE` tags
|
||||
* added via another `+%SOURCE+` tags
|
||||
|
||||
....
|
||||
Source1: deltacloudd-fedora
|
||||
....
|
||||
|
||||
* placed into appropriate locations during `%install` stage
|
||||
* placed into appropriate locations during `+%install+` stage
|
||||
|
||||
....
|
||||
install -m 0755 %{SOURCE1} %{buildroot}%{_bindir}/deltacloudd
|
||||
|
|
@ -300,13 +300,13 @@ install -m 0755 %{SOURCE1} %{buildroot}%{_bindir}/deltacloudd
|
|||
|
||||
== Running test suites
|
||||
|
||||
If there is test suite available for the package (even separately, for example not included in the gem but available in the upstream repository), it SHOULD be run in `%check`. The test suite is the only automated tool which can assure basic functionality of the package. Running it is especially helpful when mass rebuilds are required. You MAY skip test suite execution when not all build dependencies are met but this MUST be documented in the specfile. The missing build dependencies to enable the test suite SHOULD be packaged for Fedora as soon as possible and the test suite re-enabled.
|
||||
If there is test suite available for the package (even separately, for example not included in the gem but available in the upstream repository), it SHOULD be run in `+%check+`. The test suite is the only automated tool which can assure basic functionality of the package. Running it is especially helpful when mass rebuilds are required. You MAY skip test suite execution when not all build dependencies are met but this MUST be documented in the specfile. The missing build dependencies to enable the test suite SHOULD be packaged for Fedora as soon as possible and the test suite re-enabled.
|
||||
|
||||
The tests SHOULD NOT be run using Rake, as Rake almost always draws in some unnecessary dependencies like hoe or gemcutter. For similar reasons, a dependency on Bundler SHOULD be avoided. Also, code coverage frameworks such as SimpleCov and Coveralls SHOULD be avoided.
|
||||
|
||||
=== Testing With Different Ruby Implementations
|
||||
|
||||
To run tests with different Ruby implementation such as JRuby, add `BuildRequires: jruby`. Then use Rubypick's interpreter switching:
|
||||
To run tests with different Ruby implementation such as JRuby, add `+BuildRequires: jruby+`. Then use Rubypick's interpreter switching:
|
||||
|
||||
....
|
||||
ruby _jruby_ -Ilib -e 'Dir.glob "./test/test_*.rb", &method(:require)'
|
||||
|
|
@ -320,18 +320,18 @@ The Ruby community supports many testing frameworks. The following sections demo
|
|||
|
||||
==== MiniTest / Test::UNIT
|
||||
|
||||
MiniTest as well as Test::UNIT are shipped with Ruby. To use them, you need to use `BuildRequires: rubygem-minitest` or `BuildRequires: rubygem-testunit` respectively. To execute the test suite you can use something like:
|
||||
MiniTest as well as Test::UNIT are shipped with Ruby. To use them, you need to use `+BuildRequires: rubygem-minitest+` or `+BuildRequires: rubygem-testunit+` respectively. To execute the test suite you can use something like:
|
||||
|
||||
....
|
||||
%check
|
||||
ruby -Ilib -e 'Dir.glob "./test/**/*_test.rb", &method(:require)'
|
||||
....
|
||||
|
||||
You might need to adjust `-Ilib` to be `-Ilib:test`, or you could need to use a slightly different matching pattern for `test_*.rb`, etc. Packagers are expected to use the right pattern for each gem.
|
||||
You might need to adjust `+-Ilib+` to be `+-Ilib:test+`, or you could need to use a slightly different matching pattern for `+test_*.rb+`, etc. Packagers are expected to use the right pattern for each gem.
|
||||
|
||||
==== RSpec
|
||||
|
||||
To run tests using RSpec >= 3 you add `BuildRequires: rubygem-rspec` and use something like:
|
||||
To run tests using RSpec >= 3 you add `+BuildRequires: rubygem-rspec+` and use something like:
|
||||
|
||||
....
|
||||
%check
|
||||
|
|
@ -340,7 +340,7 @@ rspec -Ilib spec
|
|||
|
||||
=== Test suites not included in the package
|
||||
|
||||
Sometimes you have to get the tests separately from upstream's gem package. As an example lets suppose you're packaging `rubygem-delorean`, version 1.2.0, which is hosted on Github. Tests are not included in the Gem itself, so you need to get them and adjust the specfile accordingly:
|
||||
Sometimes you have to get the tests separately from upstream's gem package. As an example lets suppose you're packaging `+rubygem-delorean+`, version 1.2.0, which is hosted on Github. Tests are not included in the Gem itself, so you need to get them and adjust the specfile accordingly:
|
||||
|
||||
....
|
||||
# git clone https://github.com/bebanjo/delorean.git && cd delorean
|
||||
|
|
@ -366,7 +366,7 @@ popd
|
|||
# ...
|
||||
....
|
||||
|
||||
* Make sure to include the version of the tests in the source name, so that when updating to new version, rpmbuild will fail because it won't find the proper `%{SOURCE1}` (and this will remind you to update the tests, too).
|
||||
* Make sure to include the version of the tests in the source name, so that when updating to new version, rpmbuild will fail because it won't find the proper `+%{SOURCE1}+` (and this will remind you to update the tests, too).
|
||||
* Add the commands you used to get the tests into the specfile as comments. This will make it a lot easier the next time you will need to get them.
|
||||
* Run the tests as you normally would.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
__TOC__
|
||||
|
||||
This document details best practices for packaging Rust crates. Note that the rust2rpm tool, available as a Fedora package or at https://pagure.io/fedora-rust/rust2rpm, automates many of these steps. It is advisable to try `rust2rpm $crate` first before attempting to write a specfile by hand.
|
||||
This document details best practices for packaging Rust crates. Note that the rust2rpm tool, available as a Fedora package or at https://pagure.io/fedora-rust/rust2rpm, automates many of these steps. It is advisable to try `+rust2rpm $crate+` first before attempting to write a specfile by hand.
|
||||
|
||||
== Naming
|
||||
|
||||
Rust crates should be named `rust-`. Crates are expected to be from crates.io. Rust applications that aren't from crates.io SHOULD follow the main guidelines for package names.
|
||||
Rust crates should be named `+rust-+`. Crates are expected to be from crates.io. Rust applications that aren't from crates.io SHOULD follow the main guidelines for package names.
|
||||
|
||||
At this time, Rust libraries MUST be from crates.io, as this enforces a certain standard in how they are packaged and built.
|
||||
|
||||
== Dependencies
|
||||
|
||||
Packages MUST have `BuildRequires: rust-packaging`.
|
||||
Packages MUST have `+BuildRequires: rust-packaging+`.
|
||||
|
||||
=== Automatic Dependency Generation
|
||||
|
||||
`rust-packaging` automatically creates Requires/Provides based on `%cargo_registry/*/Cargo.toml` files.
|
||||
`+rust-packaging+` automatically creates Requires/Provides based on `+%cargo_registry/*/Cargo.toml+` files.
|
||||
|
||||
The Provides generator creates `crate($name) = $version` and `crate($name/$feature) = $version` for each "feature" the crate provides.
|
||||
The Provides generator creates `+crate($name) = $version+` and `+crate($name/$feature) = $version+` for each "feature" the crate provides.
|
||||
|
||||
The automatic requirement generator takes this into account and creates the appropriate rich dependency to ensure that the code works.
|
||||
|
||||
For example, `syn = { version = "0.11", features = ["visit"] }` becomes `Requires: ((crate(syn) >= 0.11.0 with crate(syn) < 0.12.0) with crate(syn/visit))`.
|
||||
For example, `+syn = { version = "0.11", features = ["visit"] }+` becomes `+Requires: ((crate(syn) >= 0.11.0 with crate(syn) < 0.12.0) with crate(syn/visit))+`.
|
||||
|
||||
=== BuildRequires
|
||||
|
||||
|
|
@ -52,11 +52,11 @@ When doing so, packagers SHOULD forward these upstream so that the upstream soft
|
|||
|
||||
== ExclusiveArch
|
||||
|
||||
All rust packages MUST have `ExclusiveArch: %{rust_arches}`.
|
||||
All rust packages MUST have `+ExclusiveArch: %{rust_arches}+`.
|
||||
|
||||
== Others
|
||||
|
||||
Packagers MUST run `%cargo_prep` to prepare configuration for further cargo invocations (sets up RUSTFLAGS and all other stuff).
|
||||
Packagers MUST run `+%cargo_prep+` to prepare configuration for further cargo invocations (sets up RUSTFLAGS and all other stuff).
|
||||
|
||||
=== Nightly, Other Platforms, etc. crates
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ As well as authentication for servers, certificates are often used to authentica
|
|||
|
||||
In this guideline, we are only concerned with _your_ certificates, where you have the corresponding private key and they are used to identify yourself.
|
||||
|
||||
These certificates are often stored in files, commonly either a PKCS#12 file (e.g. `/usr/share/doc/openvpn/sample/sample-keys/client.p12`) or a PKCS#7 or PEM file (e.g. `~/.fedora.cert`).
|
||||
These certificates are often stored in files, commonly either a PKCS#12 file (e.g. `+/usr/share/doc/openvpn/sample/sample-keys/client.p12+`) or a PKCS#7 or PEM file (e.g. `+~/.fedora.cert+`).
|
||||
|
||||
It's important that a private key remain private; if someone can take a copy of it then they can impersonate you — run a server pretending to be yours, log in to your VPN, abuse Fedora's koji system in your name, etc.
|
||||
|
||||
|
|
@ -30,9 +30,9 @@ For security reasons as described above, it's very useful to be able to import k
|
|||
|
||||
Although the use of PKCS#11 is very desirable, it can be very hard to use because each application does things differently. There has historically been no consistent way to specify which certificate to use, from which PKCS#11 provider.
|
||||
|
||||
With the pesign tool for signing EFI executables, first you need to create a NSS database and use the `modutil` tool to add your desired PKCS#11 provider to that environment. Then you can reference that token by its description and a certificate by its "nickname", which may not even be unique. For example, `-t "PIV_II (PIV Card Holder pin)" -c "Certificate for PIV Authentication"`. _(You can see this in its full horror in https://bugzilla.redhat.com/show_bug.cgi?id=1217727#1[bug 1217727].)_
|
||||
With the pesign tool for signing EFI executables, first you need to create a NSS database and use the `+modutil+` tool to add your desired PKCS#11 provider to that environment. Then you can reference that token by its description and a certificate by its "nickname", which may not even be unique. For example, `+-t "PIV_II (PIV Card Holder pin)" -c "Certificate for PIV Authentication"+`. _(You can see this in its full horror in https://bugzilla.redhat.com/show_bug.cgi?id=1217727#1[bug 1217727].)_
|
||||
|
||||
Referencing the same certificate with OpenVPN might look something like: `--pkcs11-providers=/usr/lib64/pkcs11/opensc-pkcs11.so --pkcs11-id=piv_II/PKCS\x2315\x20emulated/108421384210c3f5/PIV_II\x20\x28PIV\x20Card\x20Holder\x20pin\x29/01`
|
||||
Referencing the same certificate with OpenVPN might look something like: `+--pkcs11-providers=/usr/lib64/pkcs11/opensc-pkcs11.so --pkcs11-id=piv_II/PKCS\x2315\x20emulated/108421384210c3f5/PIV_II\x20\x28PIV\x20Card\x20Holder\x20pin\x29/01+`
|
||||
|
||||
With wpa_supplicant it's different again, as shown at http://w1.fi/cgit/hostap/plain/wpa_supplicant/examples/openCryptoki.conf
|
||||
|
||||
|
|
@ -44,15 +44,15 @@ There are two parts to the problem — there's the question of which PKCS#11 pro
|
|||
|
||||
In Fedora _(as with most other modern Linux and *NIX systems)_ this question is answered by http://p11-glue.freedesktop.org/[p11-kit]. A Fedora package containing a PKCS#11 provider module, such as the https://github.com/OpenSC/OpenSC/wiki[OpenSC] one which supports most major hardware smart cards, will automatically drop a config file into the appropriate place and then its module will automatically appear in well-behaved software which is integrated with the platform and uses p11-kit properly.
|
||||
|
||||
Applications can either link against `libp11-kit` and use its functionality for loading and handling PKCS#11 provider libraries, or there is a simpler option: `p11-kit-proxy.so` is a PKCS#11 provider module in its own right which inspects the system's configuration and loads the appropriate modules — as the name implies, _proxying_ them as slots of itself.
|
||||
Applications can either link against `+libp11-kit+` and use its functionality for loading and handling PKCS#11 provider libraries, or there is a simpler option: `+p11-kit-proxy.so+` is a PKCS#11 provider module in its own right which inspects the system's configuration and loads the appropriate modules — as the name implies, _proxying_ them as slots of itself.
|
||||
|
||||
If you have an application which is already capable of using PKCS#11 but which doesn't know about p11-kit, it will mostly _need_ a PKCS#11 provider module to be explicitly specified. All you need to do is make it use `p11-kit-proxy.so` if the user didn't specify anything else, and it should Do The Right Thing.
|
||||
If you have an application which is already capable of using PKCS#11 but which doesn't know about p11-kit, it will mostly _need_ a PKCS#11 provider module to be explicitly specified. All you need to do is make it use `+p11-kit-proxy.so+` if the user didn't specify anything else, and it should Do The Right Thing.
|
||||
|
||||
=== How to specify a certificate?
|
||||
|
||||
In April 2015, https://tools.ietf.org/html/rfc7512[RFC7512] defined a 'PKCS#11 URI' as a standard way to identify such objects.
|
||||
|
||||
This form is already accepted by some programs such as the OpenConnect VPN client. The certificate used in the above examples can be simply used as a client authentication certificate by adding the command-line option `-c '`pkcs11:manufacturer=piv_II;id=%01[`pkcs11:manufacturer=piv_II;id=%01`]`'`.
|
||||
This form is already accepted by some programs such as the OpenConnect VPN client. The certificate used in the above examples can be simply used as a client authentication certificate by adding the command-line option `+-c '+`pkcs11:manufacturer=piv_II;id=%01[`+pkcs11:manufacturer=piv_II;id=%01+`]`+'+`.
|
||||
|
||||
== Proposal
|
||||
|
||||
|
|
@ -66,27 +66,27 @@ This form is already accepted by some programs such as the OpenConnect VPN clien
|
|||
|
||||
=== PKCS#11 Providers
|
||||
|
||||
* Packages providing a PKCS#11 module DSO file SHOULD also provide a corresponding http://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html#config-module[module configuration file] in the directory specified by `pkg-config p11-kit-1 --variable p11_module_configs` _(currently `/usr/share/p11-kit/modules`)_ so that the new module is automatically visible in well-behaved applications.
|
||||
* Packages providing a PKCS#11 module DSO file SHOULD also provide a corresponding http://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html#config-module[module configuration file] in the directory specified by `+pkg-config p11-kit-1 --variable p11_module_configs+` _(currently `+/usr/share/p11-kit/modules+`)_ so that the new module is automatically visible in well-behaved applications.
|
||||
|
||||
`Packages providing PKCS#11 module DSO file SHOULD also provide a corresponding module configuration file`
|
||||
`+Packages providing PKCS#11 module DSO file SHOULD also provide a corresponding module configuration file+`
|
||||
|
||||
== Rationale
|
||||
|
||||
By consistently using p11-kit for token configuration, and PKCS#11 URIs for specifying objects, we make things a lot simpler for Fedora users. If I want to use a certain certificate from my Yubikey, I should be able to use the URI pkcs11:manufacturer=piv_II;id=%01[`pkcs11:manufacturer=piv_II;id=%01`] consistently in *all* applications within Fedora and expect it to work.
|
||||
By consistently using p11-kit for token configuration, and PKCS#11 URIs for specifying objects, we make things a lot simpler for Fedora users. If I want to use a certain certificate from my Yubikey, I should be able to use the URI pkcs11:manufacturer=piv_II;id=%01[`+pkcs11:manufacturer=piv_II;id=%01+`] consistently in *all* applications within Fedora and expect it to work.
|
||||
|
||||
== Examples
|
||||
|
||||
=== OpenVPN
|
||||
|
||||
To fix OpenVPN, we first https://community.openvpn.net/openvpn/ticket/490[fixed it] to load `p11-kit-proxy.so` by default _(thus making the correct tokens visible)_, And then we fixed its "serialisation" format for how it identifies objects. This was actually in the pkcs11-helper library, and is fixed https://github.com/OpenSC/pkcs11-helper/pull/4[here].
|
||||
To fix OpenVPN, we first https://community.openvpn.net/openvpn/ticket/490[fixed it] to load `+p11-kit-proxy.so+` by default _(thus making the correct tokens visible)_, And then we fixed its "serialisation" format for how it identifies objects. This was actually in the pkcs11-helper library, and is fixed https://github.com/OpenSC/pkcs11-helper/pull/4[here].
|
||||
|
||||
=== OpenSSL engine_pkcs11
|
||||
|
||||
Similar https://github.com/OpenSC/engine_pkcs11/pull/9[fixes] were submitted to engine_pkcs11 (now in F22+) to make it load `p11-kit-proxy.so` as its default provider if none is specified, and to make it accept the RFC7512 standard object URIs in place of its own legacy format.
|
||||
Similar https://github.com/OpenSC/engine_pkcs11/pull/9[fixes] were submitted to engine_pkcs11 (now in F22+) to make it load `+p11-kit-proxy.so+` as its default provider if none is specified, and to make it accept the RFC7512 standard object URIs in place of its own legacy format.
|
||||
|
||||
=== wpa_supplicant
|
||||
|
||||
Since wpa_supplicant uses engine_pkcs11, much of the work was already done. All that remained was to make it automatically use the PKCS#11 engine when it detected a "filename" starting with '`pkcs11:`'. (http://w1.fi/cgit/hostap/commit/?id=01b0d1d5c1d5598fc92580f2804507d61faf0453[sample commit])
|
||||
Since wpa_supplicant uses engine_pkcs11, much of the work was already done. All that remained was to make it automatically use the PKCS#11 engine when it detected a "filename" starting with '`+pkcs11:+`'. (http://w1.fi/cgit/hostap/commit/?id=01b0d1d5c1d5598fc92580f2804507d61faf0453[sample commit])
|
||||
|
||||
== Expectations
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ However, it is certainly within the purview of a packager to work with the upstr
|
|||
|
||||
Most importantly, it is often the case that software can be built with more than one crypto library, and the feature set available will depend on that choice. For example the OpenConnect VPN client will comply with all of the above requirements when built with GnuTLS, but not when built with OpenSSL. This much certainly is within the direct control of the packager.
|
||||
|
||||
Likewise, sometimes all that is required is to configure a piece of software to use `p11-kit-proxy.so` as its PKCS#11 provider module by default. The `p11-kit-proxy.so` module is a simple PKCS#11 provider which will read the system's p11-kit configuration and load all the configured modules for itself, providing a kind of 'proxy'. Again, that's certainly something a packager can do.
|
||||
Likewise, sometimes all that is required is to configure a piece of software to use `+p11-kit-proxy.so+` as its PKCS#11 provider module by default. The `+p11-kit-proxy.so+` module is a simple PKCS#11 provider which will read the system's p11-kit configuration and load all the configured modules for itself, providing a kind of 'proxy'. Again, that's certainly something a packager can do.
|
||||
|
||||
With that in mind, what we ask of packagers is this:
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ With that in mind, what we ask of packagers is this:
|
|||
|
||||
* If it can use SSL client certificates, check and see if it can use PKCS#11. If not, please file an upstream bug.
|
||||
|
||||
* If the package can support PKCS#11, make sure it is either fully integrated with libp11-kit to load the correct modules, or at _least_ that it can be configured to load `p11-kit-proxy.so` as its default PKCS#11 provider when the user doesn't explicitly specify one. If not, please file an upstream bug.
|
||||
* If the package can support PKCS#11, make sure it is either fully integrated with libp11-kit to load the correct modules, or at _least_ that it can be configured to load `+p11-kit-proxy.so+` as its default PKCS#11 provider when the user doesn't explicitly specify one. If not, please file an upstream bug.
|
||||
|
||||
* If the package can support PKCS#11, make sure it can accept RFC7512 PKCS#11 URIs as the way to specify certificates. If not, again please file an upstream bug.
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ fi
|
|||
|
||||
...for %pre and %post scripts rather than checking that it equals 2.
|
||||
|
||||
All scriptlets MUST exit with the zero exit status. Because RPM in its default configuration does not execute shell scriptlets with the `-e` argument to the shell, excluding explicit `exit` calls (frowned upon with a non-zero argument!), the exit status of the last command in a scriptlet determines its exit status. Most commands in the snippets in this document have a "`|| :`" appended to them, which is a generic trick to force the zero exit status for those commands whether they worked or not. Usually the most important bit is to apply this to the last command executed in a scriptlet, or to add a separate command such as plain "`:`" or "`exit 0`" as the last one in a scriptlet. Note that depending on the case, other error checking/prevention measures may be more appropriate.
|
||||
All scriptlets MUST exit with the zero exit status. Because RPM in its default configuration does not execute shell scriptlets with the `+-e+` argument to the shell, excluding explicit `+exit+` calls (frowned upon with a non-zero argument!), the exit status of the last command in a scriptlet determines its exit status. Most commands in the snippets in this document have a "`+|| :+`" appended to them, which is a generic trick to force the zero exit status for those commands whether they worked or not. Usually the most important bit is to apply this to the last command executed in a scriptlet, or to add a separate command such as plain "`+:+`" or "`+exit 0+`" as the last one in a scriptlet. Note that depending on the case, other error checking/prevention measures may be more appropriate.
|
||||
|
||||
Non-zero exit codes from scriptlets can break installs/upgrades/erases such that no further actions will be taken for that package in a transaction (see link:#Scriptlet_Ordering[#Scriptlet Ordering] below), which may for example prevent an old version of a package from being erased on upgrades, leaving behind duplicate rpmdb entries and possibly stale, unowned files on the filesystem. There are some cases where letting the transaction to proceed when some things in scriptlets failed may result in partially broken setup. It is however often limited to that package only whereas letting a transaction to proceed with some packages dropped out on the fly is more likely to result in broader system wide problems.
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ The scriptlets in %pre and %post are respectively run before and after a package
|
|||
|
||||
=== 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 http://rpm.org/user_doc/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 http://rpm.org/user_doc/lua.html for more information.
|
||||
|
||||
== Writing Scriptlets
|
||||
|
||||
|
|
@ -70,10 +70,10 @@ Some tips for writing good 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.
|
||||
* 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.
|
||||
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
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ If RPM file triggers are not appropriate, complex scriptlets which are shared be
|
|||
|
||||
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.
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ Of course, in the above situation it is better to use RPM file triggers if at al
|
|||
|
||||
On Fedora 28 and newer, no scriptlets are required when shared libraries are installed. However, the following scriptlets MAY be used, as they will simply evaluate to nothing on newer Fedora releases.
|
||||
|
||||
On Fedora 27 and older, ldconfig MUST be called properly in order to regenerate the dynamic linker's cache. If the package or subpackage has no existing `%post` or `%postun` scriptlets, simply include the `%ldconfig_scriptlets` macro on its own line before the %files list.
|
||||
On Fedora 27 and older, ldconfig MUST be called properly in order to regenerate the dynamic linker's cache. If the package or subpackage has no existing `+%post+` or `+%postun+` scriptlets, simply include the `+%ldconfig_scriptlets+` macro on its own line before the %files list.
|
||||
|
||||
....
|
||||
[...]
|
||||
|
|
@ -108,22 +108,22 @@ On Fedora 27 and older, ldconfig MUST be called properly in order to regenerate
|
|||
[...]
|
||||
....
|
||||
|
||||
Using the `%ldconfig_scriptlets` macro will automatically generate a dependency on ldconfig where necessary. The macro will do nothing at all on F28 and later releases.
|
||||
Using the `+%ldconfig_scriptlets+` macro will automatically generate a dependency on ldconfig where necessary. The macro will do nothing at all on F28 and later releases.
|
||||
|
||||
If the package or subpackage already has existing `%post` or `%postun` scriptlet, then use of `%ldconfig_scriptlets` will cause an error. You can use `%ldconfig_post` or `%ldconfig_postun` individually to generate a scriptlet which doesn't already conflict.
|
||||
If the package or subpackage already has existing `+%post+` or `+%postun+` scriptlet, then use of `+%ldconfig_scriptlets+` will cause an error. You can use `+%ldconfig_post+` or `+%ldconfig_postun+` individually to generate a scriptlet which doesn't already conflict.
|
||||
|
||||
Within an existing `%post` or `%postun` scriptlet, use `%{?ldconfig}` on its own line to call ldconfig on those releases which need it. This will do nothing when not needed. When calling ldconfig in this way, you MUST also have the proper dependency on /sbin/ldconfig: `Requires(post): /sbin/ldconfig` and/or `Requires(postun): /sbin/ldconfig` as appropriate. (This will generate an unnecessary dependency on releases which do not strictly need it, but this does no harm.)
|
||||
Within an existing `+%post+` or `+%postun+` scriptlet, use `+%{?ldconfig}+` on its own line to call ldconfig on those releases which need it. This will do nothing when not needed. When calling ldconfig in this way, you MUST also have the proper dependency on /sbin/ldconfig: `+Requires(post): /sbin/ldconfig+` and/or `+Requires(postun): /sbin/ldconfig+` as appropriate. (This will generate an unnecessary dependency on releases which do not strictly need it, but this does no harm.)
|
||||
|
||||
=== 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 28 and newer. 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 28 and newer. Instead simply call `+/sbin/ldconfig+` directly in both `+%post+` and `+%postun+` as well as adding the necessary dependencies when necessary:
|
||||
|
||||
....
|
||||
%post -p /sbin/ldconfig
|
||||
%postun -p /sbin/ldconfig
|
||||
....
|
||||
|
||||
or, as part of existing `%post` or `%postun` scriptlets:
|
||||
or, as part of existing `+%post+` or `+%postun+` scriptlets:
|
||||
|
||||
....
|
||||
Requires(post): /sbin/ldconfig
|
||||
|
|
@ -139,7 +139,7 @@ Requires(postun): /sbin/ldconfig
|
|||
[...]
|
||||
....
|
||||
|
||||
In addition, in Fedora 28 or newer the following applies: If the configuration file added to `/etc/ld.so.conf.d` specifies a directory into which other other packages may install files, and that directory is not located in the directory hierarchy beneath one of `/lib`, /usr/lib</code, `/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:
|
||||
In addition, in Fedora 28 or newer the following applies: If the configuration file added to `+/etc/ld.so.conf.d+` specifies a directory into which other other packages may install files, and that directory is not located in the directory hierarchy beneath one of `+/lib+`, /usr/lib</code, `+/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
|
||||
|
|
@ -149,7 +149,7 @@ In addition, in Fedora 28 or newer the following applies: If the configuration f
|
|||
/sbin/ldconfig
|
||||
....
|
||||
|
||||
Replace `DIRECTORIES` with the space-separated list of directories which the package adds to 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 to the library search path via the configuration files in `+/etc/ld.so.conf.d+`.
|
||||
|
||||
=== Users and groups
|
||||
|
||||
|
|
@ -195,20 +195,20 @@ Requires(preun): GConf2
|
|||
|
||||
In this section we uninstall old schemas during upgrade using one of two macros.
|
||||
|
||||
`%gconf_schema_prepare` is used for any current GConf schemas. It
|
||||
`+%gconf_schema_prepare+` is used for any current GConf schemas. It
|
||||
takes care of uninstalling previous versions of schemas that this package
|
||||
currently installs. It takes a space separated list of schema names without
|
||||
path or suffix that the package installs. Note that behind the scenes, this
|
||||
macro works with the `%post` scriptlet to only process GConf schemas
|
||||
macro works with the `+%post+` scriptlet to only process GConf schemas
|
||||
if changes have occurred.
|
||||
|
||||
`%gconf_schema_obsolete` is used for schemas that this package
|
||||
`+%gconf_schema_obsolete+` is used for schemas that this package
|
||||
previously provided but no longer does. It will deregister the old schema if
|
||||
it is present on the system. Nothing will happen if the old schema is not
|
||||
present. This macro takes a space separated list of schemas to uninstall. One
|
||||
example of using this might be if the package changed names. If the old schema
|
||||
was named `foo.schemas` and the new schema is named
|
||||
`foobar.schemas` you'd use:
|
||||
was named `+foo.schemas+` and the new schema is named
|
||||
`+foobar.schemas+` you'd use:
|
||||
|
||||
....
|
||||
%gconf_schema_prepare foobar
|
||||
|
|
@ -222,8 +222,8 @@ The next section does the processing of the newly installed schemas:
|
|||
%gconf_schema_upgrade schema1 schema2
|
||||
....
|
||||
|
||||
`%gconf_schema_upgrade` takes a space separated list of schemas that
|
||||
the package currently installs just like `%gconf_schema_prepare`.
|
||||
`+%gconf_schema_upgrade+` takes a space separated list of schemas that
|
||||
the package currently installs just like `+%gconf_schema_prepare+`.
|
||||
Behind the scenes, it does the actual work of registering the new version of
|
||||
the schema and deregistering the old version.
|
||||
|
||||
|
|
@ -234,9 +234,9 @@ The last section is for unregistering schemas when a package is removed:
|
|||
%gconf_schema_remove schema1 schema2
|
||||
....
|
||||
|
||||
When a package is upgraded rpm invokes the `%pre` scriptlet to register
|
||||
When a package is upgraded rpm invokes the `+%pre+` scriptlet to register
|
||||
and deregister the schemas. When a package is uninstalled, the
|
||||
`%preun` scriptlet is used. `%gconf_schema_remove` takes
|
||||
`+%preun+` scriptlet is used. `+%gconf_schema_remove+` takes
|
||||
the list of schemas that this package currently provides and removes them for us.
|
||||
|
||||
==== Rebuilds for changes to macros
|
||||
|
|
@ -279,7 +279,7 @@ Packages containing systemd unit files need to use scriptlets to ensure proper h
|
|||
|
||||
==== Scriptlets
|
||||
|
||||
The systemd package provides a set of helper macros to handle systemd scriptlet operations. These macros support systemd "presets", as documented in Features/PackagePresets. The `%systemd_requires` macro is a shortcut for listing the per-scriptlet dependencies on systemd.
|
||||
The systemd package provides a set of helper macros to handle systemd scriptlet operations. These macros support systemd "presets", as documented in Features/PackagePresets. The `+%systemd_requires+` macro is a shortcut for listing the per-scriptlet dependencies on systemd.
|
||||
|
||||
....
|
||||
%{?systemd_requires}
|
||||
|
|
@ -296,7 +296,7 @@ BuildRequires: systemd
|
|||
%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
|
||||
|
|
@ -305,11 +305,11 @@ Some services do not support being restarted (e.g. D-Bus and various storage dae
|
|||
|
||||
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 Packaging:DefaultServices[ Fedora preset policy].
|
||||
|
||||
If a package is suitable for installation without systemd (in a container image, for example) and does not require any of the systemd mechanisms such as tmpfiles.d, then the `%systemd_ordering` macro MAY be used instead of the `%systemd_requires` macro.
|
||||
If a package is suitable for installation without systemd (in a container image, for example) and does not require any of the systemd mechanisms such as tmpfiles.d, then the `+%systemd_ordering+` macro MAY be used instead of the `+%systemd_requires+` macro.
|
||||
|
||||
===== 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+`).
|
||||
|
||||
....
|
||||
%{?systemd_requires}
|
||||
|
|
@ -332,10 +332,10 @@ http://www.freedesktop.org/software/systemd/man/daemon.html.
|
|||
|
||||
=== 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.
|
||||
`+/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":
|
||||
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
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ tar -czvf libfoo-$VERSION-nopatents.tar.gz libfoo-$VERSION
|
|||
|
||||
== Python Packages (pypi)
|
||||
|
||||
As Pypi has moved to storing files in directories which change depending on the file being stored, it is rather unpleasant to use in a Source: URL. Instead, files.pythonhosted.org can be used as follows, where `%srcname` is the project's name on pypi and is the first letter of that name. (See also the sample python spec Packaging:Python#Example_common_spec_file[here]).
|
||||
As Pypi has moved to storing files in directories which change depending on the file being stored, it is rather unpleasant to use in a Source: URL. Instead, files.pythonhosted.org can be used as follows, where `+%srcname+` is the project's name on pypi and is the first letter of that name. (See also the sample python spec Packaging:Python#Example_common_spec_file[here]).
|
||||
|
||||
....
|
||||
Source0: https://files.pythonhosted.org/packages/source/<first_letter>/%{srcname}/%{srcname}-%{version}.tar.gz
|
||||
|
|
@ -76,7 +76,7 @@ Source0: https://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz
|
|||
|
||||
changing ".tar.gz" to whatever matches the upstream distribution. Note that we are using downloads.sourceforge.net instead of an arbitrarily chosen mirror. You may use the package name/package version instead of the %\{name} and %\{version} macros, of course.
|
||||
|
||||
Please note that the correct url is `downloads.sourceforge.net`, and *NOT* `download.sourceforge.net`.
|
||||
Please note that the correct url is `+downloads.sourceforge.net+`, and *NOT* `+download.sourceforge.net+`.
|
||||
|
||||
== Git Hosting Services
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ When upstream has URLs for the download that do not end with the tarball name rp
|
|||
Source0: http://example.com/foo/1.0/download.cgi#/%{name}-%{version}.tar.gz
|
||||
....
|
||||
|
||||
rpm will then use %\{name}-%\{version}.tar.gz as the tarball name. If you use `spectool -g foo.spec` to download the tarball, it will rename the tarball for you.
|
||||
rpm will then use %\{name}-%\{version}.tar.gz as the tarball name. If you use `+spectool -g foo.spec+` to download the tarball, it will rename the tarball for you.
|
||||
|
||||
Sometimes this does not work because the upstream cgi tries to parse the fragment or because you need to login or fill in a form to access the tarball. In these cases, you have to put just the tarball's filename into the Source: tag. To make clear where you got the tarball, you should leave notes in comments above the Source: line to explain the situation to reviewers and future packagers. For example:
|
||||
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ BuildRequires: sugar-toolkit
|
|||
|
||||
== Naming
|
||||
|
||||
All activities *MUST* be named `sugar-`.
|
||||
All activities *MUST* be named `+sugar-+`.
|
||||
|
||||
== Architecture-specific Activities
|
||||
|
||||
All activities containing compiled code (thus, architecture-specific) must be built in the %build section. Any architecture-specific bits must either go in `%{_bindir}` `%{_libdir}` or `%{sugarlibdir}` as appropriate.
|
||||
All activities containing compiled code (thus, architecture-specific) must be built in the %build section. Any architecture-specific bits must either go in `+%{_bindir}+` `+%{_libdir}+` or `+%{sugarlibdir}+` as appropriate.
|
||||
|
||||
== Runtime Dependencies
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ This document describes the guidelines for systemd services, for use and inclusi
|
|||
Since systemd includes some concepts which are extensions of previous concepts, the following definitions may be useful:
|
||||
|
||||
Service: A process or task executed and controlled by the init system (e.g. systemd). +
|
||||
Traditional Service: A service which is explicitly started or stopped, either by the init system at boot or manually by a superuser. In systemd, one of several types of service controlled by a `.service` file. +
|
||||
Traditional Service: A service which is explicitly started or stopped, either by the init system at boot or manually by a superuser. In systemd, one of several types of service controlled by a `+.service+` file. +
|
||||
Activated service: A service that is not (or not necessarily) started explicitly by the user but start when certain other events happen or certain state becomes true. +
|
||||
Socket-activated Service: A service which is waiting for traffic across a socket before activating. In systemd, controlled by a `.socket` file. +
|
||||
Socket-activated Service: A service which is waiting for traffic across a socket before activating. In systemd, controlled by a `+.socket+` file. +
|
||||
D-Bus service: A service which activates in response to a message from the D-Bus system bus. +
|
||||
Unit file: The systemd equivalent of a SysV initscript. +
|
||||
|
||||
|
|
@ -26,19 +26,19 @@ on http://0pointer.de/public/systemd-man/daemon.html
|
|||
|
||||
==== Naming
|
||||
|
||||
Unit files for traditional services have a naming scheme of foobar.service. When considering what basename to use, keep in mind that we'd like to use the same service names for software across distributions. We'd also like to ship the `.service` files in the upstream packages. These desires create a few guides for naming a unit file:
|
||||
Unit files for traditional services have a naming scheme of foobar.service. When considering what basename to use, keep in mind that we'd like to use the same service names for software across distributions. We'd also like to ship the `+.service+` files in the upstream packages. These desires create a few guides for naming a unit file:
|
||||
|
||||
* Follow upstream if they're already distributing a `.service` file and it's not likely to conflict with other packages.
|
||||
* Follow upstream if they're already distributing a `+.service+` file and it's not likely to conflict with other packages.
|
||||
* Look at packages in other distros or talk with the maintainers of those packages and upstream to try to come up with a common name.
|
||||
* Unit files should be named after the software implementation that they support as opposed to the generic type of software. So, a good name would be `apache-httpd.service` and bad names would be `httpd.service` or `apache.service` as there are multiple httpd implementations and multiple projects produced by the apache foundation.
|
||||
* Unit files should be named after the software implementation that they support as opposed to the generic type of software. So, a good name would be `+apache-httpd.service+` and bad names would be `+httpd.service+` or `+apache.service+` as there are multiple httpd implementations and multiple projects produced by the apache foundation.
|
||||
|
||||
For backwards compatibility you may also want to create a symlink from an older, name to the new name. In the above example, for instance, Fedora has always used `httpd` for the service. When creating the new `apache-httpd.service` file, also create a symlink named `httpd.service` that points at `apache-httpd.service`. Then end users that are used to using `service httpd` will have it continue to work.
|
||||
For backwards compatibility you may also want to create a symlink from an older, name to the new name. In the above example, for instance, Fedora has always used `+httpd+` for the service. When creating the new `+apache-httpd.service+` file, also create a symlink named `+httpd.service+` that points at `+apache-httpd.service+`. Then end users that are used to using `+service httpd+` will have it continue to work.
|
||||
|
||||
==== Basic format
|
||||
|
||||
===== [Unit]
|
||||
|
||||
Every `.service` file must begin with a `[Unit]` section:
|
||||
Every `+.service+` file must begin with a `+[Unit]+` section:
|
||||
|
||||
....
|
||||
[Unit]
|
||||
|
|
@ -46,7 +46,7 @@ Description=A brief human readable string describing the service (not the .servi
|
|||
Documentation=man:foo.service(8) man:foo.conf(5) http://www.foo.org/docs/
|
||||
....
|
||||
|
||||
The `Description=` line must not exceed 80 characters, and must describe the service, and not the `.service` file. For example, "Apache Web Server" is a good description, but "Starts and Stops the Apache Web Server" is a bad one.
|
||||
The `+Description=+` line must not exceed 80 characters, and must describe the service, and not the `+.service+` file. For example, "Apache Web Server" is a good description, but "Starts and Stops the Apache Web Server" is a bad one.
|
||||
|
||||
====== Documentation field
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ Systemd in Fedora 17+ has support for defining documentation in unit files via t
|
|||
|
||||
===== [Service]
|
||||
|
||||
Next, the `.service` file must have a `[Service]` section:
|
||||
Next, the `+.service+` file must have a `+[Service]+` section:
|
||||
|
||||
....
|
||||
[Service]
|
||||
|
|
@ -63,38 +63,38 @@ ExecStart=...
|
|||
ExecReload=...
|
||||
....
|
||||
|
||||
The `Type=` setting is very important. For D-Bus services this
|
||||
The `+Type=+` setting is very important. For D-Bus services this
|
||||
should be "dbus", for traditional services "forking" is usually a good idea,
|
||||
for services not offering any interfaces to other services "simple" is best.
|
||||
For "one-shot" scripts "oneshot" is ideal, often combined with
|
||||
`RemainAfterExit=`. See
|
||||
`+RemainAfterExit=+`. See
|
||||
http://0pointer.de/public/systemd-man/systemd.service.html for further
|
||||
discussion on the topic. Since "simple" is the default type,
|
||||
`.service` files which would normally set `Type=simple` may simply
|
||||
omit the `Type` line altogether.
|
||||
`+.service+` files which would normally set `+Type=simple+` may simply
|
||||
omit the `+Type+` line altogether.
|
||||
|
||||
`BusName=` should be set for all services connecting to D-Bus. (i.e. it is a must for those where `Type=dbus`, but might make sense otherwise, too) Omit this option if your service does not take a name on the bus.
|
||||
`+BusName=+` should be set for all services connecting to D-Bus. (i.e. it is a must for those where `+Type=dbus+`, but might make sense otherwise, too) Omit this option if your service does not take a name on the bus.
|
||||
|
||||
`ExecStart=` is necessary for all services. This line defines the string that you would run to start the daemon, along with any necessary options.
|
||||
`+ExecStart=+` is necessary for all services. This line defines the string that you would run to start the daemon, along with any necessary options.
|
||||
|
||||
`ExecReload=` should be specified for all services supporting reload. It is highly recommended to add code here that synchronously reloads the configuration file here (i.e. `/bin/kill -HUP $MAINPID` is usually a poor choice, due to its asynchronous nature). Omit this option if your service does not support reloading.
|
||||
`+ExecReload=+` should be specified for all services supporting reload. It is highly recommended to add code here that synchronously reloads the configuration file here (i.e. `+/bin/kill -HUP $MAINPID+` is usually a poor choice, due to its asynchronous nature). Omit this option if your service does not support reloading.
|
||||
|
||||
===== [Install]
|
||||
|
||||
Finally, the `.service` file should have an `[Install]` section:
|
||||
Finally, the `+.service+` file should have an `+[Install]+` section:
|
||||
|
||||
....
|
||||
[Install]
|
||||
WantedBy=...
|
||||
....
|
||||
|
||||
The recommended parameters for `WantedBy=` are either `graphical.target` (services related to the graphical user interface) or `multi-user.target` (for everything else). When the user (or our scriptlets) invoke `systemctl enable` the service will be set to start in these targets.
|
||||
The recommended parameters for `+WantedBy=+` are either `+graphical.target+` (services related to the graphical user interface) or `+multi-user.target+` (for everything else). When the user (or our scriptlets) invoke `+systemctl enable+` the service will be set to start in these targets.
|
||||
|
||||
For more information regarding these options see http://0pointer.de/public/systemd-man/systemd.unit.html and http://0pointer.de/public/systemd-man/systemd.service.html
|
||||
|
||||
==== EnvironmentFiles and support for /etc/sysconfig files
|
||||
|
||||
The `EnvironmentFiles=` line in the `[Service]` section of `.service` files is used to support loading environment variables that can be used in unit files. For instance, if your sysv-initscript used a file in /etc/sysconfig to set command line options, you can use `EnvironmentFiles=` like so:
|
||||
The `+EnvironmentFiles=+` line in the `+[Service]+` section of `+.service+` files is used to support loading environment variables that can be used in unit files. For instance, if your sysv-initscript used a file in /etc/sysconfig to set command line options, you can use `+EnvironmentFiles=+` like so:
|
||||
|
||||
Example:
|
||||
|
||||
|
|
@ -106,51 +106,51 @@ ExecStart=/usr/sbin/httpd $OPTIONS
|
|||
ExecReload=/usr/sbin/httpd $OPTIONS -k restart
|
||||
....
|
||||
|
||||
You may then refer to variables set in the `/etc/sysconfig/httpd` file with
|
||||
`${FOOBAR}` and `$FOOBAR`, in the `ExecStart=`
|
||||
lines (and related lines). (`${FOOBAR}` expands the variable into
|
||||
one word, `$FOOBAR` splits up the variable value at whitespace into
|
||||
You may then refer to variables set in the `+/etc/sysconfig/httpd+` file with
|
||||
`+${FOOBAR}+` and `+$FOOBAR+`, in the `+ExecStart=+`
|
||||
lines (and related lines). (`+${FOOBAR}+` expands the variable into
|
||||
one word, `+$FOOBAR+` splits up the variable value at whitespace into
|
||||
multiple words)
|
||||
|
||||
The "-" on the `EnvironmentFile=` line ensures that no error messages is generated if the environment file does not exist. Since many of these files were optional in sysvinit, you should include the "-" when using this directive.
|
||||
The "-" on the `+EnvironmentFile=+` line ensures that no error messages is generated if the environment file does not exist. Since many of these files were optional in sysvinit, you should include the "-" when using this directive.
|
||||
|
||||
==== Fields to avoid
|
||||
|
||||
For most services, we do not want to use requirement dependencies in the
|
||||
`[Unit]` section, such as `Requires=` or
|
||||
`Wants=`. Instead exclusively use ordering dependencies: `Before=` and
|
||||
`After=`. This is used to implement loose coupling: if someone asks two services
|
||||
`+[Unit]+` section, such as `+Requires=+` or
|
||||
`+Wants=+`. Instead exclusively use ordering dependencies: `+Before=+` and
|
||||
`+After=+`. This is used to implement loose coupling: if someone asks two services
|
||||
to start at the same time, systemd will properly order their startup but not
|
||||
make it strictly necessary to run one if the other is started.
|
||||
|
||||
If you use a requirement dependency, use `Wants=` rather than
|
||||
`Requires=`, to make things a little bit more robust. If you use a
|
||||
If you use a requirement dependency, use `+Wants=+` rather than
|
||||
`+Requires=+`, to make things a little bit more robust. If you use a
|
||||
requirement dependency in almost all cases you should also add an ordering
|
||||
dependency, as ordering and requirement dependencies are orthogonal in systemd.
|
||||
|
||||
Here's an example of this common case:
|
||||
|
||||
1. A web application needs postgresql to store its data.
|
||||
2. It is set to start `After` postgresql. On startup, the web application does not start until postgresql does.
|
||||
2. It is set to start `+After+` postgresql. On startup, the web application does not start until postgresql does.
|
||||
3. Once running, the system administrator needs to restart postgresql due to a config tweak.
|
||||
4. Since only `After` was used, the web application may be temporarily unable to serve some requests but it does not need to restart in order to serve pages after the database comes back up.
|
||||
4. Since only `+After+` was used, the web application may be temporarily unable to serve some requests but it does not need to restart in order to serve pages after the database comes back up.
|
||||
|
||||
Avoid referring to `runlevelX.target` units in all lines taking unit names (such as `WantedBy`), these are legacy names existing for compatibility with SysV only.
|
||||
Avoid referring to `+runlevelX.target+` units in all lines taking unit names (such as `+WantedBy+`), these are legacy names existing for compatibility with SysV only.
|
||||
|
||||
Avoid `Names=` (in the `[Unit]` section). Usually it is a
|
||||
Avoid `+Names=+` (in the `+[Unit]+` section). Usually it is a
|
||||
better idea to symlink an additional name in the file system. Note that a name
|
||||
listed in `Names=` is only useful when a service file is already loaded. However,
|
||||
listed in `+Names=+` is only useful when a service file is already loaded. However,
|
||||
systemd loads only the service files actually referred to in another loaded
|
||||
service, and uses the filenames during the search. Hence a name in `Names=` is
|
||||
service, and uses the filenames during the search. Hence a name in `+Names=+` is
|
||||
not useful as a search key, but a symlink in the file system is. Also do not
|
||||
put a (redundant) `Names=foobar.service` line into a file called `foobar.service`.
|
||||
put a (redundant) `+Names=foobar.service+` line into a file called `+foobar.service+`.
|
||||
We want to keep our service files short.
|
||||
|
||||
Unit files should avoid using `StandardOutput=` or `StandardError=`. The default is the right choice for almost all cases, and using the default allows users to change global defaults in /etc/systemd/system.conf.
|
||||
Unit files should avoid using `+StandardOutput=+` or `+StandardError=+`. The default is the right choice for almost all cases, and using the default allows users to change global defaults in /etc/systemd/system.conf.
|
||||
|
||||
==== Example Unit file
|
||||
|
||||
This is an example systemd unit `.service` file for ABRT:
|
||||
This is an example systemd unit `+.service+` file for ABRT:
|
||||
|
||||
....
|
||||
[Unit]
|
||||
|
|
@ -171,7 +171,7 @@ Systemd allows for three forms of activated services: link:#Hardware_activation[
|
|||
|
||||
==== Hardware activation
|
||||
|
||||
Hardware activation occurs when a service is installed but only turns on if a certain type of hardware is installed. Enabling of the service is normally done with a udev rule. At this time we do not have further guidance on how to write those udev rules. The service itself installs its `.service` files in the normal places and are installed by the normal Packaging:ScriptletSnippets#Systemd[ systemd scriptlets]. These services should never be enabled by the package as they will be enabled by udev.
|
||||
Hardware activation occurs when a service is installed but only turns on if a certain type of hardware is installed. Enabling of the service is normally done with a udev rule. At this time we do not have further guidance on how to write those udev rules. The service itself installs its `+.service+` files in the normal places and are installed by the normal Packaging:ScriptletSnippets#Systemd[ systemd scriptlets]. These services should never be enabled by the package as they will be enabled by udev.
|
||||
|
||||
==== Socket activation
|
||||
|
||||
|
|
@ -179,15 +179,15 @@ Socket activation occurs when a service allows systemd to listen for
|
|||
connections to a specific socket and, when systemd receives a connection on
|
||||
that socket, it starts the service. To do this, the upstream source needs to
|
||||
have some minor coding work to let systemd listen for connections on the socket
|
||||
and there needs to be a `.socket` file in
|
||||
`%{_lib}/systemd/system/` that tells systemd to listen to that
|
||||
and there needs to be a `+.socket+` file in
|
||||
`+%{_lib}/systemd/system/+` that tells systemd to listen to that
|
||||
socket and what to start when a connection is received. This is similar in
|
||||
function to inetd and some, but not all, services coded to work with inetd will
|
||||
work with socket activation.
|
||||
|
||||
However, socket activation can also be used to allow parallel startup of services. If a service supports systemd socket activation as described above and we additionally start it explicitly on boot, then systemd will start it but allow things that depend on it to startup at the same time. If the dependent service makes a request to the socket activatable service before it has come up, then systemd will cause the request to wait until the socket activatable service has come up and can process the request. To achieve this effect, the service must be socket activatable as described above, the `.service` file for the service needs to have a `Wants=` line for the `.socket`, and the service must autostart.
|
||||
However, socket activation can also be used to allow parallel startup of services. If a service supports systemd socket activation as described above and we additionally start it explicitly on boot, then systemd will start it but allow things that depend on it to startup at the same time. If the dependent service makes a request to the socket activatable service before it has come up, then systemd will cause the request to wait until the socket activatable service has come up and can process the request. To achieve this effect, the service must be socket activatable as described above, the `+.service+` file for the service needs to have a `+Wants=+` line for the `+.socket+`, and the service must autostart.
|
||||
|
||||
Note that certain socket activated services (notably network listening ones) require FESCo approval - see Packaging:DefaultServices for details. Once you have permission, you can package the `.socket` file and use the systemd scriptlets that enable the service by default. You need to also check the `.service` file to make sure it has a `Wants=` entry on the `.socket` file as that ensures that starting the service will also inform systemd of the socket.
|
||||
Note that certain socket activated services (notably network listening ones) require FESCo approval - see Packaging:DefaultServices for details. Once you have permission, you can package the `+.socket+` file and use the systemd scriptlets that enable the service by default. You need to also check the `+.service+` file to make sure it has a `+Wants=+` entry on the `+.socket+` file as that ensures that starting the service will also inform systemd of the socket.
|
||||
|
||||
==== Timer activation
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ unnecessary new dependencies on systemd directly.
|
|||
|
||||
==== DBus activation
|
||||
|
||||
In order to allow parallel startup of a D-Bus service and its consumers it is essential that D-Bus services can be bus activated and the D-Bus activation request is forwarded from the D-Bus system bus to systemd so that you end up with only a single instance of the service, even if a service is triggered by both boot-up and activation. If historically your D-Bus service was not bus-activated but started via a SysV init script, it should be updated to use bus activation. This may be implemented by dropping a D-Bus `.service` file in `/usr/share/dbus-1/system-services/` and use the `SystemdService=` directive therein to redirect the activation to systemd.
|
||||
In order to allow parallel startup of a D-Bus service and its consumers it is essential that D-Bus services can be bus activated and the D-Bus activation request is forwarded from the D-Bus system bus to systemd so that you end up with only a single instance of the service, even if a service is triggered by both boot-up and activation. If historically your D-Bus service was not bus-activated but started via a SysV init script, it should be updated to use bus activation. This may be implemented by dropping a D-Bus `+.service+` file in `+/usr/share/dbus-1/system-services/+` and use the `+SystemdService=+` directive therein to redirect the activation to systemd.
|
||||
|
||||
Here's an example for a D-Bus bus-activable service. The ConsoleKit bus activation file /usr/share/dbus-1/system-services/org.freedesktop.ConsoleKit.service:
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ BusName=org.freedesktop.ConsoleKit
|
|||
ExecStart=/usr/sbin/console-kit-daemon --no-daemon
|
||||
....
|
||||
|
||||
As you can see `SystemdService=` is used in the D-Bus activation file to bind the systemd service to the D-Bus service.
|
||||
As you can see `+SystemdService=+` is used in the D-Bus activation file to bind the systemd service to the D-Bus service.
|
||||
|
||||
Traditionally, bus activated D-Bus services could not be disabled without
|
||||
uninstalling them entirely. systemd allows you to disable services by making
|
||||
|
|
@ -239,10 +239,10 @@ controlled via "systemctl enable" and "systemctl disable". It is a good idea
|
|||
(though technically not necessary) to name this alias name after the D-Bus bus
|
||||
name of the service, prefixed with "dbus-". Example for Avahi, a service that
|
||||
the admin might need to disable: set
|
||||
`SystemdService=dbus-org.freedesktop.Avahi.service` instead of
|
||||
`SystemdService=avahi-daemon.service` in the D-Bus activation file, and then make
|
||||
`dbus-org.freedesktop.Avahi.service` an optional alias of avahi-daemon.service
|
||||
that can be controlled via the `Alias=` directive in the `[Install]` section of the
|
||||
`+SystemdService=dbus-org.freedesktop.Avahi.service+` instead of
|
||||
`+SystemdService=avahi-daemon.service+` in the D-Bus activation file, and then make
|
||||
`+dbus-org.freedesktop.Avahi.service+` an optional alias of avahi-daemon.service
|
||||
that can be controlled via the `+Alias=+` directive in the `+[Install]+` section of the
|
||||
systemd service file. This directive is then read by "systemctl enable" and
|
||||
"systemctl disable" to create resp. remove a symlink to make the service
|
||||
available resp. unavailable under this additional name. A full example for the
|
||||
|
|
@ -260,7 +260,7 @@ SystemdService=dbus-org.freedesktop.Avahi.service
|
|||
Exec=/bin/false
|
||||
....
|
||||
|
||||
Here is the Avahi systemd unit `.service` file (/lib/systemd/system/avahi-daemon.service):
|
||||
Here is the Avahi systemd unit `+.service+` file (/lib/systemd/system/avahi-daemon.service):
|
||||
|
||||
....
|
||||
[Unit]
|
||||
|
|
@ -280,7 +280,7 @@ Also=avahi-daemon.socket
|
|||
Alias=dbus-org.freedesktop.Avahi.service
|
||||
....
|
||||
|
||||
The `Alias=` line ensures that the existance of the /etc/systemd/system/dbus-org.freedesktop.Avahi.service symlink can be controlled by "systemctl enable" and "systemctl disable".
|
||||
The `+Alias=+` line ensures that the existance of the /etc/systemd/system/dbus-org.freedesktop.Avahi.service symlink can be controlled by "systemctl enable" and "systemctl disable".
|
||||
|
||||
Note that the creation/removal of the alias symlinks should be done with "systemctl enable" and "systemctl disable" only. You should not create these symlinks manually.
|
||||
|
||||
|
|
@ -306,27 +306,27 @@ or
|
|||
Restart=on-abnormal
|
||||
....
|
||||
|
||||
in your unit's `.service` file for this.
|
||||
in your unit's `+.service+` file for this.
|
||||
|
||||
The former will tell systemd to restart the daemon as soon as it fails regardless of the precise reason. It's a good choice for most long-running services. Some daemons require a way to escape constant restarting by exiting with any non-zero exit code. For those services use `Restart=on-abnormal`, which will still restart the daemon when it fails "abnormally", on unclean signal, core dump, timeout or watchdog exits, but not on unclean exit codes. It is recommended to to enable automatic restarts for all long-running services, but which setting is the right one, and whether it is useful at all depends on the specific service. Please consult the `systemd.service(5)` man page for more information on the various settings.
|
||||
The former will tell systemd to restart the daemon as soon as it fails regardless of the precise reason. It's a good choice for most long-running services. Some daemons require a way to escape constant restarting by exiting with any non-zero exit code. For those services use `+Restart=on-abnormal+`, which will still restart the daemon when it fails "abnormally", on unclean signal, core dump, timeout or watchdog exits, but not on unclean exit codes. It is recommended to to enable automatic restarts for all long-running services, but which setting is the right one, and whether it is useful at all depends on the specific service. Please consult the `+systemd.service(5)+` man page for more information on the various settings.
|
||||
|
||||
=== Private devices and networking
|
||||
|
||||
If you package a long-running system service, please consider enabling systemd's `PrivateDevices=` and `PrivateNetwork=` settings for it, in order to improve security and minimize the attack surface.
|
||||
If you package a long-running system service, please consider enabling systemd's `+PrivateDevices=+` and `+PrivateNetwork=+` settings for it, in order to improve security and minimize the attack surface.
|
||||
|
||||
When `PrivateDevices=yes` is set in the [Service] section of a systemd service unit file, the processes run for the service will run in a private file system namespace where /dev is replaced by a minimal version that only includes the device nodes /dev/null, /dev/zero, /dev/full, /dev/urandom, /dev/random, /dev/tty as well as the submounts /dev/shm, /dev/pts, /dev/mqueue, /dev/hugepages, and the /dev/stdout, /dev/stderr, /dev/stdin symlinks. No device nodes for physical devices will be included, however. Furthermore, the CAP_MKNOD capability is removed. Finally, the "devices" cgroup controller is used to ensure that no access to device nodes except the listed ones is possible. This is an efficient way to take away physical device access for services, thus minimizing the attack surface.
|
||||
When `+PrivateDevices=yes+` is set in the [Service] section of a systemd service unit file, the processes run for the service will run in a private file system namespace where /dev is replaced by a minimal version that only includes the device nodes /dev/null, /dev/zero, /dev/full, /dev/urandom, /dev/random, /dev/tty as well as the submounts /dev/shm, /dev/pts, /dev/mqueue, /dev/hugepages, and the /dev/stdout, /dev/stderr, /dev/stdin symlinks. No device nodes for physical devices will be included, however. Furthermore, the CAP_MKNOD capability is removed. Finally, the "devices" cgroup controller is used to ensure that no access to device nodes except the listed ones is possible. This is an efficient way to take away physical device access for services, thus minimizing the attack surface.
|
||||
|
||||
When `PrivateNetwork=yes` is set in the [Service] section of a systemd service unit file, the processes run for the service will run in a private network namespace whith a private loopback network interface, and no other network devices. Network communication between host and service can not be initiated. This is an efficient way to take away network access for services, thus minimizing the attack surface.
|
||||
When `+PrivateNetwork=yes+` is set in the [Service] section of a systemd service unit file, the processes run for the service will run in a private network namespace whith a private loopback network interface, and no other network devices. Network communication between host and service can not be initiated. This is an efficient way to take away network access for services, thus minimizing the attack surface.
|
||||
|
||||
By default both switches default to "no".
|
||||
|
||||
Note that `PrivateDevices=yes` should not be used for:
|
||||
Note that `+PrivateDevices=yes+` should not be used for:
|
||||
|
||||
* Services that actually require physical device access
|
||||
* Services which may be used to execute arbitrary user or administrator supplied programs (such as cron, ...). We shouldn't limit what people can do with these services.
|
||||
* This option creates a new file system namespace where mount/umount propagation is turned off back into the host. This means that mounts made by the service will stay private to the service. Thus this option should not be used by services which shall be able to establish mounts in the host.
|
||||
|
||||
Note that `PrivateNetwork=yes` should not be used for:
|
||||
Note that `+PrivateNetwork=yes+` should not be used for:
|
||||
|
||||
* Services that actually require network access (with the exception of daemons only needing socket activation)
|
||||
* Services which may be used to execute arbitrary user or administrator supplied programs. (see above)
|
||||
|
|
@ -340,9 +340,9 @@ For further details see the systemd.exec(5) man page.
|
|||
|
||||
=== Filesystem locations
|
||||
|
||||
Packages with systemd unit files *must* put them into `%{_unitdir}`. `%{_unitdir}` evaluates to /lib/systemd/system on all Fedora systems (F-15+). Unit files are architecture independent (hence, not `%{_lib}`) and needed early in the boot process.
|
||||
Packages with systemd unit files *must* put them into `+%{_unitdir}+`. `+%{_unitdir}+` evaluates to /lib/systemd/system on all Fedora systems (F-15+). Unit files are architecture independent (hence, not `+%{_lib}+`) and needed early in the boot process.
|
||||
|
||||
Please note that in order for the `%{_unitdir}` macro to exist, your package must have:
|
||||
Please note that in order for the `+%{_unitdir}+` macro to exist, your package must have:
|
||||
|
||||
....
|
||||
BuildRequires: systemd
|
||||
|
|
@ -350,7 +350,7 @@ BuildRequires: systemd
|
|||
|
||||
=== %files section
|
||||
|
||||
Systemd unit `.service` files must not be marked as `%config` files.
|
||||
Systemd unit `+.service+` files must not be marked as `+%config+` files.
|
||||
|
||||
=== Unit files in spec file scriptlets
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ These conventions apply to Tcl packages in Fedora 9 and later. There are some as
|
|||
|
||||
== Naming Conventions
|
||||
|
||||
The name for all Tcl/Tk extensions must be prefixed with `tcl-`. This rule applies even for Tcl/Tk packages that are already prefixed with `tcl` in the name (see examples below). An optional `Provides: foo` is recommended to allow selecting the package based on the upstream name, as long as the upstream name is not excessively generic and does not conflict with an existing package name. Tk extensions have the option of adding additional Provides: with the prefix `tk-`. +
|
||||
The name for all Tcl/Tk extensions must be prefixed with `+tcl-+`. This rule applies even for Tcl/Tk packages that are already prefixed with `+tcl+` in the name (see examples below). An optional `+Provides: foo+` is recommended to allow selecting the package based on the upstream name, as long as the upstream name is not excessively generic and does not conflict with an existing package name. Tk extensions have the option of adding additional Provides: with the prefix `+tk-+`. +
|
||||
Examples:
|
||||
|
||||
....
|
||||
|
|
@ -21,11 +21,11 @@ Provides: tclxml = %{version}-%{release}
|
|||
Name: tcl-thread
|
||||
....
|
||||
|
||||
The exception to this naming rule are existing packages that provide both an extension and a shell, such as `expect`. However, note that providing a shell is strongly discouraged (see below).
|
||||
The exception to this naming rule are existing packages that provide both an extension and a shell, such as `+expect+`. However, note that providing a shell is strongly discouraged (see below).
|
||||
|
||||
== Applications
|
||||
|
||||
Tcl and Tk applications *must* use a non-versioned interpreter name in shebang line. This is to prevent any unnecessary dependency on the version of the interpreter being used. Most dependencies are with specific Tcl extensions, not the command line applications. Nevertheless, if an application does require a specific version of Tcl, it should use the standard Tcl package system to express this, as well as an explicit `Requires: tcl(abi) = 8.x` in the spec file.
|
||||
Tcl and Tk applications *must* use a non-versioned interpreter name in shebang line. This is to prevent any unnecessary dependency on the version of the interpreter being used. Most dependencies are with specific Tcl extensions, not the command line applications. Nevertheless, if an application does require a specific version of Tcl, it should use the standard Tcl package system to express this, as well as an explicit `+Requires: tcl(abi) = 8.x+` in the spec file.
|
||||
|
||||
Bad:
|
||||
|
||||
|
|
@ -40,13 +40,13 @@ Good:
|
|||
package require -exact Tcl 8.5
|
||||
....
|
||||
|
||||
The same rules apply for Tk applications. The non-versioned `wish` interpreter name *must* be used.
|
||||
The same rules apply for Tk applications. The non-versioned `+wish+` interpreter name *must* be used.
|
||||
|
||||
== Extensions
|
||||
|
||||
Since Fedora 9, `%{_libdir}` and `%{_datadir}` have been removed from the search path to optimize package loading times. Instead, Tcl extension packages *must* be installed in `%{_datadir}/tcl8.x` if they are noarch packages containing only Tcl code, or `%{_libdir}/tcl8.x` if they are arch-specific extensions containing shared libraries. Note that most Tcl extensions are not configured do install in these directories out of the box, and may need to use additional configure switches, patches, or script code in `%install` to move the files to the correct location.
|
||||
Since Fedora 9, `+%{_libdir}+` and `+%{_datadir}+` have been removed from the search path to optimize package loading times. Instead, Tcl extension packages *must* be installed in `+%{_datadir}/tcl8.x+` if they are noarch packages containing only Tcl code, or `+%{_libdir}/tcl8.x+` if they are arch-specific extensions containing shared libraries. Note that most Tcl extensions are not configured do install in these directories out of the box, and may need to use additional configure switches, patches, or script code in `+%install+` to move the files to the correct location.
|
||||
|
||||
Both arch-specific and `noarch` Tcl extensions *must* use
|
||||
Both arch-specific and `+noarch+` Tcl extensions *must* use
|
||||
|
||||
....
|
||||
Requires: tcl(abi) = 8.6
|
||||
|
|
@ -63,15 +63,15 @@ The following macros *must* be used at the top of the spec file to determine the
|
|||
%{!?tcl_sitelib: %global tcl_sitelib %{_datadir}/tcl%{tcl_version}}
|
||||
....
|
||||
|
||||
In order for the macros to work, the package must also `BuildRequires: tcl` either directly, or indirectly with `BuildRequires: tcl-devel`
|
||||
In order for the macros to work, the package must also `+BuildRequires: tcl+` either directly, or indirectly with `+BuildRequires: tcl-devel+`
|
||||
|
||||
Merely adding the `%{tcl_sitearch}` and `%{tcl_sitelib}` is not enough to ensure that the packages get installed into the correct location. Most Tcl extensions will install into `%{_libdir}` by default. There are two ways to change this. For most `noarch` packages, you can use the `--libdir` and `--datadir` configure switches to change the installation directory:
|
||||
Merely adding the `+%{tcl_sitearch}+` and `+%{tcl_sitelib}+` is not enough to ensure that the packages get installed into the correct location. Most Tcl extensions will install into `+%{_libdir}+` by default. There are two ways to change this. For most `+noarch+` packages, you can use the `+--libdir+` and `+--datadir+` configure switches to change the installation directory:
|
||||
|
||||
....
|
||||
%configure --libdir=%{tcl_sitelib} --datadir=%{tcl_sitelib}
|
||||
....
|
||||
|
||||
For `noarch` packages that aren't fixed by using `--libdir`, you can simply move the installation directory in the `%install` section of the spec file.
|
||||
For `+noarch+` packages that aren't fixed by using `+--libdir+`, you can simply move the installation directory in the `+%install+` section of the spec file.
|
||||
|
||||
....
|
||||
%install
|
||||
|
|
@ -81,7 +81,7 @@ install -d $RPM_BUILD_ROOT%{tcl_sitelib}
|
|||
mv $RPM_BUILD_ROOT%{_datadir}/foobar%{version} $RPM_BUILD_ROOT%{tcl_sitelib}/foobar%{version}
|
||||
....
|
||||
|
||||
It may also be acceptible to patch upstream's `configure` script and `Makefile` to add additional flexibility for the install directory, but the packager is not required to do this.
|
||||
It may also be acceptible to patch upstream's `+configure+` script and `+Makefile+` to add additional flexibility for the install directory, but the packager is not required to do this.
|
||||
|
||||
=== arch-specific packages
|
||||
|
||||
|
|
@ -92,18 +92,18 @@ The following macros *must* be used at the top of the spec file to determine the
|
|||
%{!?tcl_sitearch: %global tcl_sitearch %{_libdir}/tcl%{tcl_version}}
|
||||
....
|
||||
|
||||
In order for the macros to work, the package must also `BuildRequires: tcl` either directly, or indirectly with `BuildRequires: tcl-devel`
|
||||
In order for the macros to work, the package must also `+BuildRequires: tcl+` either directly, or indirectly with `+BuildRequires: tcl-devel+`
|
||||
|
||||
While `%{tcl_sitearch}` is a symlink to `%{tcl_sitelib}` in Fedora 8 and earlier, in Fedora 9 it is an actual directory.
|
||||
While `+%{tcl_sitearch}+` is a symlink to `+%{tcl_sitelib}+` in Fedora 8 and earlier, in Fedora 9 it is an actual directory.
|
||||
|
||||
The `--libdir` flag for the configure script can often be used to set the correct installation directory:
|
||||
The `+--libdir+` flag for the configure script can often be used to set the correct installation directory:
|
||||
|
||||
....
|
||||
%build
|
||||
%configure --libdir=%{tcl_sitearch}
|
||||
....
|
||||
|
||||
For most arch-specific packages, the `--libdir` flag for the configure script is also used to locate tclConfig.sh. Some of these arch-specific packages will break if `--libdir` is redirected to `%{tcl_sitearch}`. For packages that can't handle alternate values for `--libdir`, you can simply move the installation directory in the `%install` section of the spec file:
|
||||
For most arch-specific packages, the `+--libdir+` flag for the configure script is also used to locate tclConfig.sh. Some of these arch-specific packages will break if `+--libdir+` is redirected to `+%{tcl_sitearch}+`. For packages that can't handle alternate values for `+--libdir+`, you can simply move the installation directory in the `+%install+` section of the spec file:
|
||||
|
||||
....
|
||||
%install
|
||||
|
|
@ -115,15 +115,15 @@ mv $RPM_BUILD_ROOT%{_libdir}/foobar%{version} $RPM_BUILD_ROOT%{tcl_sitearch}/foo
|
|||
arch-specific packages can be generally grouped into three categories: those that provide a shell, those that provide a fooConfig.sh file and a shared library for linking, and those that only provide a shared library for dlopen().
|
||||
|
||||
*No shells:*
|
||||
Very few Tcl extension packages provide a shell. Providing a shell for an extension is frowned upon. The extension's shared library can be dynamically loaded into a Tcl interpreter through the standard `package require ...` mechanism without providing a shell that automatically loads the shared library. The exceptions to this rule are the shells that are commonly expected to be present on a system, including Tk (wish) and Expect (expect, expectk).
|
||||
Very few Tcl extension packages provide a shell. Providing a shell for an extension is frowned upon. The extension's shared library can be dynamically loaded into a Tcl interpreter through the standard `+package require ...+` mechanism without providing a shell that automatically loads the shared library. The exceptions to this rule are the shells that are commonly expected to be present on a system, including Tk (wish) and Expect (expect, expectk).
|
||||
|
||||
*-devel subpackage for fooConfig.sh:*
|
||||
Some arch-specific Tcl extensions provide a shared library and a corresponding `fooConfig.sh` file with instructions for linking against the library. The shared library for such packages *must* be installed into %\{_libdir} so that it can be found at runtime by applications that link against it. Unfortunately, the pkgIndex.tcl file in the package directory often references the shared library with a relative path. There are two ways to fix this. First, the maintainer can choose to keep the installation directory as %\{_libdir}, and make a symlink to %\{tcl_sitearch}. Second, the maintainer can choose to patch the pkgIndex.tcl file to contain an appropriate path to the shared library. Either solution is acceptible.
|
||||
Some arch-specific Tcl extensions provide a shared library and a corresponding `+fooConfig.sh+` file with instructions for linking against the library. The shared library for such packages *must* be installed into %\{_libdir} so that it can be found at runtime by applications that link against it. Unfortunately, the pkgIndex.tcl file in the package directory often references the shared library with a relative path. There are two ways to fix this. First, the maintainer can choose to keep the installation directory as %\{_libdir}, and make a symlink to %\{tcl_sitearch}. Second, the maintainer can choose to patch the pkgIndex.tcl file to contain an appropriate path to the shared library. Either solution is acceptible.
|
||||
|
||||
`fooConfig.sh` files must be placed in a -devel subpackage. This may require some sed magic to modify `fooConfig.sh` so that the paths to the libraries and headers are still correct.
|
||||
`+fooConfig.sh+` files must be placed in a -devel subpackage. This may require some sed magic to modify `+fooConfig.sh+` so that the paths to the libraries and headers are still correct.
|
||||
|
||||
*No dlopen()'d libraries in %\{_libdir}:*
|
||||
If the extension does *not* provide a `fooConfig.sh` file, then the shared library *must not* be installed directly in `%{_libdir}`, but in the package-specific installation directory in `%{tcl_sitearch}` instead. This may require a patch to update the extension's `pkgIndex.tcl` file to look for the shared library in the correct location.
|
||||
If the extension does *not* provide a `+fooConfig.sh+` file, then the shared library *must not* be installed directly in `+%{_libdir}+`, but in the package-specific installation directory in `+%{tcl_sitearch}+` instead. This may require a patch to update the extension's `+pkgIndex.tcl+` file to look for the shared library in the correct location.
|
||||
|
||||
*Stubs are ok if put in -devel subpackage:*
|
||||
Some Tcl extensions provide a static 'stub' library. Stub libraries are a Tcl-ism to provide version-independent dynamic linking on a variety of platforms. These are not normal static libraries that provide the library's actual functionality, but instead provide a level of indirection pointing to the shared library. These stub libraries do not have the same static linking issues that are generally frowned upon in Fedora, and thus are acceptible. If a package provides such a stub library, it must be placed in a -devel subpackage. More information on stubs can be found on the Tcl wiki: http://wiki.tcl.tk/285
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
== Overview
|
||||
|
||||
tmpfiles.d is a service for managing temporary files and runtime directories for daemons. In this guideline we mainly concentrate on how it is used to populate `/run` and `/run/lock`. Since `/run` is a `tmpfs` filesystem, it and its contents must be recreated on every reboot. For files intended to be created there, this should normally not pose any problems. However, directories will often need to be created ahead of time. This is best done using the tmpfiles.d mechanism.
|
||||
tmpfiles.d is a service for managing temporary files and runtime directories for daemons. In this guideline we mainly concentrate on how it is used to populate `+/run+` and `+/run/lock+`. Since `+/run+` is a `+tmpfs+` filesystem, it and its contents must be recreated on every reboot. For files intended to be created there, this should normally not pose any problems. However, directories will often need to be created ahead of time. This is best done using the tmpfiles.d mechanism.
|
||||
|
||||
== tmpfiles.d configuration
|
||||
|
||||
Asking the tmpfiles.d mechanism to create directories for you just involves dropping a file into `%{_tmpfilesdir}`. You will need a build dependency on systemd in order to make use of this macro.
|
||||
Asking the tmpfiles.d mechanism to create directories for you just involves dropping a file into `+%{_tmpfilesdir}+`. You will need a build dependency on systemd in order to make use of this macro.
|
||||
|
||||
For example, if the package needs a few directories to be created in `/run` in order for it to run, the packager needs to create a file named `%{name}.conf` that is installed as `%{_tmpfilesdir}/%{name}.conf`. The file has one or more lines of the following format:
|
||||
For example, if the package needs a few directories to be created in `+/run+` in order for it to run, the packager needs to create a file named `+%{name}.conf+` that is installed as `+%{_tmpfilesdir}/%{name}.conf+`. The file has one or more lines of the following format:
|
||||
|
||||
....
|
||||
d /run/NAME PERM USER GROUP -
|
||||
|
|
@ -14,12 +14,12 @@ d /run/NAME PERM USER GROUP -
|
|||
|
||||
The format of the line is as follows:
|
||||
|
||||
* `d` specifies that a directory is to be created if it doesn't exist. You can use a different type specifier if you need it. See `man tmpfiles.d` for possible values.
|
||||
* `/run/NAME` is the filesystem path to create.
|
||||
* `PERM` are the permissions (in the 4-digit octal format) to apply to the directory when it is created.
|
||||
* `USER` is the name of the owner of the directory.
|
||||
* `GROUP` is the name of the group of the directory.
|
||||
* `-` specifies that aging should not be applied to the contents of the directory. Aging is a mechanism for automated cleanup of files that were not used for a specified length of time. This is mostly useful for directories such as /tmp and is seldom used by packages. Feel free to use aging if it is appropriate for your directory.
|
||||
* `+d+` specifies that a directory is to be created if it doesn't exist. You can use a different type specifier if you need it. See `+man tmpfiles.d+` for possible values.
|
||||
* `+/run/NAME+` is the filesystem path to create.
|
||||
* `+PERM+` are the permissions (in the 4-digit octal format) to apply to the directory when it is created.
|
||||
* `+USER+` is the name of the owner of the directory.
|
||||
* `+GROUP+` is the name of the group of the directory.
|
||||
* `+-+` specifies that aging should not be applied to the contents of the directory. Aging is a mechanism for automated cleanup of files that were not used for a specified length of time. This is mostly useful for directories such as /tmp and is seldom used by packages. Feel free to use aging if it is appropriate for your directory.
|
||||
|
||||
An example:
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ Information on other options is available on the http://0pointer.de/public/syste
|
|||
|
||||
== Example spec file
|
||||
|
||||
In the spec file, the packager needs to install the tmpfiles.d conf file into the `%{_tmpfilesdir}` directory and also make sure the directory is included in the rpm.
|
||||
In the spec file, the packager needs to install the tmpfiles.d conf file into the `+%{_tmpfilesdir}+` directory and also make sure the directory is included in the rpm.
|
||||
|
||||
....
|
||||
# For the _tmpfilesdir macro.
|
||||
|
|
@ -62,9 +62,9 @@ chmod 0644 %{buildroot}/run/%{name}.pid
|
|||
%{_tmpfilesdir}/%{name}.conf
|
||||
....
|
||||
|
||||
`%{_tmpfilesdir}` expands to `%{_prefix}/lib/tmpfiles.d` which is the location that the package's default tmpfile creation scripts should install into. `%{_tmpfilesdir}/%{name}.conf` is *not* marked as a `%config` file because it is not supposed to be edited by administrators. Administrators can override the package's `%{name}.conf` by placing an identically named file in `/etc/tmpfiles.d/`, but this should very rarely be needed.
|
||||
`+%{_tmpfilesdir}+` expands to `+%{_prefix}/lib/tmpfiles.d+` which is the location that the package's default tmpfile creation scripts should install into. `+%{_tmpfilesdir}/%{name}.conf+` is *not* marked as a `+%config+` file because it is not supposed to be edited by administrators. Administrators can override the package's `+%{name}.conf+` by placing an identically named file in `+/etc/tmpfiles.d/+`, but this should very rarely be needed.
|
||||
|
||||
Files (*not directories*) that the program places directly into `/run` are listed in the `%files` section as `%verify(not size mtime md5)` so that rpm knows the file must exist as part of this package but will not complain when the file contents change. Files placed in the subdirectories may be listed the same way or omitted entirely as the files will be cleaned up on every reboot.
|
||||
Files (*not directories*) that the program places directly into `+/run+` are listed in the `+%files+` section as `+%verify(not size mtime md5)+` so that rpm knows the file must exist as part of this package but will not complain when the file contents change. Files placed in the subdirectories may be listed the same way or omitted entirely as the files will be cleaned up on every reboot.
|
||||
|
||||
== Why not create the directories with XXXXXX instead?
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ There are multiple ways to try creating the directories but most suffer some dis
|
|||
|
||||
=== Have the daemon create the directory when it starts up
|
||||
|
||||
Many times, daemons run as an unprivileged user who would not be allowed to create new directories directly into `/run`.
|
||||
Many times, daemons run as an unprivileged user who would not be allowed to create new directories directly into `+/run+`.
|
||||
If the daemon does not drop privileges, then you can patch it to create the files and directories when the daemon starts and submit the patch upstream.
|
||||
|
||||
=== Have the init script create the directory when it starts up the daemon
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ Unowned directories can cause the following problems.
|
|||
|
||||
A restrictive superuser umask during package installation can create inaccessible directories when installed using the RPM Package Manager older than 4.4.2.3. Fedora 9 and RHEL 5.3 are the first to use RPM 4.4.2.3 which sets umask 0022 always. On platforms with older versions of RPM if the superuser does this:
|
||||
|
||||
` umask 077` +
|
||||
` yum update` +
|
||||
` [or]` +
|
||||
` rpm -ivh PACKAGE`
|
||||
`+ umask 077+` +
|
||||
`+ yum update+` +
|
||||
`+ [or]+` +
|
||||
`+ rpm -ivh PACKAGE+`
|
||||
|
||||
Unowned directories within the updated or installed packages will only be readable and executable by root. This prevents other users from using the files within those directories.
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ Upstream source tarball configuration can fail, because it detects the presence
|
|||
|
||||
== Tools to Help
|
||||
|
||||
It's easy to find unowned directories with `rpmls` from rpmdevtools or `rpm -qlv`. Just a bit of carefulness is needed to not include core filesystem directories, such as %_bindir, %_libdir (and obvious others, e.g. from the "filesystem" pkg) which don't belong into your package.
|
||||
It's easy to find unowned directories with `+rpmls+` from rpmdevtools or `+rpm -qlv+`. Just a bit of carefulness is needed to not include core filesystem directories, such as %_bindir, %_libdir (and obvious others, e.g. from the "filesystem" pkg) which don't belong into your package.
|
||||
|
||||
== Common Mistakes
|
||||
|
||||
|
|
@ -51,50 +51,66 @@ Here are some examples of common packaging mistakes in spec %files lists to avoi
|
|||
|
||||
==== Unversioned
|
||||
|
||||
` %{_datadir}/foo/*`
|
||||
----
|
||||
%{_datadir}/foo/*
|
||||
----
|
||||
|
||||
This includes everything _in_ "foo", but not "foo" itself. "rpm -qlv pkgname" will show a missing drwxr-xr-x entry for "foo". Correct would be:
|
||||
|
||||
` %{_datadir}/foo/`
|
||||
----
|
||||
%{_datadir}/foo/
|
||||
----
|
||||
|
||||
to include the directory _and_ the entire tree below it.
|
||||
|
||||
==== Versioned
|
||||
|
||||
` %{_docdir}/%{name}-%{version}/*` +
|
||||
` %{_includedir}/%{name}-%{version}/*.h`
|
||||
----
|
||||
%{_docdir}/%{name}-%{version}/*
|
||||
%{_includedir}/%{name}-%{version}/*.h
|
||||
----
|
||||
|
||||
This is the same as the unversioned scenario with the addition that everytime the package is upgraded to a new version the old directory will remain on the filesystem. Correct would be:
|
||||
|
||||
` %{_docdir}/%{name}-%{version}/` +
|
||||
` %dir %{_includedir}/%{name}-%{version}` +
|
||||
` %{_includedir}/%{name}-%{version}/*.h`
|
||||
----
|
||||
%{_docdir}/%{name}-%{version}/
|
||||
%dir %{_includedir}/%{name}-%{version}
|
||||
%{_includedir}/%{name}-%{version}/*.h
|
||||
----
|
||||
|
||||
=== Forgetting to Include a Toplevel Directory
|
||||
|
||||
` %dir %{_libdir}/foo-2/fu` +
|
||||
` %dir %{_libdir}/foo-2/bar` +
|
||||
` %{_libdir}/foo-2/fu/*.so` +
|
||||
` %{_libdir}/foo-2/bar/config*`
|
||||
----
|
||||
%dir %{_libdir}/foo-2/fu
|
||||
%dir %{_libdir}/foo-2/bar
|
||||
%{_libdir}/foo-2/fu/*.so
|
||||
%{_libdir}/foo-2/bar/config*
|
||||
----
|
||||
|
||||
Here it is an attempt at including the directories explicitly with the %dir macro. However, while "bar" is included, "foo-2" is not. Typically packagers run into that mistake if all installed files are stored only in subdirs of the parent "foo-2" directory. Correct would be:
|
||||
|
||||
` %dir %{_libdir}/foo-2` +
|
||||
` %dir %{_libdir}/foo-2/fu` +
|
||||
` %dir %{_libdir}/foo-2/bar` +
|
||||
` %{_libdir}/foo-2/fu/*.so` +
|
||||
` %{_libdir}/foo-2/bar/config*`
|
||||
----
|
||||
%dir %{_libdir}/foo-2
|
||||
%dir %{_libdir}/foo-2/fu
|
||||
%dir %{_libdir}/foo-2/bar
|
||||
%{_libdir}/foo-2/fu/*.so
|
||||
%{_libdir}/foo-2/bar/config*
|
||||
----
|
||||
|
||||
==== Only Including Files
|
||||
|
||||
` %{_datadir}/%{name}/db/raw/*.db` +
|
||||
` %{_datadir}/%{name}/pixmaps/*.png`
|
||||
----
|
||||
%{_datadir}/%{name}/db/raw/*.db
|
||||
%{_datadir}/%{name}/pixmaps/*.png
|
||||
----
|
||||
|
||||
Here only specific data files are included, and all 4 directories below %_datadir are unowned. Correct would be:
|
||||
|
||||
` %dir %{_datadir}/%{name}` +
|
||||
` %dir %{_datadir}/%{name}/db` +
|
||||
` %dir %{_datadir}/%{name}/db/raw` +
|
||||
` %dir %{_datadir}/%{name}/pixmaps` +
|
||||
` %{_datadir}/%{name}/db/raw/*.db` +
|
||||
` %{_datadir}/%{name}/pixmaps/*.png`
|
||||
----
|
||||
%dir %{_datadir}/%{name}
|
||||
%dir %{_datadir}/%{name}/db
|
||||
%dir %{_datadir}/%{name}/db/raw
|
||||
%dir %{_datadir}/%{name}/pixmaps
|
||||
%{_datadir}/%{name}/db/raw/*.db
|
||||
%{_datadir}/%{name}/pixmaps/*.png
|
||||
----
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ The guidelines provide two options: letting each individual system allocate UID
|
|||
|
||||
=== Methods of pre-allocating
|
||||
|
||||
There are many ways to pre-allocate the UIDs and GIDs. Sites that only want to customize the UIDs and GIDs of a few nonessential services may write a script to create the entries with `useradd` and `groupadd` and install our package afterwards.
|
||||
There are many ways to pre-allocate the UIDs and GIDs. Sites that only want to customize the UIDs and GIDs of a few nonessential services may write a script to create the entries with `+useradd+` and `+groupadd+` and install our package afterwards.
|
||||
|
||||
Sites that want to pre-allocate accounts that are needed during an unattended kickstart install have trickier problem. One way for them to accomplish their goals is to create a customized version of the "`setup`" package with the desired users and groups along with their chosen UID/GID mappings in the `/etc/passwd`, `/etc/shadow`, and `/etc/group` files. Then they make sure the install transaction uses that package instead of the vanilla distro one (by versioning their setup package higher than ours (for instance, with an epoch) and putting it in a local repo they include when installing or replacing our setup package with their own in a local mirror of the packages that they are installing from). Since setup is at the top of the dependency tree, it will be installed before any package which needs to use the UIDs and GIDs that are defined in it.
|
||||
Sites that want to pre-allocate accounts that are needed during an unattended kickstart install have trickier problem. One way for them to accomplish their goals is to create a customized version of the "`+setup+`" package with the desired users and groups along with their chosen UID/GID mappings in the `+/etc/passwd+`, `+/etc/shadow+`, and `+/etc/group+` files. Then they make sure the install transaction uses that package instead of the vanilla distro one (by versioning their setup package higher than ours (for instance, with an epoch) and putting it in a local repo they include when installing or replacing our setup package with their own in a local mirror of the packages that they are installing from). Since setup is at the top of the dependency tree, it will be installed before any package which needs to use the UIDs and GIDs that are defined in it.
|
||||
|
||||
=== Known caveat of the pre-allocation strategy
|
||||
|
||||
The practice of using existing users and groups if their symbolic names (usernames and groupnames) already exists on the system lets the system administrator customize the UIDs and GIDs as they please. However, it has one drawback that system admins should be aware of. If an unrelated account has already been created that uses those usernames and groupnames the package will make use of those accounts.
|
||||
|
||||
As an example, say that you are installing the mailman package which wants to create the `mailman` user and group so that the private mailing list archives can be owned by that user and group on disk. One of your local users already has the local username `mailman`. When the mailman package is installed, it will detect that there is already a `mailman` user and use that account for owning its private archives. The local user who owns the mailman account would then be able to read those private archives.
|
||||
As an example, say that you are installing the mailman package which wants to create the `+mailman+` user and group so that the private mailing list archives can be owned by that user and group on disk. One of your local users already has the local username `+mailman+`. When the mailman package is installed, it will detect that there is already a `+mailman+` user and use that account for owning its private archives. The local user who owns the mailman account would then be able to read those private archives.
|
||||
|
||||
At the moment, there is no strategy for the packagers to counteract this. It is up to the site system administrators to keep track of and remove conflicts for the user and group names used by their users and those used by the packages they are using.
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ Any package can use dynamic allocation; it is especially appropriate for package
|
|||
|
||||
Soft static allocation ensures that multiple independently installed systems use the same UID and GID values; either UID and GID values allocated by Fedora or values that were optionally pre-allocated by the system administrator. Don't use soft static allocation unnecessarily as the number of available values is limited. Soft static allocation is only appropriate for packages where the UID or GID values are shared between computers. For instance, if the package creates files with the assigned UID or GID that are likely to be shared over NFS. Soft static allocation *MUST* be evaluated by the FPC. See the paragraph in the link:#Soft_static_allocation[ soft static section] for details the FPC will want.
|
||||
|
||||
In some cases it is desirable to create only a group without a user account. Usually this is because there are some system resources to which we want to control access by using that group and a separate user account would add no value. Examples of common such cases include (but are not limited to) games whose executables are setgid for the purpose of sharing high score files or the like, and/or software that needs exceptional permissions to some hardware devices and it wouldn't be appropriate to grant those to all system users nor even only those logged in on the console. In these cases, apply only the `groupadd` parts of the below recipes.
|
||||
In some cases it is desirable to create only a group without a user account. Usually this is because there are some system resources to which we want to control access by using that group and a separate user account would add no value. Examples of common such cases include (but are not limited to) games whose executables are setgid for the purpose of sharing high score files or the like, and/or software that needs exceptional permissions to some hardware devices and it wouldn't be appropriate to grant those to all system users nor even only those logged in on the console. In these cases, apply only the `+groupadd+` parts of the below recipes.
|
||||
|
||||
=== Dynamic allocation
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ exit 0
|
|||
|
||||
=== Soft static allocation
|
||||
|
||||
To allocate a UID and/or GID, file a https://fedorahosted.org/fpc/newticket[ticket for the FPC] to evaluate. If the FPC finds that your package needs a soft static UID or GID, they will approve your request and pass it on to the maintainers of the `setup` package for implementation. Because the number of UIDs and GIDs is limited, you need to justify your package's need for a soft static uid in the FPC ticket. Explain how the uids and gids are being shared between computers. If applicable, also explain why the program can't be adapted to use symbolic names (username and groupname) instead. If a specific UID or GID should be used, please mention it and why (for instance, it is the one used by upstream or the one used by other distributions). We will try to accommodate on a first-come-first serve basis if the UID/GID is available from within the Fedora system UID/GID range.
|
||||
To allocate a UID and/or GID, file a https://fedorahosted.org/fpc/newticket[ticket for the FPC] to evaluate. If the FPC finds that your package needs a soft static UID or GID, they will approve your request and pass it on to the maintainers of the `+setup+` package for implementation. Because the number of UIDs and GIDs is limited, you need to justify your package's need for a soft static uid in the FPC ticket. Explain how the uids and gids are being shared between computers. If applicable, also explain why the program can't be adapted to use symbolic names (username and groupname) instead. If a specific UID or GID should be used, please mention it and why (for instance, it is the one used by upstream or the one used by other distributions). We will try to accommodate on a first-come-first serve basis if the UID/GID is available from within the Fedora system UID/GID range.
|
||||
|
||||
To create users and groups in packages, use the following:
|
||||
|
||||
|
|
@ -68,16 +68,16 @@ exit 0
|
|||
|
||||
=== Values given to useradd and groupadd
|
||||
|
||||
* `HOMEDIR` should usually be a directory created and owned by the package, with appropriately restrictive permissions. One good choice for the location of the directory is the package's data directory in case it has one.
|
||||
* `USERNAME` and `GROUPNAME` are the symbolic names used by your package. Be aware that all code in the package should use these names, not the UID or GID. If this is not possible, please mention it within the ticket so that the FPC can see if this is a different type of problem than we usually encounter.
|
||||
* `ALLOCATED_UID` and `ALLOCATED_GID` are the UID and GID that FPC tells you has been allocated for use by your package.
|
||||
* User accounts created by packages are rarely used for interactive logons, and should thus generally use `/sbin/nologin` as the user's shell.
|
||||
* `+HOMEDIR+` should usually be a directory created and owned by the package, with appropriately restrictive permissions. One good choice for the location of the directory is the package's data directory in case it has one.
|
||||
* `+USERNAME+` and `+GROUPNAME+` are the symbolic names used by your package. Be aware that all code in the package should use these names, not the UID or GID. If this is not possible, please mention it within the ticket so that the FPC can see if this is a different type of problem than we usually encounter.
|
||||
* `+ALLOCATED_UID+` and `+ALLOCATED_GID+` are the UID and GID that FPC tells you has been allocated for use by your package.
|
||||
* User accounts created by packages are rarely used for interactive logons, and should thus generally use `+/sbin/nologin+` as the user's shell.
|
||||
|
||||
=== Rationale for some of the implementation choices
|
||||
|
||||
* We run `getent` before `groupadd` and `useradd` to check whether the user/group we're about to create already exists and skip the creation if they do. This is what allows the local system administrators to customize the users and groups beforehand in case they wish to get a predefined static UID/GID mapping for those users. Similarly, we verify whether the ID values allocated in the "setup" package aren't already allocated by the local system administrators.
|
||||
* We want to invoke `groupadd` explicitly instead of relying on `useradd` to create the group for us. This is because `useradd` alone would fail if the group it tries to create already existed.
|
||||
* We run the `groupadd`/`useradd` always -- both on initial installs and upgrades -- in `%pre`. This is made possible by the `getent` checks above, and should fix things up if the user/group has disappeared after the package to be upgraded was initially installed (just like file permissions get reset on upgrades etc).
|
||||
* The `exit 0` at the end will result in the `%pre` scriptlet passing through even if the user/group creation fails for some reason. This is suboptimal but has less potential for system wide breakage than allowing it to fail. If the user/group aren't available at the time the package's payload is unpacked, rpm will fall back to setting those files owned by root.
|
||||
* We run `+getent+` before `+groupadd+` and `+useradd+` to check whether the user/group we're about to create already exists and skip the creation if they do. This is what allows the local system administrators to customize the users and groups beforehand in case they wish to get a predefined static UID/GID mapping for those users. Similarly, we verify whether the ID values allocated in the "setup" package aren't already allocated by the local system administrators.
|
||||
* We want to invoke `+groupadd+` explicitly instead of relying on `+useradd+` to create the group for us. This is because `+useradd+` alone would fail if the group it tries to create already existed.
|
||||
* We run the `+groupadd+`/`+useradd+` always -- both on initial installs and upgrades -- in `+%pre+`. This is made possible by the `+getent+` checks above, and should fix things up if the user/group has disappeared after the package to be upgraded was initially installed (just like file permissions get reset on upgrades etc).
|
||||
* The `+exit 0+` at the end will result in the `+%pre+` scriptlet passing through even if the user/group creation fails for some reason. This is suboptimal but has less potential for system wide breakage than allowing it to fail. If the user/group aren't available at the time the package's payload is unpacked, rpm will fall back to setting those files owned by root.
|
||||
|
||||
Category:Packaging_guidelines[Category:Packaging guidelines]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
__TOC__
|
||||
|
||||
In Fedora, the package versioning scheme (which encompasses both the `Version:` and `Release:` tags, as well as `Epoch:`) balances two separate goals:
|
||||
In Fedora, the package versioning scheme (which encompasses both the `+Version:+` and `+Release:+` tags, as well as `+Epoch:+`) balances two separate goals:
|
||||
|
||||
* To provide information about the version of the packaged software to users. When a package version does not correspond directly to the upstream version of the software, some useful information is conveyed such as the date a snapshot was taken or whether a pre- or post-release version has been packaged.
|
||||
|
||||
|
|
@ -8,9 +8,9 @@ In Fedora, the package versioning scheme (which encompasses both the `Version:`
|
|||
|
||||
Fedora's versioning scheme must adapt to whatever scheme any upstream developer may choose for versioning their software, while at the same time preserving the two goals above.
|
||||
|
||||
The `Epoch:` tag, which provides the most significant input to RPM's version comparison function, SHOULD ONLY be used or incremented when necessary to avoid ordering issues. If present, it MUST contain a positive integer. `Epoch:` MUST NOT ever be decreased in any way.
|
||||
The `+Epoch:+` tag, which provides the most significant input to RPM's version comparison function, SHOULD ONLY be used or incremented when necessary to avoid ordering issues. If present, it MUST contain a positive integer. `+Epoch:+` MUST NOT ever be decreased in any way.
|
||||
|
||||
The tilde (`~`) notation which alters the way RPM does version comparisons MUST NOT be used.
|
||||
The tilde (`+~+`) notation which alters the way RPM does version comparisons MUST NOT be used.
|
||||
|
||||
== Some definitions
|
||||
|
||||
|
|
@ -43,8 +43,8 @@ This is a very common versioning scheme, and the vast majority of software proje
|
|||
|
||||
To package *release versions* of software using this versioning scheme:
|
||||
|
||||
* Use the upstream verbatim in the `Version:` tag. Don't trim leading zeroes.
|
||||
* Use a `Release:` tag starting with 1 (never 0). Append the Packaging:DistTag[Dist tag]. Increment the release (by 1) for each update you make. Reset to 1 whenever you change `Version:`.
|
||||
* Use the upstream verbatim in the `+Version:+` tag. Don't trim leading zeroes.
|
||||
* Use a `+Release:+` tag starting with 1 (never 0). Append the Packaging:DistTag[Dist tag]. Increment the release (by 1) for each update you make. Reset to 1 whenever you change `+Version:+`.
|
||||
|
||||
== More complex versioning
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ There are several ways in which the simple scheme might not work in a particular
|
|||
* You need to apply a small fix to a release branch of Fedora without updating the newer branches.
|
||||
* More than one of the above may apply (lucky you). Follow all of the relevant recommendations below together.
|
||||
|
||||
The methods for dealing with most of these issues involves potentially removing some information from the `Version:` tag while imposing additional structure onto the `Release:` tag. There are potentially three fields which comprise the structured `Release:` tag:
|
||||
The methods for dealing with most of these issues involves potentially removing some information from the `+Version:+` tag while imposing additional structure onto the `+Release:+` tag. There are potentially three fields which comprise the structured `+Release:+` tag:
|
||||
|
||||
* package release number ()
|
||||
* extra version information ()
|
||||
|
|
@ -67,15 +67,15 @@ The methods for dealing with most of these issues involves potentially removing
|
|||
|
||||
The package release number MUST always be present while the others may or may not be depending on the situation.
|
||||
|
||||
Those items which are present are combined (with periods to separate them) to construct the final `Release:` tag. In the usual notation where square brackets indicate that an item is optional:
|
||||
Those items which are present are combined (with periods to separate them) to construct the final `+Release:+` tag. In the usual notation where square brackets indicate that an item is optional:
|
||||
|
||||
* `[.``][.``]%{?dist}[.``]`
|
||||
* `+[.+``+][.+``+]%{?dist}[.+``+]+`
|
||||
|
||||
The actual values to be used for those three fields are situational and are referenced in the sections below. Note that your particular situation might not result in the use of or , and in most situations won't be used at all. Simply do not include those which you don't have.
|
||||
|
||||
=== Upstream has never chosen a version
|
||||
|
||||
When upstream has never chosen a version, you MUST use `Version: 0`. "`0`" sorts lower than any other possible value that upstream might choose. And if upstream does choose to release "version 0" then you can immediately move to using `Release: 1%{?dist}` with no ordering issues.
|
||||
When upstream has never chosen a version, you MUST use `+Version: 0+`. "`+0+`" sorts lower than any other possible value that upstream might choose. And if upstream does choose to release "version 0" then you can immediately move to using `+Release: 1%{?dist}+` with no ordering issues.
|
||||
|
||||
=== Upstream uses invalid characters in the version
|
||||
|
||||
|
|
@ -91,24 +91,24 @@ If this is not possible, use Version: 0 and move the _entire_ version string int
|
|||
|
||||
=== Snapshots
|
||||
|
||||
All snapshots MUST contain a snapshot information field () in the `Release:` tag. That field must at minimum consist of the date in eight-digit "YYYYMMDD" format. The packager MAY include up to 17 characters of additional information after the date. The following formats are suggested:
|
||||
All snapshots MUST contain a snapshot information field () in the `+Release:+` tag. That field must at minimum consist of the date in eight-digit "YYYYMMDD" format. The packager MAY include up to 17 characters of additional information after the date. The following formats are suggested:
|
||||
|
||||
* `YYYYMMDD.`
|
||||
* `YYYYMMDD`
|
||||
* `+YYYYMMDD.+`
|
||||
* `+YYYYMMDD+`
|
||||
|
||||
Where is a short string identifying the source code control system upstream uses (e.g. "git", "svn", "hg") or the string "snap". is either a short git commit hash, a subversion revision number, or something else useful in identifying the precise revision in upstream's source code control system. Obviously if CVS is used, no such revision information exists, so it would be omitted, but otherwise it SHOULD be included.
|
||||
|
||||
=== Prerelease versions
|
||||
|
||||
In the `Version:` tag, use the version that upstream has determined the next release will be. For the field of the `Release:` tag, use a number of the form "0.N" where N is an integer beginning with 1 and increasing for each revision of the package. Prerelease versions MUST use a `Release:` tag strictly less than 1, as this is the sole indicator that a prerelease has been packaged.
|
||||
In the `+Version:+` tag, use the version that upstream has determined the next release will be. For the field of the `+Release:+` tag, use a number of the form "0.N" where N is an integer beginning with 1 and increasing for each revision of the package. Prerelease versions MUST use a `+Release:+` tag strictly less than 1, as this is the sole indicator that a prerelease has been packaged.
|
||||
|
||||
=== Release and post-release versions
|
||||
|
||||
For the field of the `Release:` tag, use an integer beginning with 1 and increasing for each revision of the package. Release and post-release versions MUST use a `Release:` tag greater than or equal to 1.
|
||||
For the field of the `+Release:+` tag, use an integer beginning with 1 and increasing for each revision of the package. Release and post-release versions MUST use a `+Release:+` tag greater than or equal to 1.
|
||||
|
||||
=== Upstream makes unsortable changes
|
||||
|
||||
It is possible that upstream simply adopts a different versioning scheme, fails to follow an expected pattern, or even simply resets their version to some lower value. If none of the above operations can help with giving a version which sorts properly, or give you a version which simply sorts lower than the packages already in Fedora, then you have little recourse but to increment the `Epoch:` tag, or to begin using it by adding `Epoch: 1`. At the same time, try to work with upstream to hopefully minimize the need to involve `Epoch:` in the future.
|
||||
It is possible that upstream simply adopts a different versioning scheme, fails to follow an expected pattern, or even simply resets their version to some lower value. If none of the above operations can help with giving a version which sorts properly, or give you a version which simply sorts lower than the packages already in Fedora, then you have little recourse but to increment the `+Epoch:+` tag, or to begin using it by adding `+Epoch: 1+`. At the same time, try to work with upstream to hopefully minimize the need to involve `+Epoch:+` in the future.
|
||||
|
||||
=== You need to change an old branch without rebuilding the others
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
== Introduction
|
||||
|
||||
Weak dependencies are basically variants of the `Requires:` tag and
|
||||
are matched against (virtual) `Provides:` and package names using
|
||||
`Epoch-Version-Release` range comparisons, just like regular
|
||||
`Requires:`. They come in two strengths: "weak" and "hint" and two
|
||||
directions "forward" (analogous to `Requires:`) and "backwards"
|
||||
Weak dependencies are basically variants of the `+Requires:+` tag and
|
||||
are matched against (virtual) `+Provides:+` and package names using
|
||||
`+Epoch-Version-Release+` range comparisons, just like regular
|
||||
`+Requires:+`. They come in two strengths: "weak" and "hint" and two
|
||||
directions "forward" (analogous to `+Requires:+`) and "backwards"
|
||||
(which has no analog in the previous dependency system).
|
||||
|
||||
[cols=",,",]
|
||||
|
|
@ -24,7 +24,7 @@ example, preferring ruby vs jruby or community-mysql vs mariadb.
|
|||
== Weak dependencies
|
||||
|
||||
Weak dependencies are by default treated similarly to regular
|
||||
`Requires:`. Matching packages are added to the dnf transaction. If
|
||||
`+Requires:+`. Matching packages are added to the dnf transaction. If
|
||||
adding the package would lead to an error dnf will by default ignore the
|
||||
dependency. This allows users to exclude packages that would be added by weak
|
||||
dependencies or remove them later. (Future versions of dnf might also allow to
|
||||
|
|
@ -69,7 +69,7 @@ dependencies cannot enforce a older version of a package to be chosen.
|
|||
|
||||
If there are multiple (typically virtual) providers for a dependency the
|
||||
requiring package may add a Suggests: to provide a hint to the dependency
|
||||
resolver as to which poption is preferred. `Enhances:` should only
|
||||
resolver as to which poption is preferred. `+Enhances:+` should only
|
||||
be used for the rare occasion when the main package and other providers agree
|
||||
that adding the hint to the required package is for some reason the cleaner
|
||||
solution.
|
||||
|
|
@ -85,8 +85,8 @@ Provides: mysql
|
|||
Package community-mysql:
|
||||
Provides: mysql
|
||||
|
||||
If you want to prefer mariadb over community-mysql -> add `Suggests:`
|
||||
`mariadb` to Package A.
|
||||
If you want to prefer mariadb over community-mysql -> add `+Suggests:+`
|
||||
`+mariadb+` to Package A.
|
||||
|
||||
== Forward vs Backward Dependencies
|
||||
|
||||
|
|
|
|||
|
|
@ -40,21 +40,21 @@ Requires: web-assets-httpd
|
|||
|
||||
== Install Location
|
||||
|
||||
All packages that contain static content useful to different web applications must install into a subdirectory of `%{_assetdir}`. For instance, the `jquery-ui` package should install itself into `%{_webassetdir}/jquery-ui`.
|
||||
All packages that contain static content useful to different web applications must install into a subdirectory of `+%{_assetdir}+`. For instance, the `+jquery-ui+` package should install itself into `+%{_webassetdir}/jquery-ui+`.
|
||||
|
||||
All packages that contain static content that is only useful within the package in which they are shipped should continue to ship that content in the application's directory structure. However, they must follow the remainder of the guidelines outlined in this document.
|
||||
|
||||
== Server Location
|
||||
|
||||
All HTTP daemons in the distribution should make `%{_webassetdir}` available in `/.sysassets`.
|
||||
All HTTP daemons in the distribution should make `+%{_webassetdir}+` available in `+/.sysassets+`.
|
||||
|
||||
Therefore, if the `fabulous-web-icons` package ships an icon as `%{_webassetdir}/fabulous-web-icons/important.png`, you can include it in a web application with the following HTML:
|
||||
Therefore, if the `+fabulous-web-icons+` package ships an icon as `+%{_webassetdir}/fabulous-web-icons/important.png+`, you can include it in a web application with the following HTML:
|
||||
|
||||
....
|
||||
<img src="/.sysassets/fabulous-web-icons/important.png">
|
||||
....
|
||||
|
||||
Regardless, web applications may want to make subdirectories of `%{_webassetdir}` available under their own directory via aliases or symlinks for compatibility purposes or to eliminate needless deviation from upstream.
|
||||
Regardless, web applications may want to make subdirectories of `+%{_webassetdir}+` available under their own directory via aliases or symlinks for compatibility purposes or to eliminate needless deviation from upstream.
|
||||
|
||||
== Content Guidelines
|
||||
|
||||
|
|
@ -66,15 +66,15 @@ Pure CSS frameworks can be included as-is. CSS frameworks that use an alternativ
|
|||
|
||||
== Flash
|
||||
|
||||
Flash files (which typically use the `.swf` extension) must follow the general and licensing guidelines for code, not content, and must be built from source using a toolchain available in Fedora.
|
||||
Flash files (which typically use the `+.swf+` extension) must follow the general and licensing guidelines for code, not content, and must be built from source using a toolchain available in Fedora.
|
||||
|
||||
The Flash software needs to be compiled by a free software toolchain, such as `swfc`. Packaging:Guidelines#No_inclusion_of_pre-built_binaries_or_libraries[Pre-built `.swf` files *must not* be included in Fedora packages.] That compilation must be performed as part of the build process for the package.
|
||||
The Flash software needs to be compiled by a free software toolchain, such as `+swfc+`. Packaging:Guidelines#No_inclusion_of_pre-built_binaries_or_libraries[Pre-built `+.swf+` files *must not* be included in Fedora packages.] That compilation must be performed as part of the build process for the package.
|
||||
|
||||
If the flash software is not compilable using the toolchains inside of Fedora then the flash software cannot be shipped. In some cases you may be able to patch out use of the flash software (for instance, if it's a fallback in case the browser doesn't support HTML5) or you may have to give up on packaging the software until the flash software toolchain is enhanced to allow building.
|
||||
|
||||
== Java applets
|
||||
|
||||
Java applets should follow the general and licensing guidelines for code, not content. Additionally, they should follow the Packaging:Java[Java guidelines], with the exception that the actual `.jar` file for the Java applet should be installed into a subdirectory of `%{_webassetdir}`.
|
||||
Java applets should follow the general and licensing guidelines for code, not content. Additionally, they should follow the Packaging:Java[Java guidelines], with the exception that the actual `+.jar+` file for the Java applet should be installed into a subdirectory of `+%{_webassetdir}+`.
|
||||
|
||||
== Images
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ Web Asset packages that consist solely of images, such as a set of icons, may be
|
|||
|
||||
== Fonts
|
||||
|
||||
All system fonts (available in `%{_datadir}/fonts`) are automatically made available in `%{_webassetdir}/fonts/` via a symlink. For more information on packaging system fonts, see the Packaging:FontsPolicy[font guidelines]. Please note that [Web_Assets/Fonts|only fonts available in the Fedora package collection are made available on HTTP servers by default].
|
||||
All system fonts (available in `+%{_datadir}/fonts+`) are automatically made available in `+%{_webassetdir}/fonts/+` via a symlink. For more information on packaging system fonts, see the Packaging:FontsPolicy[font guidelines]. Please note that [Web_Assets/Fonts|only fonts available in the Fedora package collection are made available on HTTP servers by default].
|
||||
|
||||
Please note that those guidelines prohibit packaging fonts elsewhere. There is no compelling reason to support other font formats, as most browsers that support web fonts support the TTF or OTF formats used by system fonts, therefore alternative web font formats like WOFF are prohibited.
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ http://wordpress.org/extend/plugins/[WordPress plugins] are packaged for Fedora
|
|||
== Requirements for packaging
|
||||
|
||||
* Use the link:#Specfile_template[specfile template]
|
||||
* Set `plugin_name` and `plugin_human_name` by appending the first two lines appropriately
|
||||
** `plugin_name` is the short name used in the URL for the plugin's page on wordpress.org
|
||||
** `plugin_human_name` is the full name of the plugin as displayed on the plugin's page on wordpress.org
|
||||
* Set `+plugin_name+` and `+plugin_human_name+` by appending the first two lines appropriately
|
||||
** `+plugin_name+` is the short name used in the URL for the plugin's page on wordpress.org
|
||||
** `+plugin_human_name+` is the full name of the plugin as displayed on the plugin's page on wordpress.org
|
||||
* Fill in the version of the package as it is displayed in the .zip filename
|
||||
* Fill in a package description in both places where it says "Your plugin's description goes here."
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ http://wordpress.org/extend/plugins/stats/
|
|||
|
||||
== Notes
|
||||
|
||||
* The spec must be named `wordpress-plugin-%{plugin_name}.spec` as per the Packaging:NamingGuidelines[naming guidelines]
|
||||
* The spec must be named `+wordpress-plugin-%{plugin_name}.spec+` as per the Packaging:NamingGuidelines[naming guidelines]
|
||||
* Remember to enter a changelog entry
|
||||
|
||||
== Specfile template
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pull in other applications associated with that library or service.
|
|||
|
||||
Applications SHOULD be installable independently whenever this is technically feasible.
|
||||
Packages that contain a visible .desktop file (a .desktop file that does not contain the line
|
||||
`NoDisplay=true`) SHOULD NOT have a Requires, Recommends, or Supplements
|
||||
`+NoDisplay=true+`) SHOULD NOT have a Requires, Recommends, or Supplements
|
||||
on any other package containing a visible desktop file, directly or indirectly, unless the
|
||||
dependency is required for technical reasons or truly makes sense to have.
|
||||
For example, it would be reasonable for a video game level editor to
|
||||
|
|
@ -90,7 +90,7 @@ The spec file ("spec") is a fundamental element in the packaging workflow. Any c
|
|||
|
||||
=== Spec File Naming
|
||||
|
||||
The spec file MUST be named `%{name}.spec`. That is, if your package is named `example`, the spec file must be named `example.spec`.
|
||||
The spec file MUST be named `+%{name}.spec+`. That is, if your package is named `+example+`, the spec file must be named `+example.spec+`.
|
||||
|
||||
=== Spec Legibility
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ Similarly, filenames that contain non-ASCII characters must be encoded as UTF-8.
|
|||
|
||||
=== Spec Maintenance and Canonicity
|
||||
|
||||
Fedora's git repository is the canonical location for Fedora spec files. Maintainers MUST expect that other maintainers and automated tooling will make changes to their packages, potentially without communicating prior to doing so (though communication is always encouraged). If some maintainers are also attempting to keep copies of a spec in an outside repository, they MUST be prepared to merge changes made to the spec in Fedora's repository, and MUST NOT overwrite those changes with a copy from an external repository or using `fedpkg import`.
|
||||
Fedora's git repository is the canonical location for Fedora spec files. Maintainers MUST expect that other maintainers and automated tooling will make changes to their packages, potentially without communicating prior to doing so (though communication is always encouraged). If some maintainers are also attempting to keep copies of a spec in an outside repository, they MUST be prepared to merge changes made to the spec in Fedora's repository, and MUST NOT overwrite those changes with a copy from an external repository or using `+fedpkg import+`.
|
||||
|
||||
== Architecture Support
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ Content, code which does not need to compile or build, and architecture independ
|
|||
|
||||
=== Architecture Build Failures
|
||||
|
||||
If a Fedora package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in `ExcludeArch`. Each architecture listed in `ExcludeArch` needs to have a bug filed in bugzilla, describing the reason that the package does not compile/build/work on that architecture. The bug number should then be placed in a comment, next to the corresponding `ExcludeArch` line. New packages will not have bugzilla entries during the review process, so they should put this description in the comment until the package is approved, then file the bugzilla entry, and replace the long explanation with the bug number. The bug should be marked as blocking one (or more) of the following bugs to simplify tracking such issues:
|
||||
If a Fedora package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in `+ExcludeArch+`. Each architecture listed in `+ExcludeArch+` needs to have a bug filed in bugzilla, describing the reason that the package does not compile/build/work on that architecture. The bug number should then be placed in a comment, next to the corresponding `+ExcludeArch+` line. New packages will not have bugzilla entries during the review process, so they should put this description in the comment until the package is approved, then file the bugzilla entry, and replace the long explanation with the bug number. The bug should be marked as blocking one (or more) of the following bugs to simplify tracking such issues:
|
||||
|
||||
* https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=F-ExcludeArch-x86[F-ExcludeArch-x86]
|
||||
* https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=F-ExcludeArch-x64[F-ExcludeArch-x64]
|
||||
|
|
@ -133,7 +133,7 @@ Sometimes you are working on a noarch package that can only run in locations tha
|
|||
|
||||
==== Arch-Specific Runtime and Build-Time Dependencies
|
||||
|
||||
You can limit both the architectures used to build a noarch package, and the repositories to which the built noarch package will be added, by using either the `ExcludeArch:` or `ExclusiveArch:` tags:
|
||||
You can limit both the architectures used to build a noarch package, and the repositories to which the built noarch package will be added, by using either the `+ExcludeArch:+` or `+ExclusiveArch:+` tags:
|
||||
|
||||
....
|
||||
BuildArch: noarch
|
||||
|
|
@ -141,7 +141,7 @@ BuildArch: noarch
|
|||
ExclusiveArch: %{ix86} %{arm} x86_64 noarch
|
||||
....
|
||||
|
||||
Sometimes a language runtime you are packaging for will provide a macro for the arches it's available on, for instance, `%{nodejs_arches}`. If it does exist, then you can use something like `ExclusiveArch: %{nodejs_arches} noarch` in your spec file. Take a look at the guidelines for the language to see if such a macro exists.
|
||||
Sometimes a language runtime you are packaging for will provide a macro for the arches it's available on, for instance, `+%{nodejs_arches}+`. If it does exist, then you can use something like `+ExclusiveArch: %{nodejs_arches} noarch+` in your spec file. Take a look at the guidelines for the language to see if such a macro exists.
|
||||
|
||||
== Filesystem Layout
|
||||
|
||||
|
|
@ -149,25 +149,25 @@ Fedora follows the http://www.pathname.com/fhs/[Filesystem Hierarchy Standard] w
|
|||
|
||||
=== Exceptions
|
||||
|
||||
* Fedora allows cross-compilers to place files in `/usr/target`.
|
||||
* Fedora allows cross-compilers to place files in `+/usr/target+`.
|
||||
|
||||
* Fedora does not allow new directories directly under `/` or `/usr` without FPC approval.
|
||||
* Fedora does not allow new directories directly under `+/+` or `+/usr+` without FPC approval.
|
||||
|
||||
=== Libexecdir
|
||||
|
||||
The http://www.pathname.com/fhs/[Filesystem Hierarchy Standard] does not include any provision for libexecdir, but Fedora packages may store appropriate files there. Libexecdir (aka, `/usr/libexec` on Fedora systems) should only be used as the directory for executable programs that are designed primarily to be run by other programs rather than by users.
|
||||
The http://www.pathname.com/fhs/[Filesystem Hierarchy Standard] does not include any provision for libexecdir, but Fedora packages may store appropriate files there. Libexecdir (aka, `+/usr/libexec+` on Fedora systems) should only be used as the directory for executable programs that are designed primarily to be run by other programs rather than by users.
|
||||
|
||||
Fedora's rpm includes a macro for libexecdir, `%{_libexecdir}`. Packagers are highly encouraged to store libexecdir files in a package-specific subdirectory of `%{_libexecdir}`, such as `%{_libexecdir}/%{name}`.
|
||||
Fedora's rpm includes a macro for libexecdir, `+%{_libexecdir}+`. Packagers are highly encouraged to store libexecdir files in a package-specific subdirectory of `+%{_libexecdir}+`, such as `+%{_libexecdir}/%{name}+`.
|
||||
|
||||
If upstream's build scripts support the use of `%{_libexecdir}` then that is the most appropriate place to configure it (eg. passing `--libexecdir=%{_libexecdir}/%{name}` to autotools configure). If upstream's build scripts do not support that, `%{_libdir}/%{name}` is a valid second choice. If you have to patch support for using one of these directories in, then you should patch in LIBEXECDIR, preferably configurable at build time (so distributions that do not have `/usr/libexec` can set LIBEXECDIR to another directory more appropriate for their distro.
|
||||
If upstream's build scripts support the use of `+%{_libexecdir}+` then that is the most appropriate place to configure it (eg. passing `+--libexecdir=%{_libexecdir}/%{name}+` to autotools configure). If upstream's build scripts do not support that, `+%{_libdir}/%{name}+` is a valid second choice. If you have to patch support for using one of these directories in, then you should patch in LIBEXECDIR, preferably configurable at build time (so distributions that do not have `+/usr/libexec+` can set LIBEXECDIR to another directory more appropriate for their distro.
|
||||
|
||||
=== Multilib Exempt Locations
|
||||
|
||||
If a package is exempt from multilib, it may use `%{_prefix}/lib` instead of `%{_libdir}`. Packages that contain architecture specific files that would ordinarily be installed into `%{_libexecdir}` are always considered ineligible for multilib. However, you should be sure that the (sub)package that they are in does not have other content that would be considered eligible for multilib. If this is not the case for the files you wish to do this in for your package or you are just unsure, ask FESCo for an explicit multilib exemption.
|
||||
If a package is exempt from multilib, it may use `+%{_prefix}/lib+` instead of `+%{_libdir}+`. Packages that contain architecture specific files that would ordinarily be installed into `+%{_libexecdir}+` are always considered ineligible for multilib. However, you should be sure that the (sub)package that they are in does not have other content that would be considered eligible for multilib. If this is not the case for the files you wish to do this in for your package or you are just unsure, ask FESCo for an explicit multilib exemption.
|
||||
|
||||
=== `/run`
|
||||
=== `+/run+`
|
||||
|
||||
System services should store small volatile run-time data in `/run`. This is a tmpfs backed directory that is mounted in very early boot, before any services are started (and before `/var` is available). `/var/run` is a legacy symlink to `/run`.
|
||||
System services should store small volatile run-time data in `+/run+`. This is a tmpfs backed directory that is mounted in very early boot, before any services are started (and before `+/var+` is available). `+/var/run+` is a legacy symlink to `+/run+`.
|
||||
|
||||
=== No Files or Directories under /srv, /usr/local, or /home/$USER
|
||||
|
||||
|
|
@ -182,26 +182,26 @@ Distributions must take care not to remove locally placed files in these
|
|||
directories without administrator permission."
|
||||
....
|
||||
|
||||
The FHS is explicitly handing control of the directory structure under `/srv` to the system administrator rather than the distribution. Therefore, no Fedora packages can have any files or directories under `/srv`, come preconfigured to use specific files or directories under `/srv`, to remove files there, or to modify the files there in any way.
|
||||
The FHS is explicitly handing control of the directory structure under `+/srv+` to the system administrator rather than the distribution. Therefore, no Fedora packages can have any files or directories under `+/srv+`, come preconfigured to use specific files or directories under `+/srv+`, to remove files there, or to modify the files there in any way.
|
||||
|
||||
In addition, no Fedora package can contain files or directories or modify files under:
|
||||
|
||||
* `/usr/local` as these directories are not permitted to be used by Distributions in the FHS
|
||||
* `/home/$USER` as users can arbitrarily modify the files in their home directories and rpm packages that modify those files run the risk of destroying user data. Additionally, sites may be nfs mounting `/home` on many different types of systems or even network automounting them on demand. Modifying files in home directories that are thus configured will have negative effects in both of these situations.
|
||||
* `+/usr/local+` as these directories are not permitted to be used by Distributions in the FHS
|
||||
* `+/home/$USER+` as users can arbitrarily modify the files in their home directories and rpm packages that modify those files run the risk of destroying user data. Additionally, sites may be nfs mounting `+/home+` on many different types of systems or even network automounting them on demand. Modifying files in home directories that are thus configured will have negative effects in both of these situations.
|
||||
|
||||
It is important to note that the software in a Fedora package, once installed and configured by a user, can use `/srv` as a location for data. The package simply must not do this out of the box
|
||||
It is important to note that the software in a Fedora package, once installed and configured by a user, can use `+/srv+` as a location for data. The package simply must not do this out of the box
|
||||
|
||||
=== Limited usage of /opt, /etc/opt, and /var/opt
|
||||
|
||||
`/opt` and its related directories (`/etc/opt` and `/var/opt`) is reserved for the use of vendors in the FHS. We have reserved the `fedora` name with http://www.lanana.org/lsbreg/providers/providers.txt[LANANA] for our use. If a package installs files into `/opt` it may only use directories in the `/opt/fedora` hierarchy. Fedora attempts to organize this directory by allocating a subdirectory of our `/opt/fedora` directory for specific subsystems. If you think you need to use `/opt/fedora` please file an FPC ticket to decide whether it's a valid use of `/opt` and what subdirectory should be allocated for your use.
|
||||
`+/opt+` and its related directories (`+/etc/opt+` and `+/var/opt+`) is reserved for the use of vendors in the FHS. We have reserved the `+fedora+` name with http://www.lanana.org/lsbreg/providers/providers.txt[LANANA] for our use. If a package installs files into `+/opt+` it may only use directories in the `+/opt/fedora+` hierarchy. Fedora attempts to organize this directory by allocating a subdirectory of our `+/opt/fedora+` directory for specific subsystems. If you think you need to use `+/opt/fedora+` please file an FPC ticket to decide whether it's a valid use of `+/opt+` and what subdirectory should be allocated for your use.
|
||||
|
||||
Currently, we have allocated `/opt/fedora/scls`, `/etc/opt/fedora/scls`, and `/var/opt/fedora/scls` for use by User:Toshio/SCL_Guidelines_(draft)[ Software Collections].
|
||||
Currently, we have allocated `+/opt/fedora/scls+`, `+/etc/opt/fedora/scls+`, and `+/var/opt/fedora/scls+` for use by User:Toshio/SCL_Guidelines_(draft)[ Software Collections].
|
||||
|
||||
Because the Google-supplied Chrome packaging has chosen a specific file location for extension-specific files which, if used, would conflicts with the above guidelines, the Packaging Committee has approved the following exception: A package MAY install files into the `/etc/opt/chrome/native-messaging-hosts` directory, and may create that directory hierarchy, as long as package as a whole also supports Chromium. (The Chromium support MAY be in a different subpackage.) If Chrome in the future allows a more standard directory to be used for this purpose, this exception will be removed.
|
||||
Because the Google-supplied Chrome packaging has chosen a specific file location for extension-specific files which, if used, would conflicts with the above guidelines, the Packaging Committee has approved the following exception: A package MAY install files into the `+/etc/opt/chrome/native-messaging-hosts+` directory, and may create that directory hierarchy, as long as package as a whole also supports Chromium. (The Chromium support MAY be in a different subpackage.) If Chrome in the future allows a more standard directory to be used for this purpose, this exception will be removed.
|
||||
|
||||
=== Effect of the UsrMove Fedora Feature
|
||||
|
||||
Fedora has merged several directories in `/` with their counterparts in `/usr/`.
|
||||
Fedora has merged several directories in `+/+` with their counterparts in `+/usr/+`.
|
||||
|
||||
/bin
|
||||
|
||||
|
|
@ -219,16 +219,16 @@ Fedora has merged several directories in `/` with their counterparts in `/usr/`.
|
|||
|
||||
/usr/lib aka %\{_prefix}/lib
|
||||
|
||||
For example, end users will find that `/bin/sh` is the same file as `/usr/bin/sh`.
|
||||
For example, end users will find that `+/bin/sh+` is the same file as `+/usr/bin/sh+`.
|
||||
|
||||
However, rpm file dependencies don't work according to what's on the filesystem, they work according to the path specified in the rpm `%files` section. So an rpm which specified:
|
||||
However, rpm file dependencies don't work according to what's on the filesystem, they work according to the path specified in the rpm `+%files+` section. So an rpm which specified:
|
||||
|
||||
....
|
||||
%files
|
||||
/bin/sh
|
||||
....
|
||||
|
||||
would be able to satisfy a file dependency for `/bin/sh` but not for `/usr/bin/sh`. As a packager you may need to pay attention to where other packages expect to find your files. Things that history has placed into `/bin`, `/sbin`, `/lib`, or `/lib64` should be listed in the `%files` section as being in those directories. Things that history placed in `/usr/bin`, `/usr/sbin`, etc, should be listed in the `%files` section as being in `%{_bindir}`, `%{_sbindir}`, etc. If you feel that there is some historical confusion as to which directory a program is placed in, you can use a Virtual Provides to list the alternate path. For instance:
|
||||
would be able to satisfy a file dependency for `+/bin/sh+` but not for `+/usr/bin/sh+`. As a packager you may need to pay attention to where other packages expect to find your files. Things that history has placed into `+/bin+`, `+/sbin+`, `+/lib+`, or `+/lib64+` should be listed in the `+%files+` section as being in those directories. Things that history placed in `+/usr/bin+`, `+/usr/sbin+`, etc, should be listed in the `+%files+` section as being in `+%{_bindir}+`, `+%{_sbindir}+`, etc. If you feel that there is some historical confusion as to which directory a program is placed in, you can use a Virtual Provides to list the alternate path. For instance:
|
||||
|
||||
....
|
||||
Provides: %{_sbindir}/ifconfig
|
||||
|
|
@ -244,19 +244,19 @@ $ rpm -ql $(rpm -qf /usr/sbin/ifconfig)|grep sbin/ifconfig
|
|||
/sbin/ifconfig
|
||||
....
|
||||
|
||||
So you'd want to use `Requires: /sbin/ifconfig` in your spec file.
|
||||
So you'd want to use `+Requires: /sbin/ifconfig+` in your spec file.
|
||||
|
||||
== Use rpmlint
|
||||
|
||||
Run rpmlint on binary and source rpms to examine them for common errors, and fix them (unless rpmlint is wrong, which can happen, too). If you find rpmlint's output cryptic, the `-i` switch to it can be used to get more verbose descriptions of most errors and warnings. Note that rpmlint will perform additional checks if given the name of an installed package. For example, `dnf install foo-1.0-1.f20.x86_64.rpm; rpmlint foo` will perform a set of tests on the foo package that `rpmlint foo-1.0-1.f20.x86_64.rpm` cannot. A community-maintained page on rpmlint issues can be found link:Common_Rpmlint_issues[here].
|
||||
Run rpmlint on binary and source rpms to examine them for common errors, and fix them (unless rpmlint is wrong, which can happen, too). If you find rpmlint's output cryptic, the `+-i+` switch to it can be used to get more verbose descriptions of most errors and warnings. Note that rpmlint will perform additional checks if given the name of an installed package. For example, `+dnf install foo-1.0-1.f20.x86_64.rpm; rpmlint foo+` will perform a set of tests on the foo package that `+rpmlint foo-1.0-1.f20.x86_64.rpm+` cannot. A community-maintained page on rpmlint issues can be found link:Common_Rpmlint_issues[here].
|
||||
|
||||
== Tags and Sections
|
||||
|
||||
* The `Copyright:`, `Packager:`, `Vendor:` and `PreReq:` tags MUST NOT be used.
|
||||
* The `BuildRoot:` tag, `Group:` tag, and `%clean` section SHOULD NOT be used.
|
||||
* The contents of the buildroot SHOULD NOT be removed in the first line of `%install`.
|
||||
* The `Summary:` tag value SHOULD NOT end in a period.
|
||||
* The `Source:` tags document where to find the upstream sources for the package. In most cases this SHOULD be a complete URL to the upstream tarball. For special cases, please see the Packaging:SourceURL[SourceURL Guidelines].
|
||||
* The `+Copyright:+`, `+Packager:+`, `+Vendor:+` and `+PreReq:+` tags MUST NOT be used.
|
||||
* The `+BuildRoot:+` tag, `+Group:+` tag, and `+%clean+` section SHOULD NOT be used.
|
||||
* The contents of the buildroot SHOULD NOT be removed in the first line of `+%install+`.
|
||||
* The `+Summary:+` tag value SHOULD NOT end in a period.
|
||||
* The `+Source:+` tags document where to find the upstream sources for the package. In most cases this SHOULD be a complete URL to the upstream tarball. For special cases, please see the Packaging:SourceURL[SourceURL Guidelines].
|
||||
|
||||
== Package Dependencies
|
||||
|
||||
|
|
@ -295,11 +295,11 @@ $ gtk-config --libs
|
|||
|
||||
This means that gtk+-devel should contain
|
||||
|
||||
`Requires: glib-devel%{?_isa} libXi-devel%{?_isa} libXext-devel%{?_isa} libX11-devel%{?_isa}`
|
||||
`+Requires: glib-devel%{?_isa} libXi-devel%{?_isa} libXext-devel%{?_isa} libX11-devel%{?_isa}+`
|
||||
|
||||
=== Weak dependencies
|
||||
|
||||
Weak dependencies (`Recommends:`, `Suggests:`, `Supplements:` and `Enhances:`) MAY be used to specify relationships between packages which are less strict than mandatory requirements. Please see Packaging:WeakDependencies for guidelines on using these tags.
|
||||
Weak dependencies (`+Recommends:+`, `+Suggests:+`, `+Supplements:+` and `+Enhances:+`) MAY be used to specify relationships between packages which are less strict than mandatory requirements. Please see Packaging:WeakDependencies for guidelines on using these tags.
|
||||
|
||||
=== Rich/Boolean dependencies
|
||||
|
||||
|
|
@ -339,7 +339,7 @@ RPM attempts to auto-generate Requires (and Provides) at build time, but in some
|
|||
|
||||
== Build-Time Dependencies (BuildRequires)
|
||||
|
||||
It is important that your package list all necessary build dependencies using the `BuildRequires:` tag. You MAY assume that enough of an environment exists for RPM to function, to build packages and execute basic shell scripts, but you SHOULD NOT assume any other packages are present as RPM dependencies and anything brought into the buildroot by the build system can change over time.
|
||||
It is important that your package list all necessary build dependencies using the `+BuildRequires:+` tag. You MAY assume that enough of an environment exists for RPM to function, to build packages and execute basic shell scripts, but you SHOULD NOT assume any other packages are present as RPM dependencies and anything brought into the buildroot by the build system can change over time.
|
||||
|
||||
=== BuildRequires and %\{_isa}
|
||||
|
||||
|
|
@ -362,11 +362,11 @@ This would prevent yum-builddep or similar tools that use the SRPM's requirement
|
|||
|
||||
=== BuildRequires based on pkg-config
|
||||
|
||||
Fedora packages which use `pkg-config` to build against a library (e.g. 'foo') on which they depend, *SHOULD* express their build dependency correctly as `pkgconfig(foo)`. For more information, see Packaging:PkgConfigBuildRequires.
|
||||
Fedora packages which use `+pkg-config+` to build against a library (e.g. 'foo') on which they depend, *SHOULD* express their build dependency correctly as `+pkgconfig(foo)+`. For more information, see Packaging:PkgConfigBuildRequires.
|
||||
|
||||
== Conditional build-time dependencies
|
||||
|
||||
If the spec file contains conditional dependencies selected based on presence of optional `--with(out) foo` arguments to `rpmbuild`, build the source RPM to be submitted with the default options, ie. so that none of these arguments are present in the `rpmbuild` command line. The reason is that those requirements get "serialized" into the resulting source RPM, ie. the conditionals no longer apply.
|
||||
If the spec file contains conditional dependencies selected based on presence of optional `+--with(out) foo+` arguments to `+rpmbuild+`, build the source RPM to be submitted with the default options, ie. so that none of these arguments are present in the `+rpmbuild+` command line. The reason is that those requirements get "serialized" into the resulting source RPM, ie. the conditionals no longer apply.
|
||||
|
||||
== Summary and description
|
||||
|
||||
|
|
@ -391,13 +391,13 @@ If you're not sure, ask yourself, is there any chance someone may get confused a
|
|||
|
||||
== Documentation
|
||||
|
||||
Any relevant documentation included in the source distribution should be included in the package in the proper documentation directory. Irrelevant documentation includes build instructions, the omnipresent _INSTALL_ file containing generic build instructions, for example, and documentation for non-Linux systems, e.g. _README.MSDOS_. Also pay attention about which subpackage you include documentation in. For example API documentation belongs in the `-devel` subpackage, not the main one. Or if there's a lot of documentation, consider putting it into a subpackage. In this case, it is recommended to use `*-doc` as the subpackage name.
|
||||
Any relevant documentation included in the source distribution should be included in the package in the proper documentation directory. Irrelevant documentation includes build instructions, the omnipresent _INSTALL_ file containing generic build instructions, for example, and documentation for non-Linux systems, e.g. _README.MSDOS_. Also pay attention about which subpackage you include documentation in. For example API documentation belongs in the `+-devel+` subpackage, not the main one. Or if there's a lot of documentation, consider putting it into a subpackage. In this case, it is recommended to use `+*-doc+` as the subpackage name.
|
||||
|
||||
Marking a _relative_ path with `%doc` in the `%files` section will cause RPM to copy the referenced file or directory from `%_builddir` to the proper location for documentation. Files can also be placed in `%_pkgdocdir`, and the build scripts of the software being packaged may do this automatically when called in `%install`. However, mixing these methods is problematic and may result in duplicated or conflicting files, so use of `%doc` with _relative_ paths and installation of files directly into `%_pkgdocdir` in the same source package is forbidden.
|
||||
Marking a _relative_ path with `+%doc+` in the `+%files+` section will cause RPM to copy the referenced file or directory from `+%_builddir+` to the proper location for documentation. Files can also be placed in `+%_pkgdocdir+`, and the build scripts of the software being packaged may do this automatically when called in `+%install+`. However, mixing these methods is problematic and may result in duplicated or conflicting files, so use of `+%doc+` with _relative_ paths and installation of files directly into `+%_pkgdocdir+` in the same source package is forbidden.
|
||||
|
||||
Files marked as documentation must not cause the package to pull in more dependencies than it would without the documentation. One simple way to ensure this in most cases is to remove all executable permissions from files in `%_pkgdocdir`.
|
||||
Files marked as documentation must not cause the package to pull in more dependencies than it would without the documentation. One simple way to ensure this in most cases is to remove all executable permissions from files in `+%_pkgdocdir+`.
|
||||
|
||||
Files located in `%_pkgdocdir` must not affect the runtime of the packaged software. The software must function properly and with unchanged functionality if those files are modified, removed or not installed at all.
|
||||
Files located in `+%_pkgdocdir+` must not affect the runtime of the packaged software. The software must function properly and with unchanged functionality if those files are modified, removed or not installed at all.
|
||||
|
||||
Although license files are documentation, they are treated specially (including using a different tag. Please see Packaging:LicensingGuidelines for how to handle them.
|
||||
|
||||
|
|
@ -521,7 +521,7 @@ To use this in your spec, add:
|
|||
%global _hardened_build 1
|
||||
....
|
||||
|
||||
This adds `-fPIC` (if `-fPIE` is not already present) to the compiler flags, and adds `-z now` to the linker flags.
|
||||
This adds `+-fPIC+` (if `+-fPIE+` is not already present) to the compiler flags, and adds `+-z now+` to the linker flags.
|
||||
|
||||
If your package meets any of the following criteria you MUST enable the PIE compiler flags:
|
||||
|
||||
|
|
@ -545,7 +545,7 @@ There are some notable disadvantages to enabling PIE that should be considered i
|
|||
|
||||
== Debuginfo packages
|
||||
|
||||
Packages should produce useful `-debuginfo` packages, or explicitly disable them when it is not possible to generate a useful one but rpmbuild would do it anyway. Whenever a `-debuginfo` package is explicitly disabled, an explanation why it was done is required in the specfile. Debuginfo packages are discussed in more detail in a separate document, Packaging:Debuginfo .
|
||||
Packages should produce useful `+-debuginfo+` packages, or explicitly disable them when it is not possible to generate a useful one but rpmbuild would do it anyway. Whenever a `+-debuginfo+` package is explicitly disabled, an explanation why it was done is required in the specfile. Debuginfo packages are discussed in more detail in a separate document, Packaging:Debuginfo .
|
||||
|
||||
== Devel Packages
|
||||
|
||||
|
|
@ -623,7 +623,7 @@ correct object.
|
|||
Keep in mind that although the filename is usually the library's SONAME plus an incrementing minor version there's nothing that intrinsically links these. ldconfig uses the SONAME as the value for a symlink to the actual filename. The dynamic linker then uses that symlink to find the library, disregarding the actual filename. The dynamic linker merely does a simple equality check on the field and does not check for ABI incompatibilities or similar problems. This is the main reason for using an link:How_to_check_for_ABI_changes_in_a_package[ABI comparison tool] and incrementing the the SONAME.
|
||||
|
||||
The SONAME field is written to the shared object by linker, using (at least in
|
||||
case of `ld`) the `-soname SONAME` flags. This can be
|
||||
case of `+ld+`) the `+-soname SONAME+` flags. This can be
|
||||
passed as an option to like this:
|
||||
|
||||
....
|
||||
|
|
@ -631,7 +631,7 @@ $ gcc $CFLAGS -Wl,-soname,libfoo.so.0.n -o libfoo.so.0.n
|
|||
....
|
||||
|
||||
If you want to check if the SONAME field is set and what value it has, use the
|
||||
`objdump` command (from ):
|
||||
`+objdump+` command (from ):
|
||||
|
||||
....
|
||||
$ objdump -p /path/to/libfoo.so.0.n | grep 'SONAME'
|
||||
|
|
@ -649,7 +649,7 @@ Libtool archives, _foo.la_ files, SHOULD NOT be included. Packages using libtool
|
|||
|
||||
* We want to be able to track which packages are using static libraries (so we can find which packages need to be rebuilt if a security flaw in a static library is fixed, for instance). There are two scenarios in which static libraries are packaged:
|
||||
|
||||
1. *Static libraries and shared libraries.* In this case, the static libraries MUST be placed in a _*-static_ subpackage. Separating the static libraries from the other development files in _*-devel_ allow us to track this usage by checking which packages `BuildRequire` the _*-static_ package. The intent is that whenever possible, packages will move away from using these static libraries, to the shared libraries. If the _*-static_ subpackage requires headers or other files from _*-devel_ in order to be useful it MUST require the _*-devel_ subpackage.
|
||||
1. *Static libraries and shared libraries.* In this case, the static libraries MUST be placed in a _*-static_ subpackage. Separating the static libraries from the other development files in _*-devel_ allow us to track this usage by checking which packages `+BuildRequire+` the _*-static_ package. The intent is that whenever possible, packages will move away from using these static libraries, to the shared libraries. If the _*-static_ subpackage requires headers or other files from _*-devel_ in order to be useful it MUST require the _*-devel_ subpackage.
|
||||
2. *Static libraries only.* When a package only provides static libraries you MAY place all the static library files in the _*-devel_ subpackage. When doing this you also MUST have a virtual Provide for the _*-static_ package:
|
||||
|
||||
....
|
||||
|
|
@ -657,9 +657,9 @@ Libtool archives, _foo.la_ files, SHOULD NOT be included. Packages using libtool
|
|||
Provides: foo-static = %{version}-%{release}
|
||||
....
|
||||
|
||||
Packages which explicitly need to link against the static version MUST `BuildRequire: foo-static`, so that the usage can be tracked.
|
||||
Packages which explicitly need to link against the static version MUST `+BuildRequire: foo-static+`, so that the usage can be tracked.
|
||||
|
||||
* If (and only if) a package has shared libraries which require static libraries to be functional, the static libraries can be included in the _*-devel_ subpackage. The devel subpackage must have a virtual Provide for the _*-static_ package, and packages dependent on it must `BuildRequire` the _*-static_ package.
|
||||
* If (and only if) a package has shared libraries which require static libraries to be functional, the static libraries can be included in the _*-devel_ subpackage. The devel subpackage must have a virtual Provide for the _*-static_ package, and packages dependent on it must `+BuildRequire+` the _*-static_ package.
|
||||
|
||||
=== Packaging Header Only Libraries
|
||||
|
||||
|
|
@ -672,7 +672,7 @@ Place all of the header files in the _*-devel_ subpackage and then you must have
|
|||
Provides: foo-static = %{version}-%{release}
|
||||
....
|
||||
|
||||
Packages which use the header library must `BuildRequire: foo-static`, so that the usage can be tracked.
|
||||
Packages which use the header library must `+BuildRequire: foo-static+`, so that the usage can be tracked.
|
||||
|
||||
==== Do not use noarch
|
||||
|
||||
|
|
@ -680,9 +680,9 @@ It may be tempting to make the header library package noarch, since the header f
|
|||
|
||||
=== Statically Linking Executables
|
||||
|
||||
Executables and libraries SHOULD NOT be linked statically against libraries which come from other packages. (It is of course acceptable for files generated during a package's build process to be linked statically against `.a` files generated as part of that build process.)
|
||||
Executables and libraries SHOULD NOT be linked statically against libraries which come from other packages. (It is of course acceptable for files generated during a package's build process to be linked statically against `+.a+` files generated as part of that build process.)
|
||||
|
||||
If it is necessary to link against `.a` files from a different package, a build dependency on the `-static` package (not just the `-devel` package) which provides those files MUST be present so that the usage can be tracked.
|
||||
If it is necessary to link against `+.a+` files from a different package, a build dependency on the `+-static+` package (not just the `+-devel+` package) which provides those files MUST be present so that the usage can be tracked.
|
||||
|
||||
== Bundling and Duplication of system libraries
|
||||
|
||||
|
|
@ -698,9 +698,9 @@ To indicate an instance of bundling, first determine the name and version of the
|
|||
|
||||
* Use the Packaging:Versioning[versioning guidelines] to determine an appropriate version for the library, if possible. If the library has been forked from an upstream, use the upstream version that was most recently merged in or rebased onto, or the version the original library carried at the time of the fork.
|
||||
|
||||
Then at an appropriate place in your spec, add `Provides: bundled(``) = ` where and are the name and version you determined above. If it was not possible to determine a version, use `Provides: bundled(``)` instead.
|
||||
Then at an appropriate place in your spec, add `+Provides: bundled(+``+) = +` where and are the name and version you determined above. If it was not possible to determine a version, use `+Provides: bundled(+``+)+` instead.
|
||||
|
||||
In addition to indicating bundling in this manner, packages whose upstreams have no mechanism to build against system libraries must be contacted publicly about a path to supporting system libraries. If upstream refuses, this must be recorded in the spec file, either in comments placed adjacent to the Provides: above, or in an additional file checked into the SCM and referenced by a comment placed adjacent to the `Provides:` above.
|
||||
In addition to indicating bundling in this manner, packages whose upstreams have no mechanism to build against system libraries must be contacted publicly about a path to supporting system libraries. If upstream refuses, this must be recorded in the spec file, either in comments placed adjacent to the Provides: above, or in an additional file checked into the SCM and referenced by a comment placed adjacent to the `+Provides:+` above.
|
||||
|
||||
=== Avoid bundling of fonts in other packages
|
||||
|
||||
|
|
@ -711,7 +711,7 @@ For more information, see: Packaging:FontsPolicy#Package_layout_for_fonts.
|
|||
|
||||
Sometimes, code will hardcode specific library paths when linking binaries (using the -rpath or -R flag). This is commonly referred to as an rpath. Normally, the dynamic linker and loader (ld.so) resolve the executable's dependencies on shared libraries and load what is required. However, when -rpath or -R is used, the location information is then hardcoded into the binary and is examined by ld.so in the beginning of the execution. Since the Linux dynamic linker is usually smarter than a hardcoded path, we usually do not permit the use of rpath in Fedora.
|
||||
|
||||
There is a tool called _check-rpaths_ which is included in the _rpmdevtools_ package. It is a good idea to add it to the _`%__arch_install_post`_ macro in your _`~/.rpmmacros`_ config file:
|
||||
There is a tool called _check-rpaths_ which is included in the _rpmdevtools_ package. It is a good idea to add it to the _`+%__arch_install_post+`_ macro in your _`+~/.rpmmacros+`_ config file:
|
||||
|
||||
....
|
||||
%__arch_install_post \
|
||||
|
|
@ -768,7 +768,7 @@ sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
|
|||
....
|
||||
|
||||
* Sometimes, the code/Makefiles can be patched to remove the _-rpath_ or _-R_ flag from being called. This is not always easy or sane to do, however.
|
||||
* As a last resort, Fedora has a package called _chrpath_. When this package is installed, you can run `chrpath --delete` on the files which contain rpaths. So, in our earlier example, we'd run:
|
||||
* As a last resort, Fedora has a package called _chrpath_. When this package is installed, you can run `+chrpath --delete+` on the files which contain rpaths. So, in our earlier example, we'd run:
|
||||
|
||||
....
|
||||
chrpath --delete $RPM_BUILD_ROOT%{_bindir}/xapian-tcpsrv
|
||||
|
|
@ -780,13 +780,13 @@ Make sure that you remember to add a *BuildRequires: chrpath* if you end up usin
|
|||
|
||||
Configuration files must be marked as such in packages.
|
||||
|
||||
As a rule of thumb, use `%config(noreplace)` instead of plain `%config` unless your best, educated guess is that doing so will break things. In other words, think hard before overwriting local changes in configuration files on package upgrades. An example case when /not/ to use `noreplace` is when a package's configuration file changes so that the new package revision wouldn't work with the config file from the previous package revision. Whenever plain `%config` is used, add a brief comment to the specfile explaining why.
|
||||
As a rule of thumb, use `+%config(noreplace)+` instead of plain `+%config+` unless your best, educated guess is that doing so will break things. In other words, think hard before overwriting local changes in configuration files on package upgrades. An example case when /not/ to use `+noreplace+` is when a package's configuration file changes so that the new package revision wouldn't work with the config file from the previous package revision. Whenever plain `+%config+` is used, add a brief comment to the specfile explaining why.
|
||||
|
||||
Don't use %config or %config(noreplace) under /usr. /usr is deemed to not contain configuration files in Fedora.
|
||||
|
||||
=== Configuration of Package Managers
|
||||
|
||||
Packages MUST NOT install repository configuration files which violate the https://fedoraproject.org/wiki/Third_Party_Repository_Policy[Third Party Repository Policy], unless those files are installed under `%{_docdir}`.
|
||||
Packages MUST NOT install repository configuration files which violate the https://fedoraproject.org/wiki/Third_Party_Repository_Policy[Third Party Repository Policy], unless those files are installed under `+%{_docdir}+`.
|
||||
|
||||
== Per-product Configuration
|
||||
|
||||
|
|
@ -812,11 +812,11 @@ The icon tag can be specified in two ways:
|
|||
|
||||
* Full path to specific icon file:
|
||||
|
||||
`Icon=/usr/share/pixmaps/comical.png`
|
||||
`+Icon=/usr/share/pixmaps/comical.png+`
|
||||
|
||||
* Short name without file extension:
|
||||
|
||||
`Icon=comical`
|
||||
`+Icon=comical+`
|
||||
|
||||
The short name without file extension is preferred, because it allows for icon theming (it assumes .png by default, then tries .svg and finally .xpm), but either method is acceptable.
|
||||
|
||||
|
|
@ -838,7 +838,7 @@ Categories=Graphics;
|
|||
|
||||
=== desktop-file-install usage
|
||||
|
||||
It is not simply enough to just include the .desktop file in the package, one MUST run `desktop-file-install` (in `%install`) OR `desktop-file-validate` (in `%check` or `%install`) and have `BuildRequires: desktop-file-utils`, to help ensure .desktop file safety and spec-compliance. `desktop-file-install` MUST be used if the package does not install the file or there are changes desired to the .desktop file (such as add/removing categories, etc). `desktop-file-validate` MAY be used instead if the .desktop file's content/location does not need modification. Here are some examples of
|
||||
It is not simply enough to just include the .desktop file in the package, one MUST run `+desktop-file-install+` (in `+%install+`) OR `+desktop-file-validate+` (in `+%check+` or `+%install+`) and have `+BuildRequires: desktop-file-utils+`, to help ensure .desktop file safety and spec-compliance. `+desktop-file-install+` MUST be used if the package does not install the file or there are changes desired to the .desktop file (such as add/removing categories, etc). `+desktop-file-validate+` MAY be used instead if the .desktop file's content/location does not need modification. Here are some examples of
|
||||
usage:
|
||||
|
||||
....
|
||||
|
|
@ -872,7 +872,7 @@ Packagers are strongly encouraged to use macros instead of hard-coded directory
|
|||
* The package must be consistent. For any given path, within the same spec, use either a hard-coded path or a macro, not a combination of the two.
|
||||
* %\{_libdir} must always be used for binary libraries due to multi-lib, you may not substitute a hard-coded path.
|
||||
|
||||
Macro forms of system executables SHOULD NOT be used except when there is a need to allow the location of those executables to be configurable. For example, `rm` should be used in preference to `%{__rm}`, but `%{__python}` is acceptable.
|
||||
Macro forms of system executables SHOULD NOT be used except when there is a need to allow the location of those executables to be configurable. For example, `+rm+` should be used in preference to `+%{__rm}+`, but `+%{__python}+` is acceptable.
|
||||
|
||||
Having macros in a Source: or Patch: line is a matter of style. Some people enjoy the ready readability of a source line without macros. Others prefer the ease of updating for new versions when macros are used. In all cases, remember to be consistent in your spec file and verify that the URLs you list are valid. spectool (from the rpmdevtools package) can aid you in checking that whether the URL contains macros or not.
|
||||
|
||||
|
|
@ -882,9 +882,9 @@ If you need to determine the actual string when it contains macros, you can use
|
|||
rpm -q --specfile foo.spec --qf "$(grep -i ^Source foo.spec)\n"
|
||||
....
|
||||
|
||||
=== `%autosetup`
|
||||
=== `+%autosetup+`
|
||||
|
||||
As an alternative to the usual `%setup` macro, the `%autosetup` can be used. In addition to the normal %setup tasks, it will apply all defined Patch# items in the spec automatically. It is also capable of handling VCS formatted patch files, but this will require additional BuildRequires, and assumes that _all_ patch files in the spec are formatted for that single VCS type. For this reason, it is not recommended that you specify a VCS with `%autosetup`. For more details on proper use of `%autosetup`, refer to the http://rpm.org/user_doc/autosetup.html[RPM documentation].
|
||||
As an alternative to the usual `+%setup+` macro, the `+%autosetup+` can be used. In addition to the normal %setup tasks, it will apply all defined Patch# items in the spec automatically. It is also capable of handling VCS formatted patch files, but this will require additional BuildRequires, and assumes that _all_ patch files in the spec are formatted for that single VCS type. For this reason, it is not recommended that you specify a VCS with `+%autosetup+`. For more details on proper use of `+%autosetup+`, refer to the http://rpm.org/user_doc/autosetup.html[RPM documentation].
|
||||
|
||||
=== Using %\{buildroot} and %\{optflags} vs $RPM_BUILD_ROOT and $RPM_OPT_FLAGS
|
||||
|
||||
|
|
@ -903,18 +903,18 @@ Mixing the two styles, while valid, is bad from a QA and usability point of view
|
|||
|
||||
=== Why the %makeinstall macro should not be used
|
||||
|
||||
Fedora's RPM includes a `%makeinstall` macro but it must *NOT* be used when make install DESTDIR=%\{buildroot} works. %makeinstall is a kludge that can work with Makefiles that don't make use of the DESTDIR variable but it has the following potential issues:
|
||||
Fedora's RPM includes a `+%makeinstall+` macro but it must *NOT* be used when make install DESTDIR=%\{buildroot} works. %makeinstall is a kludge that can work with Makefiles that don't make use of the DESTDIR variable but it has the following potential issues:
|
||||
|
||||
* `%makeinstall` overrides a set of Make variables during "make install" and prepends the %\{buildroot} path. I.e. it performs make prefix="%\{buildroot}%\{_prefix}" libdir="%\{buildroot}%\{_libdir} ...".
|
||||
* `+%makeinstall+` overrides a set of Make variables during "make install" and prepends the %\{buildroot} path. I.e. it performs make prefix="%\{buildroot}%\{_prefix}" libdir="%\{buildroot}%\{_libdir} ...".
|
||||
* It is error-prone and can have unexpected effects when run against less than perfect Makefiles, e.g. the buildroot path may be included in installed files where variables are substituted at install-time.
|
||||
* It can trigger unnecessary and wrong rebuilds when executing "make install", since the Make variables have different values compared with the %build section.
|
||||
* If a package contains libtool archives, it can cause broken *.la files to be installed.
|
||||
|
||||
Instead, Fedora packages should use: `%make_install` (Note the "_" !), `make DESTDIR=%{buildroot} install` or `make DESTDIR=$RPM_BUILD_ROOT install`. Those all do the same thing.
|
||||
Instead, Fedora packages should use: `+%make_install+` (Note the "_" !), `+make DESTDIR=%{buildroot} install+` or `+make DESTDIR=$RPM_BUILD_ROOT install+`. Those all do the same thing.
|
||||
|
||||
=== Source RPM Buildtime Macros
|
||||
|
||||
All macros in `Summary:` and `%description` need to be expandable at srpm buildtime. Because SRPMs are built without the package's BuildRequires installed, depending on macros defined outside of the spec file can easily lead to the unexpanded macros showing up in the built SRPM. One way to check is to create a minimal chroot and build the srpm:
|
||||
All macros in `+Summary:+` and `+%description+` need to be expandable at srpm buildtime. Because SRPMs are built without the package's BuildRequires installed, depending on macros defined outside of the spec file can easily lead to the unexpanded macros showing up in the built SRPM. One way to check is to create a minimal chroot and build the srpm:
|
||||
|
||||
....
|
||||
mock --init
|
||||
|
|
@ -926,11 +926,11 @@ rpmbuild -bs --nodeps [SRPM]
|
|||
rpm -qpiv /builddir/build/SRPMS/[SRPM]
|
||||
....
|
||||
|
||||
Check the `rpm` output for unexpanded macros (`%{foo}`) or missing information (when`%{?foo}` is expanded to the empty string). Even easier is to simply avoid macros in `Summary:` and `%description` unless they are defined in the current spec file.
|
||||
Check the `+rpm+` output for unexpanded macros (`+%{foo}+`) or missing information (when`+%{?foo}+` is expanded to the empty string). Even easier is to simply avoid macros in `+Summary:+` and `+%description+` unless they are defined in the current spec file.
|
||||
|
||||
=== Improper use of %_sourcedir
|
||||
|
||||
Packages which use files itemized as Source# files, must refer to those files by their `Source#` macro name, and must not use `$RPM_SOURCE_DIR` or `%{sourcedir}` to refer to those files. See Packaging:RPM_Source_Dir for full details.
|
||||
Packages which use files itemized as Source# files, must refer to those files by their `+Source#+` macro name, and must not use `+$RPM_SOURCE_DIR+` or `+%{sourcedir}+` to refer to those files. See Packaging:RPM_Source_Dir for full details.
|
||||
|
||||
=== Software Collection Macros
|
||||
|
||||
|
|
@ -942,16 +942,16 @@ In the past, SCL macros were allowed to be present inside of mainstream packages
|
|||
|
||||
Additional RPM macros must be stored in %\{_rpmmacrodir}. They must be named using the syntax "macros.$PACKAGE" (e.g. macros.perl).
|
||||
|
||||
Normally, these files are packaged in the -devel subpackage, since they are usually only needed for building other packages. However, in some situations, this is not always ideal and packagers are encouraged to use their best judgment when determining the proper package for these files. RPM macro files MUST NOT be marked as `%config`.
|
||||
Normally, these files are packaged in the -devel subpackage, since they are usually only needed for building other packages. However, in some situations, this is not always ideal and packagers are encouraged to use their best judgment when determining the proper package for these files. RPM macro files MUST NOT be marked as `+%config+`.
|
||||
|
||||
== Scripting inside of spec files
|
||||
|
||||
Sometimes it is necessary to write a short script (perhaps a one-liner) that is executed in the %prep, %build, or %install sections of a spec file to get some information about the build environment. In order to simplify the dependency graph, spec files should only use the following languages for this purpose:
|
||||
|
||||
` 1. Python` +
|
||||
` 2. Perl` +
|
||||
` 3. Standard programs used in shell programing, for instance gawk or sed` +
|
||||
` 4. Lua (as supported by the native lua interpreter in rpm)`
|
||||
`+ 1. Python+` +
|
||||
`+ 2. Perl+` +
|
||||
`+ 3. Standard programs used in shell programing, for instance gawk or sed+` +
|
||||
`+ 4. Lua (as supported by the native lua interpreter in rpm)+`
|
||||
|
||||
Additionally, if your package cannot build without a specific scripting language (such as Ruby, or Tcl), and therefore already has a BuildRequires on that language, it may also be called from the spec file.
|
||||
|
||||
|
|
@ -959,11 +959,11 @@ Note: If you call perl or python in your spec file (and it is not already a Buil
|
|||
|
||||
== %global preferred over %define
|
||||
|
||||
Use `%global` instead of `%define`, unless you really need only locally defined submacros within other macro definitions (a very rare case).
|
||||
Use `+%global+` instead of `+%define+`, unless you really need only locally defined submacros within other macro definitions (a very rare case).
|
||||
|
||||
Rationale: The two macro defining statements behave the same when they are a the top level of rpm's nesting level.
|
||||
|
||||
But when they are used in nested macro expansions (like in `%{!?foo: ... }` constructs, `%define` theoretically only lasts until the end brace (local scope), while `%global` definitions have global scope.
|
||||
But when they are used in nested macro expansions (like in `+%{!?foo: ... }+` constructs, `+%define+` theoretically only lasts until the end brace (local scope), while `+%global+` definitions have global scope.
|
||||
|
||||
Note that %define and %global differ in more ways than just scope: the body of a %define'd macro is lazily expanded (ie when used), but the body of %global is expanded at definition time. It's possible to use %%-escaping to force lazy expansion of %global.
|
||||
|
||||
|
|
@ -983,14 +983,14 @@ For Qt-based packages that use the Linguist tool chain, for the localization uti
|
|||
BuildRequires: qt-devel
|
||||
....
|
||||
|
||||
If you have few enough locale files that they can all go into one package, you can use the `%find_lang` macro. (If you need to split your package into separate language packs, please see Packaging:Langpacks[the langpack guidelines].) This macro will locate all of the them belonging to your package (by name), and put this list in a file. You can then use that file to include all of the locales. `%find_lang` should be run in the %install section of your spec file, after all of the files have been installed into the buildroot. The correct syntax for `%find_lang` is usually:
|
||||
If you have few enough locale files that they can all go into one package, you can use the `+%find_lang+` macro. (If you need to split your package into separate language packs, please see Packaging:Langpacks[the langpack guidelines].) This macro will locate all of the them belonging to your package (by name), and put this list in a file. You can then use that file to include all of the locales. `+%find_lang+` should be run in the %install section of your spec file, after all of the files have been installed into the buildroot. The correct syntax for `+%find_lang+` is usually:
|
||||
|
||||
....
|
||||
%find_lang %{name}
|
||||
....
|
||||
|
||||
In some cases, the application may use a different "name" for its locales. You may have to look at the locale files and see what they are named. If they are named `myapp.mo`, then you will need to pass `myapp` to `%find_lang` instead of `%{name}`.
|
||||
After `%find_lang` is run, it will generate a file in the active directory (by default, the top level of the source dir). This file will be named based on what you passed as the option to the `%find_lang` macro. Usually, it will be named `%{name}.lang`. You should then use this file in the `%files` list to include the locales detected by `%find_lang`. To do this, you should include it with the -f parameter to `%files`.
|
||||
In some cases, the application may use a different "name" for its locales. You may have to look at the locale files and see what they are named. If they are named `+myapp.mo+`, then you will need to pass `+myapp+` to `+%find_lang+` instead of `+%{name}+`.
|
||||
After `+%find_lang+` is run, it will generate a file in the active directory (by default, the top level of the source dir). This file will be named based on what you passed as the option to the `+%find_lang+` macro. Usually, it will be named `+%{name}.lang+`. You should then use this file in the `+%files+` list to include the locales detected by `+%find_lang+`. To do this, you should include it with the -f parameter to `+%files+`.
|
||||
|
||||
....
|
||||
%files -f %{name}.lang
|
||||
|
|
@ -998,21 +998,21 @@ After `%find_lang` is run, it will generate a file in the active directory (by d
|
|||
...
|
||||
....
|
||||
|
||||
Note that `%find_lang` by default searches for gettext locales, but it can also handle Qt translations, localised manpages and help files.
|
||||
Note that `+%find_lang+` by default searches for gettext locales, but it can also handle Qt translations, localised manpages and help files.
|
||||
|
||||
To process GNOME help files put into `/usr/share/gnome/help/` use
|
||||
To process GNOME help files put into `+/usr/share/gnome/help/+` use
|
||||
|
||||
....
|
||||
%find_lang %{name} --with-gnome
|
||||
....
|
||||
|
||||
To process KDE help files put into `/usr/share/doc/HTML/` use
|
||||
To process KDE help files put into `+/usr/share/doc/HTML/+` use
|
||||
|
||||
....
|
||||
%find_lang %{name} --with-kde
|
||||
....
|
||||
|
||||
To process Qt's `.qm` binary translation files use
|
||||
To process Qt's `+.qm+` binary translation files use
|
||||
|
||||
....
|
||||
%find_lang %{name} --with-qt
|
||||
|
|
@ -1024,11 +1024,11 @@ To process localised manpages (doesn't include the default, non-localised one),
|
|||
%find_lang %{name} --with-man
|
||||
....
|
||||
|
||||
To see all the options, run `/usr/lib/rpm/find-lang.sh` in the terminal.
|
||||
To see all the options, run `+/usr/lib/rpm/find-lang.sh+` in the terminal.
|
||||
|
||||
Names different from `%{name}` (e.g. multiple manpages) must be handled via separate calls to `%find_lang`.
|
||||
Names different from `+%{name}+` (e.g. multiple manpages) must be handled via separate calls to `+%find_lang+`.
|
||||
|
||||
Here is an example of proper usage of `%find_lang`, in `foo.spec` with the "foo" application localised using gettext and man pages named "bar" instead of "foo":
|
||||
Here is an example of proper usage of `+%find_lang+`, in `+foo.spec+` with the "foo" application localised using gettext and man pages named "bar" instead of "foo":
|
||||
|
||||
....
|
||||
Name: foo
|
||||
|
|
@ -1061,10 +1061,10 @@ make DESTDIR=%{buildroot} install
|
|||
|
||||
=== Why do we need to use %find_lang?
|
||||
|
||||
Using `%find_lang` helps keep the spec file simple, and helps avoid several other packaging mistakes.
|
||||
Using `+%find_lang+` helps keep the spec file simple, and helps avoid several other packaging mistakes.
|
||||
|
||||
* Packages that use `%{_datadir}/*` to grab all the locale files in one line also grab ownership of the locale directories, which is not permitted.
|
||||
* Most packages that have locales have lots of locales. Using `%find_lang` is much easier in the spec file than having to do:
|
||||
* Packages that use `+%{_datadir}/*+` to grab all the locale files in one line also grab ownership of the locale directories, which is not permitted.
|
||||
* Most packages that have locales have lots of locales. Using `+%find_lang+` is much easier in the spec file than having to do:
|
||||
|
||||
....
|
||||
%{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo
|
||||
|
|
@ -1075,9 +1075,9 @@ Using `%find_lang` helps keep the spec file simple, and helps avoid several othe
|
|||
...
|
||||
....
|
||||
|
||||
* As new locale files appear in later package revisions, `%find_lang` will automatically include them when it is run, preventing you from having to update the spec any more than is necessary.
|
||||
* As new locale files appear in later package revisions, `+%find_lang+` will automatically include them when it is run, preventing you from having to update the spec any more than is necessary.
|
||||
|
||||
Keep in mind that usage of `%find_lang` in packages containing locales is a MUST unless the locale files are broken out into langpacks. In which case, you should follow Packaging:Langpacks[the langpack guidelines].
|
||||
Keep in mind that usage of `+%find_lang+` in packages containing locales is a MUST unless the locale files are broken out into langpacks. In which case, you should follow Packaging:Langpacks[the langpack guidelines].
|
||||
|
||||
== Log Files
|
||||
|
||||
|
|
@ -1102,13 +1102,13 @@ Since these are config files, they must be marked as %config(noreplace) in the %
|
|||
|
||||
== Timestamps
|
||||
|
||||
When adding file copying commands in the spec file, consider using a command that preserves the files' timestamps, eg. `cp -p` or `install -p`.
|
||||
When adding file copying commands in the spec file, consider using a command that preserves the files' timestamps, eg. `+cp -p+` or `+install -p+`.
|
||||
|
||||
When downloading sources, patches etc, consider using a client that preserves the upstream timestamps. For example `wget -N` or `curl -R`. To make the change global for wget, add this to your `~/.wgetrc`: `timestamping = on`, and for curl, add to your `~/.curlrc`: `-R`.
|
||||
When downloading sources, patches etc, consider using a client that preserves the upstream timestamps. For example `+wget -N+` or `+curl -R+`. To make the change global for wget, add this to your `+~/.wgetrc+`: `+timestamping = on+`, and for curl, add to your `+~/.curlrc+`: `+-R+`.
|
||||
|
||||
== Parallel make
|
||||
|
||||
Whenever possible, invocations of `make` should be done as
|
||||
Whenever possible, invocations of `+make+` should be done as
|
||||
|
||||
....
|
||||
%make_build
|
||||
|
|
@ -1122,7 +1122,7 @@ Do make sure, however, that the package builds cleanly this way as some make fil
|
|||
%_smp_mflags -j3
|
||||