From Mageia wiki
Jump to: navigation, search
(Maintaining a Package)
m (obsoleting %apply_patch by autopatch -p[01])
Line 266: Line 266:
 
To create patches, you can ease your work by using something like http://labix.org/patcher
 
To create patches, you can ease your work by using something like http://labix.org/patcher
  
*'''Using %apply_patches'''
+
*'''Using %apply_patches''' (deprecated, use '''%autopatch''' instead)
 
This may be used to replace all the %patchN lines in %prep and can save space in the spec file (especially in packages with many upstream patches) as it will apply all patches listed with one command. However, for this to work '''all''' the patches must be '''-p1''' and the PatchN: keyword definitions '''must''' be placed immediately following the SourceN: definitions in the spec file, otherwise they may be silently ignored (no error messages during build) so be careful.
 
This may be used to replace all the %patchN lines in %prep and can save space in the spec file (especially in packages with many upstream patches) as it will apply all patches listed with one command. However, for this to work '''all''' the patches must be '''-p1''' and the PatchN: keyword definitions '''must''' be placed immediately following the SourceN: definitions in the spec file, otherwise they may be silently ignored (no error messages during build) so be careful.
Alternatively, the macro '''%autopatch -p1''' may be used, which works essentially the same way. This is a new standard macro from upstream RPM, and therefore provides better compatibility with other distributions.
+
 
 +
*'''%autopatch -p[01]'''
 +
This works essentially the same way as '''%apply_patches'''. This is a new standard macro from upstream RPM, and therefore provides better compatibility with other distributions.
  
 
=== %clean ===
 
=== %clean ===

Revision as of 10:58, 10 May 2019


Drakconf multiflag.png
Other languages
English ; Français ;

Warning Icon.png This page is WORK IN PROGRESS and needs to be adapted to Mageia packaging policies. Feel free to proofread and correct where needed. Markup in Italic shows passages which need to be revised.

Mageia Packaging Guidelines

These guidelines are based on Fedora, OpenSUSE, Meego and other distributions' guidelines.

Maintaining a Package

Every package in Mageia needs a maintainer (AKA owner, bug owner). Any package without an owner will automatically be nominated for deletion from Mageia. A package maintainer is responsible for making sure that

  • packages are up to date with latest upstream
  • packages consistently build in the Mageia build system and fix build failures when they occur
  • package meta data in the RPM spec file is accurate
  • the license of the package is correct
  • she/he follow upstream for any critical security issues and fix them as soon as possible
  • she/he provides information about major changes to other packagers and maintainer to allow enough time for fixing compatibility issues

Currently the data about ownership of packages is tracked in http://pkgsubmit.mageia.org/data/maintdb.txt and unmaintained packages are listed in http://pkgsubmit.mageia.org/data/unmaintained.txt. This will be better integrated and managed at a later point, and we will have a grace period for unmaintained packages. After the grace period, packages without a maintainer will be reviewed and any packages without a maintainer will be nominated for deletion.

To add yourself as a maintainer of a package, please follow the steps below:

  • Update to the most recent version of mgarepo
  • Identify the packages of which you are the ultimate maintainer
  • Do the following for every package you want to maintain:
 mgarepo maintdb set [packagename] [yourlogin]
  • This can be done only by packagers, apprentices have no rights to the maintdb command
  • You can only do this if the package is currently maintained by nobody!
  • Your request will be processed immediately and you will then be the maintainer of the package. Good deed, you helped save some unmaintained packages. Now go on and show some love to them :)


The current status can be seen here: http://pkgsubmit.mageia.org/data/maintdb.txt or if you already have a full packager account (i.e. you're not an apprentice) you can query the maintainer database like so:

 mgarepo maintdb get [packagename]

or you can ask Sophie on IRC:

 :maint [packagename]


[WIP] Non-maintainer updates

Mageia has a lot of packages and relatively few packagers. We, as a community, always do what we do to make Mageia a better distribution and if/when we step on somebody's toes, we've done it in good faith because we want to make Mageia the best it can be.

This development deserves a set of guidelines or policies and here is a Work In Progress list proposed on @dev.

  • Non-maintainer release bumps are fine, no need to ask maintainer, unless it's a substantial change (most of the time those are rebuilds or small fixes)
  • Non-maintainer version bumps should be discussed with the registered maintainer (in maintdb), when:
    • The package is well-established as being maintained by one person or a group of persons (firefox, KDE stack, kernel, etc.)
    • The maintainer is active, i.e. has been working on packages, MLs or bugzilla during the last couple of months
    • The version bump is substantial: major/minor bump or soname change, non-trivial spec changes like syncing with another distro that was not the maintainer's documented update workflow
  • For security issues, non-maintainer uploads are fine if the maintainer hasn't commented on the bug report yet and a reasonable amount of time has passed. Of course, use common sense, if it's the kernel or glibc, give the maintainer a chance to review your changes.
  • In other cases, use empathy and your best judgement. Sending a two lines email to a maintainer to notify of your wish to update a package doesn't cost much. Many times, you'd even get an answer saying that you can go ahead and thanking you for your work, which is always worth taking IMO :)
  • When doing non-maintainer uploads, be conservative with your changes. Don't drop patches that you don't understand, ask the maintainer, and use the answer to better document the purpose of said patches. Don't sync with a new upstream or another distro without asking (unless that package is identified as synced with a given distro, e.g. rust or firefox).

