Personal Spec Formatting Guidelines
I'm pretty anal about consistency within one's code, so I've set a lot of guidelines for myself to make my spec files readable and easily editable. These are the guidelines I strive to adhere to in my own spec files, in addition to [wiki:Self:Packaging/Guidelines the standard guidelines] . They are here for the reference of myself and others only. (Violation of these guidelines is permitted where applicable, but should be heavily discouraged.)
Please note that this document is still a work in progress, and while attempts are made to update it regularly, it is likely still quite incomplete. Thank you. |
Alignment & Whitespace
- All alignment should be done using hard tabs; and NOT individual spaces.
- Unless otherwise discussed, all lines should begin on the first column and be left-aligned to it.
- For any binary operator in the spec file, such as comparisons, a single space surrounds the operator on both sides and is placed between it and its respective operands.
- Unless otherwise discussed, all lines should not exceed 79 characters in length.
- All RPM sections, starting from
%description
, should be separated by two empty lines.
Comments
- Comments used simply to ignore one or more lines of a spec file should begin with a single hash mark followed by a single space ("# ").
- Comments used to explain why a piece of the spec file is written in a specific way or why a piece of the spec file is commented-out should begin with two hash marks and a single space ("## ").
- All comments must immediately precede the code or segment of the spec file being explained, left-aligned to the same level of indentation.
Example:
## This is a snapshot of code dated YYYY-MM-DD, so the URL is not valid for the ## time being. #Source0: http://example.com/download/%{name}-%{version}.tar.bz2 Source0: %{name}-%{version}.cvsYYYYMMDD.tar.bz2
Intial Tags
- Any used macros/tags outside of what is used normally to define sections should be enclosed in braces:
%{name}
,%{version}
,%{?foo_variable}
. - All initial tags should be vertically aligned per "section," which is a single block of lines together ending in an empty new line.
- Any per-package definition macros (
%define
) should be at the very top of the spec file. The left-most column of the identifiers should all be vertically aligned, and the left most column of the values should all be vertically aligned as well. - The following tags should be in their own sections, which are visual blocks separated by exactly one empty line. Each section should be left-aligned by hard tabs:
Name
,Version
,Release
,Summary
These constitute a brief overview of what the package is and its version in regards to both upstream and downstream packaging.
Group
,License
, andURL
These give us more information about the category of the package and where to find more information from the website of upstream or other relevant and appropriate URL.
Source
N,Patch
N,BuildRoot
, andBuildArch
,ExcludeArch
,ExclusiveArch
, et al.
These tags store the information describing the initial setup of the build environment.
Dependencies
Dependencies, both build- and run-time, can cause much havoc to one's spec files if he or she is not careful.
- All dependencies should be listed one per line, with the package names aligned at the left-most column after being tabbed from the tag.
- The following should be grouped into their own "sections," as explained above:
BuildRequires
(build-time dependencies)Requires
(run-time dependencies)Requires(pre)
(%pre
scriplet dependencies)Requires(preun)
(%preun
scriplet dependencies)Requires(post)
(%post
scriplet dependencies)Requires(postun)
(%postun
scriplet dependencies)
Sources
- All
Source
N tags should contain a value which is a fully qualified URL. - The URL in the Source tag should use
%{name}
and%{version}
macros where applicable.
Patching
- All patch files should be named in a descriptive manner, with words separated by hyphens and prefixed with the name of the package.
- All patches should be unified diff format (e.g.,
diff -u
). - If a patch is for a single file in the source, the base filename thereof should be the second field of the patch filename.
- Patch numbers should be sequential, starting from
Patch0
and increasing as needed (e.g.,Patch1
,Patch2
, ...,Patch25
, et al.). - For security fixes, the patch file name should contain a CVE identifier, Secunia Advisory number, or functionally equivalent other form of identifying the specific security issue which the patch fixes, works around, or otherwise resolves.
Example:
## [...] Patch42: %{name}-configure.ac-fix-dependency-check.patch Patch43: %{name}-fix-CVE-2007-0123.patch ## [...]
.
RPM Conditionals
Similar to a programming language, RPM's spec file format allows conditional blocks of code to be used dependent on
various properties such as architecture (%ifarch
/ %ifnarch
), operating system (%ifos
/ %ifnos
), or any other conditional expression.
- All conditional blocks must be indented one tab level from their parent, with the
%if
,%endif
, and any%elseif
or%else
macros (if it is present) left-aligned to the same column. - For nested conditionals, this must occur for the nesting as well.
Example:
%build %ifarch x86_64 sparc64 ppc64 make -D__64BIT__ %{?_smp_mflags} %else %ifarch ppc make -D __PPC32__ %{?_smp_mflags} %else make %{?_smp_mflags} %endif %endif
Dates & Times
- Where used, all dates and times (except for
%changelog
entries: see below) should follow the ISO-8601 standard, or a more applicable variation thereof. (For example, one should use YYYY-MM-DD format when referring to a date, but a source code snapshot would have YYYYMMDD in its filename.)
RPM ChangeLog Entries
Spec files contain a %changelog
section, wherein notes are made about changes to each new EVR
- Each entry should begin with a line left-aligned to the first column as follows: an asterisk followed by a single space, then the date (in "Day Mon DD YYYY" format), followed by a space and the full name or alias of the person making the change, followed by a space and that person's email address in angled brackets, followed by a space, a hyphen, and another space, and finally the EVR (in "
Version
-Release
" format, prepending an "Epoch:
if needed). (Note: One should not append or hardcode a'%{?dist}
tag to the EVR in the %changelog.) - If the day is a single-digit number (such as December 9 or August 5), then it must be appended to a leading zero so that it is two digits in the
%changelog
entry. - Each entry should then contain notes, separated into consecutive lines as needed, prefixed with a hyphen, stating what was changed. If more than one line is needed, the note should be separated between words and the next line of the note should start indented at the third column (indented by two spaces with no prepending hyphen).
- The first note in each entry should mention any version update if there was one in this new EVR.
- If there is an ABI/API update in this release which would make it incompatible with the most previous EVR, that should also be noted.
- All patches should be referenced discarding their "
%{name}
" prefix, and any additions or removals thereof should be noted on successive lines, beginning indented two spaces (as with all multi-line notes), with a plus sign ("+") or minus sign ("-") noting the two, respectively. - For any notes about bug fixes and such, a bug ID # (from an appropriate upstream tracker or Fedora's Bugzilla or equivalent method of tracking the bug report should be included in the entry, with the full name or alias of the reporter as shown.
Example (from the scribes package):
* Mon Dec 18 2006 Peter Gordon <peter@thecodergeek.com> - 0.3-3.20061218bzr - Update to 2006-12-18 BZR snapshot. This should fix the longstanding bug wherein a zombie .scribesclient process is left which becomes incredibly processor-intensive, since the internal IPC has been reworked; also includes various updated translations. - Add CONTRIBUTORS, TRANSLATORS, and TODO files as %%doc - Add patch to install plugins to proper $(DESTDIR) location: + fix-plugins-installation-dir.patch
RPM Subpackages
RPM spec files have a capability to produce multiple packages from a singe-sources build, known as subpackages.
- If the main package contains a COPYING, LICENSE, or other file which holds copyright license information, it should be included as part of the installed documentation (
%doc
) for every subpackage (except for-debuginfo
subpackages, which are automatically generated). This is to keep the licensing explicitly clear and avoid any potential referencing issues thereof.
TODO
- I need to add a LOT more to this, including (though not limited to) subpackage blocks.
License
This document was written by Peter Gordon <[[MailTo(peter@thecodergeek.com)] >, and is placed into the Public Domain.
Footnotes
1. Source
N is used to refer to numbered Source tags in a spec file, such as Source0
, Source1
, et al.; and likewise for the Patch
N tags.
2. "EVR" refers to the combination of the Epoch
, Version
and Release
of a package.