From Mageia wiki
Jump to: navigation, search


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


Spec header

The rpm .spec header contains the important version, source, patch, requires, and buildrequires information for the particular package(s) to be built.

Macros definition

The first part of the spec should contain macros definitions, as illustrated below:

 %define major       0
 %define libname     %mklibname aide %{major}

All %define statements should be made here, with comments as appropriate. They should be tabbed so as to align properly, as noted above (use two tab widths after the name definition, or column 25 (third tab stop), as this allows for longer definition names).

Note: defining explicit macros for name, version and release is useless, as those are implicitly defined from corresponding tags.

Name, Version and Release

The first section should contains standard name, version and release tags:

 Name:    aide  
 Version: 0.13.1
 Release: %mkrel 1

Name should be the upstream name of the software project, always lowercase.

Summary, Name, Sources and Patches

The next section of the header would look as follows:

 Summary:        Advanced Intrusion Detection Environment  
 License:        GPLv2+
 Group:          Monitoring
 URL:            http://sourceforge.net/projects/aide
 Source0:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz
 Source1:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz.asc
 Source2:        aide.conf
 Source3:        aidecheck
 Source4:        aideupdate
 Source5:        aideinit
 Source6:        aideinit.8
 Patch0:         some.patch

As can be seen, everything in is a very linear order:

  1. Summary tag -- a brief one-line description of the package, max. 79 characters, no dot at the end, first character uppercase and no space
  2. License tag -- refer to the Licensing Policy : [1]
  3. Group tag -- the Mageia group this package belongs to
  4. URL -- the home page of the software package
  5. Source0... -- the source files
  6. Patch0... -- the patch files

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. Likewise for the Patch0 keyword; always begin with Patch0:, and never just Patch:. If a source file has a downloadable URL that it came from, it must be included.

NB : If the source file is badly named, it can be renamed adding #/%{name}-%{version}.tar.xz to the SOURCE url.

Tab stops here are one shorter than the defines, largely because defines can, and often are, longer but Source, Name, etc. tags tend not to. Instead of progressing to column 25, use column 17, or the second tab stop. It is important that everything is left-aligned for the "second column" or keyword values as it maximizes readability.

Patch Naming

There is a standard way of naming patch files. It is documented in the packaging guidelines.

Build Root, Requires, etc.

The next part of the RPM spec is the build requirements and this is perhaps one of the messiest and potentially inconsistent part of any spec. 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.

Buildroot can safely be omitted, as it’s automatically deduced by rpm when building. For historical reasons, it’s still present in Mandriva specs (releases prior to 2008.0) but is not necessary in Mageia This should remain consistent across specs. For instance:

 BuildRequires:  flex
 BuildRequires:  glibc-devel
 BuildRequires:  glibc-static-devel
 BuildRequires:  mhash-devel
 BuildRequires:  zlib-devel
 BuildRequires:  bison

Requires, Obsoletes, Provides, Conflicts, etc.

The last set of tags in the RPM header are for Requires, Obsoletes, Provides, Conflicts, etc. and they should be defined one per line as with BuildRequires.

 Requires:       gnupg
 Requires(pre):  foo
 Requires(postun): foo
 Conflicts:      tripwire
 Provides:       AIDE+gpg
 Obsoletes:      bar

Again, keep the tab stops in mind. When using "Requires(postun)" you will progress beyond the tab stop at column 17; in these instances use a single space. Also note the ordering. Instead of mixing Requires and Provides, keep them in a distinct order:

  1. Requires, Requires(pre), Requires(post), etc. -- all requires should come first, one per line
  2. Conflicts -- all conflicts come second
  3. Provides and Obsoletes -- all provides and obsoletes come third, and may be intermixed as they tend to be closely related

Description

The %description comes last, and provides the description of the package. Lines should be wrapped at 76 characters.

A final RPM spec header would look like:

Name:           aide
Version:        0.13.1
Release:        %mkrel 1
 
%define major       0
%define libname     %mklibname aide %{major}
%define somereallylongname foo
 
Summary:        Advanced Intrusion Detection Environment
License:        GPLv2+
Group:          Monitoring
URL:            http://sourceforge.net/projects/aide
Source0:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz
Source1:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz.asc
Source2:        aide.conf
Source3:        aidecheck
Source4:        aideupdate
Source5:        aideinit
Source6:        aideinit.8
Patch0:         some.patch
 