Package Naming

  • The base package names (used for svn and src.rpm) should be the upstream name of the software project, always lowercase. Upstream names can contain digits, '+', '_' or '.', but no other special characters. Really exceptionally, uppercase letters can be allowed if there is proper justification (e.g. perl packages) or historical reasons.
  • Package names that are built by Mageia packagers from the upstream name by adding suffixes should always use '-' as delimiter (e.g. foo-devel or foo-plugins as derived from the foo package). All '_' and '+' in package names must come from upstream naming! The '.' in package names should only come upstream or standard versioning schemes.
  • The spec file should be named using the %{name}.spec scheme, i.e. the name of the source package and svn directory should be used as the name for the spec.

Version and Release

Package Versions look like : X.Y.Z - R mga V

  • X.Y.Z is the 'Version' number which should represent the version of the project

* R is the 'Release' tag which needs to be always incremented after committing a change to the package before submitting this package for a new build

  • mga is the distsuffix
  • V is the distro version number

Version

The Version field in the spec file is where you should put the current version of the software being packaged. There are some cases in which a source file comes with a "version number" containing non-numeric characters:

  • Pre-release packages: Packages released as "pre-release" versions, prior to a "final" version. Example tags include "alpha", "beta", "rc", "cvs", "git", "svn", etc..., and should be appended to the Release Tag, and not to the Version field. Details can be found below:

Pre-Release Versions

For pre-release or development packages the Release tag should start with "0." so when this software becomes final and does not change Version, we can assure a safe upgrade to the stable version by just changing Release to 1.

Example:

mysourcefile-2.9rc2.tar.gz yields a specfile containing Version: 2.9 and Release: %mkrel 0.rc2.1

For each rebuilt of the same pre-released package, just increase the Release tag; for instance, 0.rc2.1 would become 0.rc2.2 etc...

It is recommended to use the macro "%mkrel -c rc2 1" to generate 0.rc2.1.

For svn or git checkouts, it is preferred to include the date of the snapshot, with or without the release number or git hash (which should at least be as comments in the spec file). The following are acceptable:

%mkrel -c svn20130213 1
%mkrel -c 20130213svn85423 1
%mkrel -c git20130213 1
%mkrel -c 20130213gitae25f2 1

rtmpdump can help deal with snapshots, with its %snap and %mkrel usage: http://svnweb.mageia.org/packages/cauldron/rtmpdump/current/SPECS/rtmpdump.spec?view=markup

Release

The release number should start with 1, and be set back to 1 with every new version, and increased by one with any change in the package.


Sub-Release (only applies for updates)

See relevant section of our updates policy

Tags

  • The Packager tag should not be used in spec files. The identities of the packagers are evident from the changelog entries. By not using the Packager tag, you also avoid seeing bad binaries rebuilt by someone else with your name in the header. See also the Maximum RPM definition of the Packager tag . If you need to include information about the packager in the rpms you built, use %packager in your ~/.rpmmacros instead.
  • The Vendor tag also should not be used. It is set automatically by the build system.
  • Usually, the PreReq tag should be replaced by plain Requires. For more info, see Maximum RPM fine-grained dependencies chapter.
  • The Source tag documents where to find the upstream sources for the rpm. In most cases, this should be a complete URL to the upstream tarball. Best practice would be using macros like %version and %name where possible to allow for automatic updates, but this is not necessary.

Summary Tag

This tag is a single line string describing the package. The maximum length is 79 characters and it should start with an uppercase letter and not with a space. The summary must not end with a dot (.) If this bothers you from a grammatical point of view, sit down, take a deep breath, and get over it.

The name of the package should not be repeated in its summary. This is often redundant information and looks silly in various programs' output.

It should fit all standard situations and not assume any special context. It should be helpful alone, in alphabetically sorted or unsorted lists of some selected packages, and in alphabetically sorted or unsorted lists of all packages.

It should describe the package's main function and point out any special properties of the package to support the user comparing similar packages. For example, the two words "Web Browser" summarize any web browser, but using additional adjectives (like minimalistic, complex, GNOME, KDE, text-based, fast, or author's) helps characterize a specific package.

The summary should be brief and to the point without including redundant information.

The RPM spec file contains only the English version to keep the RPM database small.

RPM Group Tag

The RPM group tag is used to group packages by the types of functionality they provide, and also makes up the list of Categories in rpmdrake. Following is the list of the groups to use for building an RPM package for Mageia. It is now different from the old one invented and used by Red Hat, because it appeared (from our point of view) that it was no longer suitable for today's distribution. You can still see it at [1]

For a complete list please read Mageia policy

BuildRoot

The BuildRoot tag is deprecated and should be removed where encountered, as it is handled directly by rpm in Mageia.

PreReq

