(Clarify X.Y.Z-R.B version number) |
(→External References) |
||
| Line 528: | Line 528: | ||
Currently defined: | Currently defined: | ||
* MeeGo Bugs : BMC# | * MeeGo Bugs : BMC# | ||
| + | * MeeGo Features: FEA# | ||
* Common Vulnerability / Exposure : CVE | * Common Vulnerability / Exposure : CVE | ||
| Line 536: | Line 537: | ||
- Symlink icon to pixmaps dir (BMC#2108) | - Symlink icon to pixmaps dir (BMC#2108) | ||
- Added gnome-ui-properties to control-center (BMC#1960). | - Added gnome-ui-properties to control-center (BMC#1960). | ||
| + | |||
| + | New packages related to new features will refer to the corresponding bug number in bugzilla, preceded with an FEA. For example: | ||
| + | - Adding Qt Contacts support FEA#8011 | ||
==== CVE numbers in change log ==== | ==== CVE numbers in change log ==== | ||
Guidelines below were adapted for MeeGo from Moblin, OpenSUSE, Fedora and other distributions.
Package Versions look like : X.Y.Z-R.B
The Version field in the spec file is where you should put the current version of the software being packaged. There are four cases where the version contains non-numeric characters:
We can use letters and tilde into the version tag. We do not use the Release field for this.
Example:
Let's assume the following Qt versions: Qt 4.7.0~beta1 Qt 4.7.0~beta1+git1 Qt 4.7.0~beta2 Qt 4.7.0 Version comparison results: $ rpmdev-vercmp 4.7.0~beta1 4.7.0~beta1+git1 0:4.7.0~beta1+git1-None is newer $ rpmdev-vercmp 4.7.0~beta1+git2 4.7.0~beta2 0:4.7.0~beta2-None is newer $ rpmdev-vercmp 4.7.0~beta2 4.7.0 0:4.7.0-None is newer Conclusion: 4.7.0~beta1 < 4.7.0~beta1+git1 < 4.7.0~beta2 < 4.7.0
Note that the ~ comparison order is specific to MeeGo rpm (http://rpm.org/ticket/56).
This field is handled by the build system to be able to manage automated builds. The initial setting in the spec file is used by the build system but in many cases it does not need to be changed.
There is no need for the %{dist} macro in the release field. This is also handled directly by the build system.
The release number is set to zero with any version update. It is increased by one with any change in the package.
We can put letters into the version tag, so we do not use the Release field for this. Details can be found above.
If you build the package outside of the OBS or if you copy a package then you will of course not get the correct Release or Build values.
%packager in your ~/.rpmmacros instead.
Req tag should be replaced by plain Requires. For more info, see Maximum RPM snapshot's fine grained dependencies chapter .
The summary is a single line string describing the package. The maximum length is 80 characters. 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 RPM spec file contains only the English version to keep the RPM database small.
Valid RPM Groups are:
Amusements/Games Amusements/Graphics Applications/Archiving Applications/Communications Applications/Databases Applications/Editors Applications/Emulators Applications/Engineering Applications/File Applications/Internet Applications/Multimedia Applications/Productivity Applications/Publishing Applications/System Applications/Text Development/Debuggers Development/Languages Development/Libraries Development/System Development/Tools Documentation System/Boot System/Console System/I18n/Chinese System/I18n/Japanese System/I18n/Korean System/Packages System/Base System/Daemons System/Kernel System/Libraries System/Shells System/X11 System/X11/Fonts System/X11/Icons System/GUI/XFCE System/GUI/Other System/GUI/GNOME
The BuildRoot value MUST be below %{_tmppath}/ and MUST contain at least %{name}, %{version} and %{release}.
The recommended values for the BuildRoot tag are (in descending order of preference) :
%{_tmppath}/%{name}-%{version}-%{release}-root
The BuildRoot tag can be omitted in packages targeting MeeGo only and is handled directly by rpm in MeeGo, for packages that need to run on other distros with older rpm it should be added for backward compatibility.
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.
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. 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 at installing RPM packages manually, however, history has shown that such dependencies add confusion when library/files are moved from one package to another, when packages get renamed, when one out of multiple alternative packages would suffice, and when versioned explicit dependencies become out-of-date and inaccurate. Additionally, in some cases, old explicit dependencies on package names require unnecessary updates/rebuilds.
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
Packagers should revisit an explicit dependency as appropriate to avoid it becoming inaccurate and superfluous.
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 with 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.
Before adding BuildRequires to any package, please be comfortable with Requires .
Each problem should be solved in a separate patch. To allow easy maintenance of patches, every patch should have a header providing the following information:
The name of a patch file consists of:
.patch
Patches are 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 an another primary source site. The original name, suffix, and format is preserved in this case.
Each patch should be compressed with bzip2 if its size is greater than 100kB. The macros %name and %version should be used whenever possible.
Example:
Source: %{name}-%{version}.tar.bz2
Patch0: %{name}-%{version}-autoconf.patch
Patch1: %{name}-%{version}-gcc31.patch
For the patches to be applied, the patches should be mentioned under %setup. For the above example, this could be done as
%setup -q %patch0 -p1 %patch1 -p1
Patches have to be marked as such in the spec file and should be applied using the internal patch routines available in rpm. Use of alternate patch management system not supported by rpm is not allowed.
The %clean section is not required for MeeGo 1.1 and above. Each package for MeeGo 1.0 MUST have a %clean section, which contains rm -rf %{buildroot} (or $RPM_BUILD_ROOT).
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 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, 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.
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:
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.
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.
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.
Whenever possible (and feasible), MeeGo Packages containing libraries should build them as shared libraries. In addition, every binary RPM package which contains shared library files (not just symlinks) in any of the dynamic linker's default paths, must call ldconfig in %post and %postun. If the package has multiple subpackages with libraries, each subpackage should also have a %post/%postun section that calls /sbin/ldconfig. An example of the correct syntax for this is:
%post -p /sbin/ldconfig %postun -p /sbin/ldconfig
Note that this specific syntax only works if /sbin/ldconfig is the only call in %post and %postun. If you have additional commands to run during the scriptlet, call /sbin/ldconfig at the beginning of the scriptlet, like this:
%post /sbin/ldconfig /usr/bin/foo --add %postun /sbin/ldconfig /usr/bin/foo --remove
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 MeeGo.
Currently, only SystemV-style initscripts are supported in MeeGo.
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.
The icon tag can be specified in two ways:
Icon=/usr/share/pixmaps/comical.png
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.
If the package doesn't already include and install its own .desktop file, you need to make your own. You can do this by including a .desktop file you create as a Source: (such as Source3: %{name}.desktop) or generating it in the spec file. Here are the contents of a sample .desktop file (comical.desktop):
[Desktop Entry] Name=Comical GenericName=Comic Archive Reader Comment=Open .cbr & .cbz files Exec=comical Icon=comical Terminal=false Type=Application Categories=Graphics;
It is not simply enough to just include the .desktop file in the package, one MUST run desktop-file-install OR desktop-file-validate in %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:
desktop-file-install \
--dir=${RPM_BUILD_ROOT}%{_datadir}/applications \
%{SOURCE3}
desktop-file-install \
--add-category="AudioVideo" \
--delete-original \
--dir=%{buildroot}%{_datadir}/applications \
%{buildroot}/%{_datadir}/foo.desktop
desktop-file-validate %{buildroot}/%{_datadir}/applications/foo.desktop
There are two styles of defining the rpm Build Root and Optimization Flags in a spec file:
| macro style | variable style | |
| Build Root | %{buildroot} | $RPM_BUILD_ROOT |
| Opt. Flags | %{optflags} | $RPM_OPT_FLAGS |
There is very little value in choosing one style over the other, since they will resolve to the same values in all scenarios. You should pick a style and use it consistently throughout your packaging.
Mixing the two styles, while valid, is bad from a QA and usability point of view, and should not be done in MeeGo packages.
If the package includes translations, add
BuildRequires: gettext
If you don't, your package could fail to generate translation files in the buildroot.
MeeGo 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
%defattr(-,root,root,-)
%{_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.)
Here is an example of proper usage of %find_lang, in foo.spec:
...
%prep
%setup -q
%build
%configure --with-cheese
make %{?_smp_mflags}
%install
make DESTDIR=%{buildroot} install
%find_lang %{name}
%clean
rm -rf %{buildroot}
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc LICENSE README
%{_bindir}/foobar
Using %find_lang helps keep the spec file simple, and helps avoid several other packaging mistakes.
%{_datadir}/* to grab all the locale files in one line also grab ownership of the locale directories, which is not permitted.
%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
...
%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.
Great care should be taken when using scriptlets in MeeGo packages. If scriptlets are used, those scriptlets must be sane.
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 .
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:
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.
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.
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 transition from third party repositories.
See Spectacle
Spectacle is a great tool for straightforward packages, and we have many of those, hundreds, many of those packages already have been using spectacle happily for a while now. Generally, the 80/20 rule applies here, almost 80% of packages in MeeGo can be converted to this format, probably around 20% will need to stay as is for various reasons.
Spectacle in general helps a lot when you have a package that does:
and especially useful when for example you have to manage many build dependencies and patches or for common packaging of perl/python/X packages that usually follows the same packaging work flow. We have plans to add lots of nice features to make packaging easier and more fun with spectacle.
While spectacle has many advanced options to cover all kind of corner cases, it should not be used for complex packages that would require lots of customization, especially now that we support multiple architectures and where we need to apply code and custom scripts to support different scenarios.
Spectacle provides scripts to convert spec files to spectacle, those try to do their best but you SHOULD never just take the output as is and rely on the script, a review of the output is necessary, otherwise you might end up with lots of duplication in the spec file. This is the most common mistake, developers are relying on the output of the conversion script, basically picking some spec file from another distro and converting it. This can lead to major disasters in some cases.
So to summarize:
If you base a new package on an existing non-MeeGo package, make sure you verify its correctness of the package and the spec file and to understand exactly what has been done to package the software exactly. Do not submit a package without knowing what those strange, but innocent-looking commands do.
In particular, you should
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.
This section describes the MeeGo 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 theat MeeGo 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.
* dow mmm dd yyyy Name Goes Here <your@email.com> - [version] - comment - comment
Note the following exceptions are noted through observation:
This wide variation in formats makes automation tasks harder than they should be. Please use the correct format.
Each external reference (bug numbers etc) should be of the form:
"(" + external reference code + bug number +")"
Currently defined:
During maintenance of a distribution, every change has to be marked with the correct bug number. Normally this has to be an number from https://bugzilla.meego.com/. Add an entry with bugzilla number and a short description of the bug-summary. For example:
- Removed invalid desktop Category "Application" (BMC#4654). - Symlink icon to pixmaps dir (BMC#2108) - Added gnome-ui-properties to control-center (BMC#1960).
New packages related to new features will refer to the corresponding bug number in bugzilla, preceded with an FEA. For example:
- Adding Qt Contacts support FEA#8011
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. Examples:
- Add gdk-pixbuf-226710.patch (BMC#226710), and (CVE-2007-0010). - More XPM fixes: (CVE-2005-2975) xpm too many colors DoS (BMC#129642) - fix ~/.dmrc symlink attack (BMC#180704), (CVE-2006-2449)
Be as precise as possible! This is especially important if you remove something from the spec file.
Document the most important changes but limit verbosity.
- 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: ++ ............ [MGN:332] ++ .............[MGN:337] - split of devel package
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.
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.
BuildRequire the *-static package. The intent is that whenever possible, packages will move away from using these static libraries, to the shared libraries.
%package devel
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.
BuildRequire the *-static package.