Annvix:Documentation/Dev/Building/Specs
|
This page contains content from the old Annvix.org wiki and has been moved here to preserve content. These pages have been retained for historical and nostalgic purposes only. |
Developer's Reference: Building Annvix: Spec Files
Annvix uses the RPM package format for packages, however everyone seems to have their own style as to the formatting of the .spec files and it can make it confusing for other developers or maintainers to work on these packages.
As a result, we encourage packagers to use the following .spec template when writing or modifying .spec files to make it simple for others to take over or do work on the packages. If everyone follows the same format, there are never any surprises.
The following is the beginning of an rpm .spec template:
#
# spec file for package package_name
#
# Package for the Annvix Linux distribution: http://annvix.org/
#
# Please submit bugfixes or comments via http://bugs.annvix.org/
#
# $Id: package_name.spec 6081 2006-08-15 19:01:56Z vdanen $
%define revision $Rev: 6081 $
%define name package_name
%define version 1.0
%define release %_revrel
[other %defines]
Summary: Package summary
Name: %{name}
Version: %{version}
Release: %{release}
[Epoch: 1]
License: License
Group: System/Group
URL: http://www.annvix.org/
Source0: package_source.tar.bz2
Patch0: package_patch.bz2
BuildRoot %{_buildroot}/%{name}-%{version}
BuildRequires: other-package
BuildArch: noarch
Requires: other-package
PrePreq: other-package
Provides: other-package
Conflicts: other-package
Obsoletes: other-package
%description
...
The above shows the header of a spec file. Values should be indented with tabs and fields should be placed in the order indicated to make all .spec files very similar so as to allow for quick and easy modification. At the top of each spec file should be a comment indicating what the spec file is for and who created it (i.e. packages in ports can have the name of the maintainer, etc.).
All user-definable macros (such as %_bindir or %_tmppath, etc.) should be enclosed in curly brackets (i.e. %_libdir would be %{_libdir}) as this makes for easier reading and provides a standard format. Macros such as %_install_info should remain without curly brackets to indicate it is a "system" macro that does something. The main difference is that a macro like %{_libdir} provides a value (in this case, /usr/lib) where as a macro like %_install_info actually executes some shell code.
As of Annvix 1.1-CURRENT, the BuildRoot should use %{_buildroot} rather than %{_tmppath}. By default, %{_buildroot} is set to /override, like Openwall. This makes it easier to figure out where builds go (are they in /var/tmp or /tmp or ~/tmp or even ~/RPM/tmp?). The BuildRoot should also only contain the package name and version, so building glibc would result in the BuildRoot being /override/glibc-2.3.5/.
Definitions such as $RPM_OPT_FLAGS or $RPM_BUILD_ROOT are no longer to be used. Instead, use %{optflags} or %{buildroot}. Keep "$*" variables strictly limited to shell constructs and not RPM-based definitions.
Another thing to keep in mind is changelog messages. Changelog messages can be as verbose as required to clearly indicate what changes were made. If changes are made that include the addition or removal of a patch or source file, it should be clearly indicated. For example:
* Fri Dec 05 2003 Vincent Danen <vdanen-at-build.annvix.org> 1.0 - P28: turns off some really insecure thing - removed P12: merged upstream - S3: new source file
With a changelog that refers to (in the case of the above) Patch28, Patch12, and Source3 (respectively) anyone looking at the spec can clearly determine exactly what changes were done without having to go look in subversion.
Also note that, unlike Mandriva, we do not append the release tag to the changelog entry but just the version (ie. "1.0" rather than "1.0-1avx").
We also obfuscate email addresses in the above fashion: <user-at-host> instead of <user@host>.
Finally, it is required that anyone using tabs inside of a spec file set their tabstop to a width of 8. Ideally, spaces should be used instead. This is easy to accomplish if using vim for editing by appending:
# vim: expandtab:shiftwidth=8:tabstop=8:softtabstop=8
as the last line of the spec file. For other editors, please ensure that the default tab width is 8 when using tabs in a spec file.
Contents |
Annvix-specific RPM Macros
Annvix adds a few new macros and changes some others. Developers need to note these changes when working on their spec files. The following is a list of the new and/or changed macros from a standard Mandrakelinux 9.2 installation:
- %{_srvdir}: expands to /var/service.
- %{_srvlogdir}: expands to /var/log/supervise.
- %{_ext}: expands to avx (currently unused).
- %{_buildroot}: expands to /override.
- %_post_srv: replaces %_post_service for supervise-controlled services ($1 is the name of the service).
- %_preun_srv: replaces %_preun_service for supervise-controlled services ($1 is the name of the service).
- %_pre_useradd: adds another field ($4) to the macro to set the static uid/gid.
- %_mkafterboot: merges the afterboot manpage from parts (used in %post and %postun in a .spec that includes an afterboot snippet).
- %_revrel: this is a macro that changes the release tag to a number that is equivalent to the current subversion revision and the string "avx". This is highly dependant upon %revision being defined as containing the value of subversion's "$Rev$" keyword.
- %kill_lang: is a macro that removes all non-english language files. Annvix is english-only and as a result removes all of those files (due to the nature of translations, it seems ridiculous to have 10% of the programs on the distribution translated in 5% of the languages so we've opted to just get rid of it all). The %kill_lang macro should be used prior to the %find_lang macro.
- %_mkdepends: a macro to create service dependencies from one service to another. For instance, using "%_mkdepends amd portmap" will create a service dependency on "portmap" for the "amd" service
Some examples:
mkdir -p %{buildroot}%{_srvdir}/exim
install %{SOURCE12} %{buildroot}%{_srvdir}/exim/run
This creates the /var/service/exim service directory and installs SOURCE12 (the exim run script) into the directory.
%dir %attr(0750,nobody,nogroup) %{_srvlogdir}/exim
This sets permissions on the /var/log/supervise/exim directory, which is the log directory for the exim service.
%post %_post_srv rpc.mountd %_post_srv rpc.nfsd
This calls the %_post_srv macro on two services: rpc.mountd and rpc.nfsd in the nfs-utils %post scriptlet. Both are required as the nfs initscript started both services, whereas under supervise we control them individually.
%preun %_preun_srv rpc.mountd %_preun_srv rpc.nfsd
Similar to the above, this replaces "%_preun_service nfs" in the nfs-utils %preun scriptlet.
%pre clients %_pre_useradd rpcuser /var/lib/nfs /bin/false 73
This creates the rpcuser user with a home directory of /var/lib/nfs and a shell of /bin/false. This is identical to the traditional call of %_pre_useradd in Mandriva Linux except we add a static uid/gid pair to the call; in this case rpcuser will always have a uid/gid of 73.
%kill_lang %{name}
%find_lang %{name}
This performs the %kill_lang action (removing all non-english locale, translated man page, etc.) files and then generates the %{name}.lang files. This allows us to easily remove just the %kill_lang macro later if Annvix does decide to again support multiple languages.
Documentation packages
Annvix breaks out documentation (what normally would be used in %doc in a package) into it's own package. This allows us to provide only manpages and info pages, without a huge number of files in /usr/share/doc/ that may rarely be looked at. If a user wants the extra documentation for Apache, for example, they would install httpd-doc. Documentation packages also have their own repository, so users must add this repository prior to installing these packages.
To support this, all packages that contain documentation files (those files used in the %doc section) must now contain:
%package doc
Summary: Documentation for %{name}
Group: Documentation
%description doc
This package contains the documentation for %{name}.
as well as (for example):
%files doc %defattr(-,root,root) %doc doc/COPYING doc/CHANGES.gz README
No documentation files are permitted, using %doc, outside of the "doc" sub-package.
Development Packages
Traditionally, Annvix followed the Mandriva naming scheme of libfoo1-devel and lib64foo1-devel for development packages. Unfortunately, there is little consistency here (and as of June 2007 a discussion has ensued regarding correcting this scheme to ease the upgrade of development packages). As of 2.1-CURRENT a new policy is in effect regarding development packages:
- Packages will be named libfoo-devel rather than libfoo1-devel; there is no need to the library major to be in the package name (eases upgrades in the case of soname changes such that libfoo1-devel is not upgraded by libfoo2-devel unless libfoo2-devel obsoletes libfoo1-devel which adds unnecessary complexity since there should at any given time typically be one version of libfoo available at a time)
- In the event that there needs to be more than one version of development files at a time, the old version will be renamed to libfoo1-devel, while the new version will retain libfoo-devel which means the new version will be the default (and upgradeable)
- More than likely these two files (libfoo1-devel and libfoo-devel) will have conflicting files, so a Conflicts should be used
- Instead of naming a package "%{libname}-devel", it should be named %{devname} and a new define should be in place: "%define devname %mklibname %name -d"
- Static development files can use "%define staticdevname %mklibname %name -d -s"
- All development files must also provide "%name-devel"
- All packages requiring development files must require %name-devel instead of libfoo-devel as this eases cross-platform building (on x86 it will be libfoo-devel whereas on x86_64 it will be lib64foo-devel); a work-around for this was to have packages provide "lib%name-devel" but this hardly seems consistent
- Unfortunately, to ease the upgrade from earlier releases, an Obsoletes must be provided for the package, which should take the form of "Obsoletes: %{mklibname %name 0 -d}" where 0 is the current major at the time of implementing the policy (i.e. this does not need to be upgraded for new majors in the future, just once to handle upgrades from earlier Annvix versions). Likewise, the same must be done for static-devel packages.
For instance:
...
%define libname %mklibname %{name} 0
%define devname %mklibname %{name} -d
...
%package -n %{devname}
Summary: Development headers and libraries for %{name}
Group: Development/Other
Requires: %{libname} = %{version}
Provides: %{name}-devel = %{version}-%{release}
Obsoletes: %{mklibname %{name} 0 -d}
Library Packages
Library packages are packages named libfoo1 or lib64foo1 that contain library files. Library files must be versioned with the library's major (i.e. 1), unlike the library development files which must not contain the library's major (unless more than one version of the library is available, for which the default library's development package must not contain the major).
Library packages should also provide a non-versioned name, such that:
- libfoo1 provides libfoo
- lib64foo1 provides libfoo
In other words, every library must provide "lib%{name}". In this way, calling apt to install "libfoo", or putting a requires on "libfoo" will always pull the latest version of the library. As with development packages, if more than one library is provided, then the latest must provide "libfoo" where the older versions would provide "libfoo0", etc.
Resources
- Fedora's RPM Guide - this is a killer anything-having-to-do-with-rpm resource