Packages should not use the PreReq tag. Once upon a time, in dependency loops PreReq used to "win" over the conventional Requires when RPM determined the installation order in a transaction. This is no longer the case.

Requires / Explicit Requires

Packages should only contain Requires if those are absolutely necessary for the program to work correctly. Use versioned Requires where needed as explained below.

Packages must not contain explicit Requires on libraries except when absolutely necessary. When explicit library Requires are necessary, there should be a spec file comment justifying it.

We generally rely on rpmbuild to automatically add dependencies on library SONAMEs, shell script interpreters, and modules used by programs written in popular scripting languages like Perl & Python. Modern package management tools are capable of resolving such dependencies to determine the required packages. Explicit dependencies on specific package names may aid the inexperienced user who attempts to install RPM packages manually, however, history has shown that such dependencies add confusion when library or files are moved from one package to another, when packages get renamed, or when one out of multiple alternative packages would suffice. Additionally, in some cases, old explicit dependencies on package names require unnecessary updates & rebuilds.

rpmbuild will automatically add versioned dependencies in a few cases: on library SONAMEs (which operate as library major version numbers), weak symbol versions from glibc, and the Perl or Python API version when installing a binary or versioned extension module. Explicit versioned dependencies are required when they are needed to allow correct updates on stable release or upgrades from one release to another, and are helpful when backporting packages. However, they can become out-of-date, inaccurate and superfluous over time, and should be revisited once the versions in question become ancient history. The rule of thumb is to add (or keep) an explicit version if it is required for upgrading from either of the last two stable releases.

Versioned dependencies are especially critical for upgraded and backported packages in a stable release. Users may elect to install a subset of packages during an upgrade which could leave an older version of a necessary package installed and result in a non-functioning system.

An exemplary rationale for a versioned explicit dependency:

  # The automatic dependency on libfubar.so.1 is insufficient,
  # as we strictly need at least the release that fixes two segfaults.
  Requires: libfubar >= 0:1.2.3-7

Exceptions from automatically generated Requires/Provides

As all files in a package are automatically scanned what facilities they require and what they provide, it is sometimes necessary to change this and exclude some of those facilities. To do this, you can do it like this:

 # Suppress automatically generated Requires for devel packages
 %global __requires_exclude devel\(.*\)

or


This requires some editing as the code has changed (October 2014)

Use now for pear packages: %global __requires_exclude pear\\(Blowfish/DefaultKey.php\\)



 # Suppress automatically generated Requires for pear packages
 %global __requires_exclude pear(vendor/autoload.php)\\|pear(xmlapi.php)
 # we don't want to provide private python extension libs
 %define __provides_exclude_from ^(%{python_sitearch}/.*\\.so\\|%{python3_sitearch}/.*\\.so)$


You can also see this page in the Fedora wiki for more information on this.

Debugging loop dependencies =

An issue is often the existence of too much ordering hints which conflicts between themselves. As such librpm has to break the dependencies cycle and do so randomly in order to have some kind of ordering as a perfect ordering isn't possible when deps tags conflicts.

One can use "urpmi --debug-librpm --deploops" in order to debug such situations...

Upgrades from previous releases can be solved by breaking depsloops.

BuildRequires

In package development and testing, please verify that your package is not missing any necessary build dependencies. Having proper build requirements saves the time of all developers and testers as well as build systems because they will not need to search for missing build requirements manually. It is also a safety feature that prevents builds that would not otherwise fail, but would be missing crucial features. For example, a graphical application may exclude PNG support after its configure script detects that libpng is not installed.

BuildRequires should be listed one per line for maximum readability; instead of cramming multiple BuildRequires on a single line, use one BuildRequires tag per dependency. While RPM may be able to quickly “view” that really long line of BuildRequires, humans cannot and while this may make the spec longer, it makes it easier to read. Before adding BuildRequires to any package, please be comfortable with Requires . Also please check that you don't add unnecessary BuildRequires. If you BuildRequire package "A" and this has Requires on package "B" and "C" it's useless to buildrequire package "B" and "C" additionally. You can check this with urpmq -pd on package "A".