Buildrequires:  flex
BuildRequires:  glibc-devel
BuildRequires:  glibc-static-devel
BuildRequires:  mhash-devel
BuildRequires:  zlib-devel
BuildRequires:  bison
 
Requires:       gnupg
Requires(pre):  foo
Requires(postun): foo
Conflicts:      tripwire
Provides:       AIDE+gpg
Obsoletes:      bar
 
%description
AIDE (Advanced Intrusion Detection Environment) is a free alternative to
Tripwire. It does the same things as the semi-free Tripwire and more.  It
is a file system integrity monitoring tool.

For packages that create multiple sub-packages, follow the guidelines above for each one.

 %prep

The %prep section follows all package definitions. There should be at least two blank lines to separate the end of the last %description from %prep. A simple %prep section would look like:

 %prep
 %setup -q

Other Conventions

Here is a list of other conventions that must be observed in Mageia spec files:

System Macros vs. User-Definable Macros

System macros are those defined in /etc/rpm/macros.d/ files and include ie. %_install_info, among others. A system macro is something that does something or calculates something. It is not a simple definition, like %{_tmppath} which merely translates to a path. System macros must be written without curly braces; i.e. as %_install_info and not %{_install_info}. User-definable macros, which include %{_tmppath} or %{_bindir} must be written with curly braces; i.e. as %{_tmppath} and not %_tmppath. This makes reading the spec easier as everyone will be using a similar "curly braces" convention. If you're unsure of which to use, keep in mind that a macro like %{_libdir} provides a value (in this case, /usr/lib), whereas a macro like %_install_info actually executes code of some sort.

  • Use %{_libdir}, not %_libdir
  • Use %_install_info, not %{_install_info}

Consistently use this mechanism and all spec files will be much easier to read

Standard macros

Keeping constistent macros names across spec files enhance readability.

  •  %{upstream_name} when upstream name differs from the package one
  •  %{upstream_version} when upstream version differs from the package one

Variables

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.

Changelogs

Please have a look at our Packaging Guidelines changelog section

Source handling

Source files have typically be handled by using %{SOURCExx} macros, but this is inefficient for a few simple reasons:

  • no need to jump up and down in the spec to figure out what %{SOURCE12} is
  • source files can be easily renumbered without making multiple changes

Instead, using %{_sourcedir}/foo in the spec is preferred as it makes things easier to read and easier to work with. For instance, compare:

 Source12:   something.pam
 ...
 install -m 0644 %{SOURCE12} %{buildroot}%{_sysconfdir}/pam.d/

to:

 Source12:   something.pam
 ...
 install -m 0644 %{_sourcedir}/something.pam %{buildroot}%{_sysconfdir}/pam.d/

Source files must not contain the macros %{version} or %{name} unless they are the original upstream source files.

Patch files must not contain the macros %{version} or %{name} ever.

Resources

  • Fedora's guidelines:
    • How to create a GNU Hello RPM package;
    • How to create an RPM package;
  • Packaging guidelines.
    • Mageia RPM HOWTO - the Mageia RPM HOWTO (contains good information and should be seen as supplemental to this policy)

Possible Changes/Suggestions Based on Proposal

This section details some technical changes that are not part of the proposal but may need to be implemented to make the proposal most effective:

Obsolete Stuff, should discard where seen

The mgagnome has a clean-spec subcommand to facilitate below.

  • %clean section, is now done automagically by RPM itself
  • rm -rf %{buildroot} is no longer needed explicitly in %install as it is done there automatically
  • BuildRoot: definition
  • %defattr(-,root,root) is useless, should be removed. Only use %defattr if you want really want to change the default upstream permissions. From of all files following after the %defattr macro. This is rarely needed
  • change %py_requires into BuildRequires: python
  • change %py_requires -d into BuildRequires: python and BuildRequires: python-devel
  • remove variables such as name, version, release if not defined conditionally. For Example:
# Example of spec file with unneeded variables for name/version/release
%define name modulename
%define version 1.2.3
%define release %mkrel 1

Name: %name
Version: %version
Release: %release
# Do the following instead:
Name: modulename
Version: 1.2.3
Release: %mkrel 1

See Also