You should always use architecture-independent virtual provides as BuildRequires. Arch-independent virtual provides are for example %name-devel (which has to manually added according to our library policy or pkgconfig(name) (which is available for many packages already, and automatically generated)

For example don't use libsqlite3-devel, but use either sqlite3-devel or pkgconfig(sqlite3). You can check which virtual provides a -devel package has like so:

 rpm -q --provides lib64sqlite3-devel

which would result in these:

libsqlite3-devel = 3.7.6.2-3.mga1
sqlite3-devel = 3.7.6.2-3.mga1
pkgconfig(sqlite3) = 3.7.6.2
devel(libsqlite3(64bit))
lib64sqlite3-devel = 3.7.6.2-3.mga1
lib64sqlite3-devel(x86-64) = 3.7.6.2-3.mga1

As you can see, only the two recommended above bear no reference to the architecture, unlike devel(libsqlite3(64bit)) or lib64sqlite3-devel(x86-64).

IMPORTANT: If you use some binaries like desktop-file-install you must buildrequire the packages which contain them, otherwise, the package will fail to build on the Mageia build system.


When you build a package locally, you can easily install the BuildRequires of package foo using the command:

 urpmi foo.spec

(or urpmi --buildrequires foo.spec or urpmi --buildrequires foo.src.rpm which would be the more correct syntax) It will pull in all packages listed in the spec-file as BuildRequires.


ExclusiveArch / ExcludeArch / %ifarch / %ifnarch

Use ExclusiveArch when you are sure the package only works on some architectures. Use ExcludeArch when you know the package doesn't work on some arch, but don't know the exact arches it does work on.

For x86 (i586) the macro to use is %ix86.

%ifarch/%ifnarch should be avoided as much as possible, at least for patching. In general, you should not apply a patch conditionally only for one architecture. This will also give an rpmlint warning:


%ifarch-applied-patch
A patch is applied inside an %ifarch block. Patches must be
applied on all architectures and may contain necessary configure
and/or code patch to be effective only on a given arch.

Sources

Source files must begin with Source0, do not use Source: and then Source1:; if a package has exactly one source file, still use Source0 as it may not always continue to have exactly one source file. If a source file has a downloadable URL that it came from, it must be included. In most cases this should be a complete URL to the upstream tarball. Best practice would be to use macros like %version and %name for this URL where possible to allow for automatic updates, but this is not necessary.

Patches

Each problem should be solved in a separate patch. To allow easy maintenance of patches, the source of the patch should be indicated, especially if the patch may need to be updated from the same source in the future. When the patch is first added, the source of the patch should be stated in the commit message. It also helps to have a comment in the SPEC where the patch comes from, which should be a complete URL to the upstream if this is not obvious, and a description what the patch does in short simple words, if that is not clearly self-evident from the patch name.

Patches should start from Patch0 keyword in SPEC, similar to the Source tag. Patches should be named in a very explicit manner to make it very clear against which version of the software the patch was originally generated or applied. To that end, patch names usually follow the convention of [package_name]-[version]-[description].[filename suffix]:

  • [package_name] is the name of the package it applies against, such as 'shadow-utils' or 'gnupg'
  • [version] is the version of the program this patch was developed against, such as 1.0. If a patch is rediffed because the old patch does not apply to a new version, a new patch must be created with the appropriate name – it is inappropriate to rediff foo-1.0-linking-fix.patch against foo-1.2 and continue to use the same patch name. The new patch must be named foo-1.2-linking-fix.patch. For historical purposes, patches should be moved in svn; instead of doing “svn rm foo-1.0-linking-fix.patch” and “svn add foo-1.2-linking-fix.patch”, the original patch should be moved and then the newly-derived patch copied and committed; i.e. “svn mv foo-1.0-linking-fix.patch foo-1.2-linking-fix.patch; svn commit”
  • [description] is a short description of the patch's purpose
  • [filename suffix] Normally this is .patch or in some cases, mostly when reusing upstream patches .diff

Patches should be in the unified format (diff -u) and should be applied with 1 strip level in the spec file (%patch -p1). The only exceptions are the patches obtained from another primary source site. The original name, suffix, and format is preserved in this case. Each patch should be kept in plaintext format and uncompressed, to allow for usage with SVN web frontend for example.

For the patches to be applied, the patches should be mentioned in %prep below %setup, and should be done as follows

%patch0 -p1 -b .foobar
  • -p1 is the patch level, relative from where the patch is applied from
  • -b is the suffix that is appended to the backup files which the patch command creates, in this case .foobar, this should similar to or derived from the [description] part of the patch filename (see above).

To create patches, you can ease your work by using something like http://labix.org/patcher

  • Using %apply_patches (deprecated, use %autopatch instead)

This may be used to replace all the %patchN lines in %prep and can save space in the spec file (especially in packages with many upstream patches) as it will apply all patches listed with one command. However, for this to work all the patches must be -p1 and the PatchN: keyword definitions must be placed immediately following the SourceN: definitions in the spec file, otherwise they may be silently ignored (no error messages during build) so be careful.

  • %autopatch -p[01]

This works essentially the same way as %apply_patches. This is a new standard macro from upstream RPM, and therefore provides better compatibility with other distributions.

%clean

The %clean section is deprecated and should be removed where encountered, as it is handled directly by rpm in Mageia.

Documentation

Any relevant documentation included in the source distribution should be included in the package. Irrelevant documentation include build instructions, the omnipresent INSTALL file containing generic build instructions, for example, and documentation for non-Linux systems, e.g. README.MSDOS. Pay also attention to 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, and Documentation as the value of the Group tag.

Also, 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.

Check that documentation file permissions allow reading by normal users.

When only English man pages are available, install them uncompressed to %{buildroot}%{_mandir}/manX/ (where X is the appropriate section number). They will be automatically compressed before being packaged, so they must be referred to in the %files section with a wildcard, e.g. %{_mandir}/man1/xyzzy.1*. Man pages will be automatically given the %doc attribute, so don't add that explicitly.

Devel Packages

If the software being packaged contains files intended solely for development, those files should be put in a -devel subpackage. The following are examples of file types which should be in -devel:

  • Header files (such as .h files)
  • Unversioned shared libraries (such as libfoo.so). Versioned shared libraries (such as libfoo.so.3, libfoo.so.3.0.0) should not be in -devel.

A good rule of thumb is if the file is used for development and not needed for the base package to run properly, it should go in -devel.

.a files and .la files should generally not be included anywhere. They are only useful when one wants to statically link a program against the library (i.e. include the library in the program binary itself, so the library isn't needed at run-time), which is generally not done in Mageia. Libtool archives, foo.la files, should not be included. Packages using libtool will install these by default even if you configure with --disable-static, so they may need to be removed before packaging. Due to bugs in older versions of libtool or bugs in programs that use it, there are times when it is not always possible to remove *.la files without modifying the program. In most cases, it is fairly easy to work with upstream to fix these issues. Note that if you are updating a library in a stable release (not devel) and the package already contains *.la files, removing the *.la files should be treated as an API/ABI change -- ie: Removing them changes the interface that the library gives to the rest of the world and should not be undertaken lightly.

Requiring Base Package

Devel packages must require the base package using a fully versioned dependency: Requires: %{name} = %{version}-%{release} Usually, subpackages other than -devel should also require the base package using a fully versioned dependency.

Pkgconfig Files

The placement of pkgconfig(.pc) files depends on their usecase. Since they are almost always used for development purposes, they should be placed in a -devel package. A reasonable exception is when the main package itself is a development tool not installed in a user runtime, such as gcc or gdb.

Shared Libraries

Whenever possible (and feasible), Mageia Packages containing libraries should build them as shared libraries.

An ldconfig isn't needed anymore for libraries in %post and %postun, this is handled automagically by RPM filetriggers . If this is encountered, please remove the ldconfig calls and if this is the only purpose of %post / %postun then remove the whole %post / %postun section

See Libraries policy for more details on how to package libraries.

Configuration files

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.

Don't use %config or %config(noreplace) under /usr. /usr is deemed to not contain configuration files in Mageia.

Service Management / Initscripts

Since Mageia 3 systemd is the only init system offered, however, it is still able to support SystemV-style initscripts with the caveat that they must contain valid LSB headers to allow for proper dependency information to be extracted.

Mageia 2 supported both SystemV and systemd boots and thus required both a SystemV-style initscript and (optionally) a systemd unit.

Mageia 1 only supported SystemV.

For more information on packaging services see the System Service policy.

Desktop files

If a package contains a GUI application, then it needs to also include a properly installed .desktop file. For the purposes of these guidelines, a GUI application is defined as any application which draws an X window and runs from within that window. Installed .desktop files MUST follow the desktop-entry-spec , paying particular attention to validating correct usage of Name, GenericName, Categories , StartupNotify entries. Please always validate .desktop files via desktop-file-validate from the package desktop-file-utils.

Icon key in Desktop Files

The icon key can only be specified in one way:

  • Short name without file extension/path:

Icon=comical

The short name without file extension allows for icon theming (it assumes .png by default, then tries .svg and finally .xpm)

.desktop file creation

If the package doesn't already include and install its own .desktop file, you need to make your own. You can do this by generating a .desktop file you create as a Source: (such as Source3: %{name}.desktop) or generating it in the spec file via a "here document". Here is an example of such a here document, the green part is the contents of the .desktop file


 mkdir -p %{buildroot}%{_datadir}/applications
 cat > %{buildroot}%{_datadir}/applications/%{name}.desktop << EOF
 [Desktop Entry]
 Name=Ginkgo
 Comment=Ginkgo is a graphical front-end for Nepomuk
 Exec=%{_bindir}/%{name}
 Icon=nepomuk
 Type=Application
 Categories=Utility;KDE;Qt;
 EOF

Localizing .desktop files

The values of Name or GenericName are displayed as captions to the graphical desktop icon, so they should be localized according to the Desktop Entry Specification. Most of the time, only language codes or language/country codes are needed to select the intended system locale. For example:

[Desktop Entry]
Type=Application
Name=Clocks
Name[de]=Uhrzeit
Name[es]=Relojes
Name[fr]=Horloges
Name[pt_BR]=Relógios
Name[zh_CN]=时钟

In the above .desktop file, [de] specifies the German language locale, covering any German-speaking locale, such as de_DE or de_AT.

Note: Since a language/country code (e.g. pt_BR) is more specific than a language code (e.g. pt), a string for the pt_BR locale will not be used for the Portuguese language locale (pt). If a string is appropriate for every Portuguese locale, you can use "Name[pt]" instead.

desktop-file-install usage

desktop-file-install SHOULD be used if there are changes desired to an upstream provided .desktop file (such as add/removing categories, etc). Note: The limited available editing options can be queried via desktop-file-install --help-edit or desktop-file-install --help-all

Here are some usage examples:


 desktop-file-install --vendor="%{_real_vendor}" \
 --remove-category="Application" \
 --add-category="Settings;HardwareSettings;" \
 --dir %{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/%{name}.desktop


 desktop-file-install --vendor="%{_real_vendor}" \
 --dir=%{buildroot}%{_datadir}/applications \
 --remove-category='Application' \
 --remove-category='Utility' \
 --add-category='System' \
 --add-category='Settings' \
 --add-category='Printing' \
 --add-category='Qt' \
 --add-category='HardwareSettings' \
 --add-category='X-Mageia-CrossDesktop' \
 --remove-key='Version' \
 %{buildroot}%{_datadir}/applications/hplip.desktop

The installation of the desktop file on the target system does not have to be handled manually anymore as had to be done previously in %post/%postun, this is automagically handled now via RPM filetriggers. Just make sure that all desktop files you want to install are correct and validated as pointed out above.

MandrivaLinux special categories

In many older .desktop files in packages imported from Mandriva there are deprecated X-MandrivaLinux category entries. They were used when switching from Debian Menu System to Freedesktop XDG menu system, and are deprecated and should be replaced by standard Freedesktop categories. Those can be seen in Freedesktop specification

The only Mandriva one that has an equivalent in Mageia is X-MandrivaLinux-CrossDesktop. This is for applications which have toolkit-related categories (like GTK, QT, KDE) in their desktop files (and would thus be shown in More submenu in other desktop environments) when we want them to not go to the More submenu on any desktop. These entries should be replaced by X-Mageia-CrossDesktop. For reference have a look at this bugreport: Bug 2449 - X-MandrivaLinux-* should be dropped

Here's one example on how it should be done. totem.desktop file from Totem media player contains:

 Categories=GTK;GNOME;AudioVideo;Player;Video;X-MandrivaLinux-CrossDesktop;X-MandrivaLinux-Multimedia-Video;

So X-MandrivaLinux-CrossDesktop should be replaced by X-Mageia-CrossDesktop (or one could remove the GTK and GNOME categories from the desktop file, but this will also remove information which could be useful to some desktop environments)

Also X-MandrivaLinux-Multimedia-Video is such a deprecated category and should definitely not be used anymore, instead replaced by the main Freedesktop category AudioVideo and supplemented by at least one additional category from http://standards.freedesktop.org/menu-spec/latest/apa.html. As this is already the case (AudioVideo;Player;Video; see above) this X-MandrivaLinux category should simply be removed.

Macros vs. variables

%{buildroot} and %{optflags} vs $RPM_BUILD_ROOT and $RPM_OPT_FLAGS There are generally two styles of defining the rpm BuildRoot and Optimization Flags in a spec file:

macro style variable style
Build Root %{buildroot} $RPM_BUILD_ROOT
Opt. Flags %{optflags} $RPM_OPT_FLAGS

According to our SPEC syntax policy variables which are really definitions, such as $RPM_OPT_FLAGS or $RPM_BUILD_ROOT must not be used. Macros like %{optflags} and %{buildroot} must be used instead. Keep "$*" variables strictly limited to shell constructs and not RPM-based definitions.

Handling Locale Files

Locale files, also known as localisations or (as an abbreviation) l10n files or i18n files (short form of internationalisation, the number shows how many letters have been left out) are compiled .mo files. This section is not about man pages.


(If a package includes translations, it is no longer needed to add the gettext BuildRequire, because gettext is already present in the build environment.)

Mageia includes an rpm macro called %find_lang. This macro will locate all of the locale files that belong 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.

%files -f %{name}.lang
%{_bindir}/foobar
...

If you are already using the -f parameter for the %files section where the locales should live, just append the contents of %{name}.lang to the end of the file that you are already using with -f. (Note that only one file may be used with %files -f.)

Why do we need to use %find_lang?

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:
%{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/be/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/cs/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/de/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/es/LC_MESSAGES/%{name}.mo
...
  • 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.

Scriptlets

Great care should be taken when using scriptlets in Mageia packages. If scriptlets are used, those scriptlets must be sane.


Scriptlets requirements Do not use the Requires(pre,post) style notation for scriptlet dependencies, because of two bugs in RPM. Instead, they should be split like this:

Requires(pre): ...
Requires(post): ...

For more information, see www.redhat.com .

Running scriptlets only in certain situations When the rpm command executes the scriptlets in a package it indicates if the action preformed is an install, erase, upgrade or reinstall by passing an integer argument to the script in question according to the following:

macro install erase upgrade reinstall
%pre 1 - 2 2
%post 1 - 2 2
%preun - 0 1 -
%postun - 0 1 -

This means that for example a package that installs an init script with the chkconfig command should uninstall it only on erase and not upgrade with the following snippet:

%preun
if [ $1 -eq 0 ] ; then
/sbin/chkconfig --del %{name}
fi

See also /usr/share/doc/rpm-*/triggers, which gives a more formal, generalized definition about the integer value(s) passed to various scripts.

Scriplets are only allowed to write in certain directories Build scripts of packages (%prep, %build, %install, %check and %clean) may only alter files (create, modify, delete) under %{buildroot}, %{_builddir} and valid temporary locations like /tmp, /var/tmp (or $TMPDIR or %{_tmppath} as set by the rpmbuild process) according to the following matrix

/tmp, /var/tmp, $TMPDIR, %{_tmppath} %{_builddir} %{buildroot}
%prep yes yes no
%build yes yes no
%install yes yes yes
%check yes yes no
%clean yes yes yes

Further clarification: That should hold true irrespective of the builder's uid.

Use of Epochs

The Epoch tag in RPM is to be used only as a last resort and should be avoided whenever possible. However, it is sometimes necessary to use an Epoch to handle upstream versioning changes or to ease the transition from third-party repositories.


Writing a package from scratch

If you want to create a package from scratch, here is a skeleton SPEC where you just need to replace foo with the proper values according to these guidelines

Name:		foo	
Version:	1.0
Release:	%mkrel 1
Summary:	foo
License:	foo
Group:		foo
URL:		foo
Source0:	%name-%version.tar.bz2

%description
foo


%prep
%setup -q

%build
%configure2_5x

%make

%install
%makeinstall

%find_lang %name

%files -n %name

Modifying existing Packages

If you base a new package on an existing non-Mageia package, make sure you verify the correctness of the package and it's spec file to understand exactly what has been done to package the software. Do not submit a package without knowing what those strange, but innocent-looking commands do.

In particular, you should

  • ensure that original tarballs are self-contained pristine tarballs. The tarball should not contain symlinks that reference outside the tarball root directory
  • verify any sources and patches and remove patches or sources that:
    • are related to platforms we do not support (example: sparc, ia64, ppc, ...)
    • Implement features we do not support (example: selinux)
    • Read every patch and understand what it does, if it is needed, put an explanation in the header justifying why the patch is needed.
  • verify that the license stated in the spec file matches the actual license of the software, for this, it is advised to also look/grep in the header files of the source code to verify the license information
  • skim the summary and description for typos and oddities (see Summary and description ),
  • make sure that the correct build root is used,
  • ensure that macro usage is consistent and that the macros are available in Mageia (see Macros )

Keep old changelog entries to credit the original authors. Entries that are several years old or refer to ancient versions of the software may be erased. If you end up doing radical changes and re-write most of the spec file anyway, feel free to start the changelog from scratch. In other words, use your best judgement.

Changelogs

This section describes the Mageia policy for RPM changelogs. (Original changelogs included in the original source are not affected by this policy.)

Please consider that a "normal end user with some technical skills" should be able to read and understand an RPM changelog. Changelog entries have to be in reverse chronological order: newer change log entries are listed above older entries, with the first entry being the most recent.

Please bear in mind that Mageia changelogs will be automatically parsed to prepare distribution release notes and to report on bugs and CVEs and malformed entries may not be read correctly.

General information

  • Changelogs are stored in the SVN commit logs, but should still be considered as part of the final spec when committing to svn (see below)
  • The %changelog section must not be used in the .spec file as the svn commit logs produce the RPM changelog upon build
  • one supplies a commit message when commiting changes, either via svn ci or mgarepo ci via the option -m '- this is my commit message'
  • provide meaningful and detailed commit messages and make them verbose enough that those coming later do not need to look at a diff of changes to see what actually happened.
  • A bad example would be:
 - fixed foo

This tells no one anything and after a year, whoever made the commit likely has no idea what they did in that commit.

  • A good example would be:
 - rediffed description.patch to fix foo
 - added foo-manpages.tar.bz2 to provide such and such for foo
 - dropped cvsfix32.patch; merged upstream

The above is far more telling as to what was actually done. Note that source files must be referred to by their full name (in the above, foo-manpages.tar.bz2, not "S23" or "source23" or something similar). Patches do not need to be referred to by their full names, but can be referred to by the "description" portion of the patch. For instance, the first comment is "rediffed description.patch to fix foo", where description.patch is noted. The patch could in reality be named foo-1.2-mga-description.patch; the prefix (foo-1.2-mga) can be dropped as it should be fairly straightforward to determine what patch has modified/added/removed based on the unique description of the patch. If the patch name is not unique (i.e. there is foo-1.2-mga-description.patch and foo-1.0-cvs-description.patch), then one of the patch names can (and probably should) be changed or the entire patch name should be noted in the changelog. Do not refer to source files or patch numbers numerically (i.e. using S23 or P12) as patches and source files may be renumbered from time to time and a patch number is not guaranteed to remain consistent.

  • when adding multi-line commit messages, every seperate entry must begin with the '-' character. Like
 - Bumped release
 - Added foo.patch

This is optional for single line messages, as in that case it's automatically added if not present To create a multi-line message simply leave the current line unterminated (no final quote mark) and hit ENTER and continue writing. Finally, terminate the last line with a quote mark. Or write the commit messages into a file and use the -F option for svn ci / mgarepo ci.

External References

Each external reference (bug numbers etc) should be of the form:

"(" + external reference code + bug number +")"

Currently defined:

  • Mageia Bugs : mga#
  • Common Vulnerability / Exposure : CVE

Bug Numbers in the change log

During maintenance of a distribution, every change has to be marked with the correct bug number. Normally this has to be a number from https://bugs.mageia.org/. Add an entry with the bugzilla number and a short description of the bug summary. For example:

- Removed invalid desktop Category "Application" (mga#4654).
- Symlink icon to pixmaps dir (mga#2108)
- Added gnome-ui-properties to control-center (mga#1960).

New packages related to new features will refer also to the corresponding bug number in bugzilla, For example:

- Adding Qt Contacts support (mga#8011)

CVE numbers in change log

As with bug numbers: Add a short description (normally the CVE summary should be enough), the Bugzilla and the CVE number to the changelog entry, and also the name and origin of the patch fixing that CVE. Example:

- fix CVE-2012-1234, denial of service through user stupidity (fix-cve-2012-1234.patch, from upstream).

Spec File changes

Be as precise as possible! This is especially important if you remove something from the spec file.

  • Removing original source code must be declared in spec file with a comment ("useful for FreeBSD only" for example) - not necessary to repeat the comment in specfile.
  • Extra commands (for example during %install) can be illustrated with a short comment in spec file
  • Adding/Removing packages from Requires/Provides must be described in the changelog
  • one thing which should not be done without communicating with the maintainer beforehand is reindentation of some parts of the SPEC file. Albeit only small changes in the spec itself (like exchanging a space by one/two tabs between the Tags in the preamble and the values) the diff which is produced by this will be huge.

Source Code changes

Document the most important changes but limit verbosity.

  • look into the source changelog and pick up the most important changes for the distribution (changes for other operating systems are not important). Include what has changed in the new version, usually in the level of detail of a NEWS file; the change log files are usually too long. More than 10-15 lines shouldn't be necessary to describe the most important changes.
  • arrange the original changes behind the version update information. Example:
 - Update to 1.3.2:
   + fixes memory leak in import function
   + new API command: unlock_client()
   + the following bugs are closed by this new upstream release:
   ++ ............ [mga:332]
   ++ ............ [mga:337]
 - split of devel package
  • If upstream does not provide a meaningful change log, then only do the best effort. Don't waste too much time over it.
  • If the upstream tarball really has not changed except for the version number, just the version number in the change log would be fine. Same goes for packages just containing some graphics or theming (unless upstream already provides something that fits). If the upstream changes just consist of "updated translation" or "several bug fixes" even that can be sufficient for a changelog entry (unless these bug fixes contain something you find worth mentioning).

Packaging Static Libraries

Packages including libraries should exclude static libs as far as possible (eg by configuring with --disable-static). Static libraries should only be included in exceptional circumstances. Applications linking against libraries should as far as possible link against shared libraries, not static versions.

.a files and .la files should generally not be included anywhere. They are only useful when one wants to statically link a program against the library (i.e. include the library in the program binary itself, so the library isn't needed at run-time), which is generally not done in Mageia. Libtool archives, foo.la files, should not be included. Packages using libtool will install these by default even if you configure with --disable-static, so they may need to be removed before packaging. Due to bugs in older versions of libtool or bugs in programs that use it, there are times when it is not always possible to remove *.la files without modifying the program. In most cases, it is fairly easy to work with upstream to fix these issues. Note that if you are updating a library in a stable release (not devel) and the package already contains *.la files, removing the *.la files should be treated as an API/ABI change -- i.e. removing them changes the interface that the library gives to the rest of the world and should not be undertaken lightly.


Packaging Static Libraries

  • In general, packagers are strongly encouraged not to ship static libs unless a compelling reason exists.
  • 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-devel 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-devel package. The intent is that whenever possible, packages will move away from using these static libraries, to the shared libraries.
  2. Static libraries only. When a package only provides static libraries you can place all the static library files in the *-devel subpackage.
  • 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.

Statically Linking Executables

  • Static linkage is a special exception and should be decided on a case-by-case basis. The packager must provide rationale for linking statically, including precedences where available, to release engineering for approval.

Obsoleting a package

When a package is no longer needed in the distribution it should be obsoleted and removed from cauldron.

To obsolete and remove a package from cauldron :

  • on svn, move the package to the directory svn+ssh://svn.mageia.org/svn/packages/obsolete/ (see also How to drop a package from SVN )
  • if the package is replaced by the other one which provides the same functionality, add it as obsolete in the new package. Using versioned obsoletes is recommended (Obsoletes: foo < last cauldron version + 1) - This applies to all subpackages which should be obsoleted!
  • if the package is not replaced by an other one and is simply dropped, obsolete it by the task-obsolete package. Don't forget to add a comment with the reason for obsoleting, or a link to the discussion on the mailing list explaining the reasons.). Using versioned obsoletes is recommended (Obsoletes: foo < last cauldron version + 1) - This applies to all subpackages which should be obsoleted!

When a package is obsoleted by another package it will automatically be removed from the cauldron repository.

This was imported from MeeGo wiki licensed under CC-By 3.0
As the wiki doesn't exist anymore, have a look at the archived version: http://wayback.archive.org/web/20130903235324/http://wiki.meego.com/Main_Page

Specific languages

see https://en.opensuse.org/openSUSE:Packaging_nodejs