User Tools

Site Tools


rpm

RPM

* Python packages to rpm

Package management system few tips / trick to build / modify / work with packages.
Many hints information taken from original site RPM

RPM Common Command

Syntax Description
rpm -ivh {rpm-file} Install the package
rpm -Uvh {rpm-file} Upgrade package
rpm -ev {package} Erase/remove/ an installed package
rpm -ev –nodeps {package} Erase/remove/ an installed package without checking for dependencies
rpm -qa Display list all installed packages
rpm -qi {package} Display installed information along with package version and short description
rpm -qf {/path/to/file} Find out what package a file belongs to i.e. find what package owns the file
rpm -qc {pacakge-name} Display list of configuration file(s) for a package
rpm -qcf {/path/to/file} Display list of configuration files for a command
rpm -qa –last Display list of all recently installed RPMs
rpm -qpR {.rpm-file} Find out what dependencies a rpm file has
rpm -qR {package}
rpm -qR bash

How to Print .spec file from RPM

rpm --scripts -qp <rpmfile>

First RPM

Name of Package : libtorrent
Building it in folder “/usr/local/src/libtorrent”

mkdir /usr/local/src/libtorrent
cd /usr/local/src/libtorrent
mkdir BUILD RPMS SOURCES SPECS SRPMS

Creating macro not bad idea.

| /usr/local/src/libtorrent/.rpmmacros
%packager Ketan Patel

Get Sources from libtorrent
Place it in “/usr/local/src/libtorrent/SOURCES”
I have used following method.

cd /usr/local/src/libtorrent/SOURCES
svn co svn://rakshasa.no/libtorrent/trunk/libtorrent libtorrent
tar -cvf /usr/local/src/libtorrent/SOURCES/libtorrent.tar.gz libtorrent

Considering building rtorrent at non standard location.

NOTE : Please make sure code below has some SUSE Based Customization

| /usr/local/src/libtorrent/SPECS/libtorrent.spec
%define name libtorrent
%define srcdir /usr/local/src
%define _topdir %{srcdir}/libtorrent
 
 
summary: rTorrent
name: libtorrent
Source: libtorrent.tar.gz
License: GPL
version: 1
release: 1
Group: System/Utils
Prefix: /opt/libtorrent
buildarch: x86_64
BuildRoot: %{prefix}/%{name}-%{version}-%{release}-%{buildarch}-root
%define lib %{prefix}/lib64
%define include %{prefix}/include
Provides: libtorrent
Requires: ncurses, libcppunit-devel
AutoReqProv: no
 
 
%description
libtorrent is a BitTorrent client for ncurses, using
the libtorrent library. The client and library is
written in C++ with emphasis on speed and efficiency, while delivering
equivalent features to those found in GUI based clients in an ncurses
client.
 
%prep
%setup -q -n libtorrent
 
 
%build
chmod 755 autogen.sh
./autogen.sh
%{suse_update_config -f}
autoreconf -fiv
./configure --prefix=%{prefix} --libdir=%{lib}
make prefix=$RPM_BUILD_ROOT
 
%install
rm -rf %{buildroot}
make DESTDIR=$RPM_BUILD_ROOT install
rm -rf $RPM_BUILD_ROOT/%{prefix}/usr
 
 
%clean
make clean
rm -rf %{buildroot}
 
%files
%defattr(-,root,root,-)
%doc README
/opt/libtorrent/lib64/*
/opt/libtorrent/include/*
 
%post
echo "/opt/libtorrent/lib64/" > /etc/ld.so.conf.d/libtorrent.conf
ldconfig
 
%postun
rm -rf %{prefix}
rm /etc/ld.so.conf.d/libtorrent.conf
ldconfig
 
%Changelog
* Mon Nov 08 2010 Seriously, Check release son!!
Initial Build
Building Actual RPM
cd /usr/local/src/libtorrent
rpmbuild -v -bb --clean SPECS/libtorrent.spec

OR

rpmbuild -ba SPECS/libtorrent.spec
Test Your RPM
rpm -Vp RPMS/x86_64/libtorrent-1-1.x86_64.rpm

Something i come across

If you wanna override marco from OS you can define value at top of the spec file.

%define _mandir /usr/man

Sample RPM

| sample.spec
Name:      xgauguin-support
Summary:   xGauguin support metapackage
Version:   20110513
Release:   1.blip
Vendor:    lithiumfox
License:   none
Group:     Applications
URL:       http://lithiumfox.com
BuildRoot: %{_tmppath}/%{name}-%{version}-%(id -u -n)
BuildArch: noarch
Requires:  nginx, perl(Image::Size), perl(Params::Validate), perl(DateTime::Locale), perl(Class::Load), perl(parent), perl(DateTime::TimeZone), perl(Class::Singleton), perl(Test::Exception), perl(DateTime), perl(Image::Magick), perl(GD), perl(LWP), ImageMagick, gd, yum-utils
 
%description
Gauguin supporting packages
 
%install
[ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
%{__mkdir_p} %{buildroot}%{_localstatedir}/www/releases
%{__mkdir_p} %{buildroot}%{_localstatedir}/tmp/cache
 
%pretrans
## Force installation of conflicts
# libxml2.i386, perl-Locale-Codes
if $( ! rpm -q libxml2.i386 > /dev/null 2>&1)
  then
 
    yumdownloader libxml2.i386 > /dev/null 2>&1
    %{__rm} /var/lib/rpm/__db.000 > /dev/null 2>&1
    rpm --force -ivh libxml2*.rpm 
    %{__rm} libxml2*.rpm > /dev/null 2>&1
fi
 
if $( ! rpm -q perl-Locale-Codes > /dev/null 2>&1)
  then
    set -m
    yumdownloader perl-Locale-Codes > /dev/null 2>&1
    %{__rm} /var/lib/rpm/__db.000 > /dev/null 2>&1
    rpm --force -ivh perl-Locale-Codes*.rpm > /dev/null 2>&1
    %{__rm} libxml2*.rpm > /dev/null 2>&1
fi
 
%pre
## Check if vlad user exists, if not add them
if $( ! id vlad >/dev/null 2>&1) 
   then
     groupadd -g 1029 vlad > /dev/null 2>&1 ||: 
     useradd -u 1029 -g 1029 -d /home/vlad -s /bin/bash -p '$1asdf0' -m vlad > /dev/null 2>&1
fi
 
##Add user to sudoers
if $( ! grep vlad /etc/sudoers >/dev/null 2>&1)
  then
    echo "vlad ALL=NOPASSWD: /etc/init.d/nginx" >> /etc/sudoers
fi
 
%post
##Add nginx to startup
chkconfig --level 345 nginx on
 
##Create symlink for nginx.conf
if [ ! -h /etc/nginx/nginx.conf ]
  then
   ln -f -s %{_localstatedir}/www/prod/gauguin/current/conf/nginx-prod.conf %{_sysconfdir}/nginx/nginx.conf
fi 
 
 
%files
%defattr(-,root,root)
%attr(-,vlad,-) %{_localstatedir}/www/prod/xgauguin
%attr(777,-,-) %{_localstatedir}/tmp/xgauguin-cache
 
%changelog
* Fri May 13 2010 Jason Thomas <jason@lithiumfox.com> - %{version}
- Initial package creation

changelog

You can use following one liner for changelog.

awk '{print "*", $1, $2, $3, $6, "Jason Thomas <jason@lithiumfox.com>","-", "%{version}""\n""- initial rpm creation"}' <(date)

Good Reading

Scriptlets

Normally, rpm has scriptlets inside the spec file that are ran at install time. These are:

	%pre              - Run before rpm files are installed.
	%post             - Run after rpm files are installed.
	%preun            - Run before rpm files are erased.
	%postun           - Run after rpm files are erased.
 	%triggerin        - Install trigger.
	%triggerun        - uninstall trigger
	%triggerpostun    - postuninstall trigger.

The scripts are normally bash scripts, but you can change the interpreter with the -p option.

Also, as they are bash scripts you can call external scripts from these.

General RPM Command

List Content

rpm -qpl file.rpm

Error on Building

module: command not found

Try running following command and then execute rpmbuild will resolve the issue.

source /etc/profile.d/modules.sh

MOCK

Mock is a really nice tool to generate RPM cleanly.
I used KVM / MOCK to build RPM for my own reasons but you can use just mock and clean env. after every build.

General Details Available at Mock Project Page

Rather then guessing i have pasted all the command i have used to build RPM from srpm.
Using / Generating Spec require another tutorial this is strictly about some work around and keeping env. between transaction.

Install Mock
yum install mock
Add user to group

I am using rpmbuild user.

usermod -a -G mock rpmbuild
Initialize Mock

Before you work on anything Please initialize the environment.
It is good practice to initialize Environment between every build cycle to clean any possible left over or unforeseen issue.

mock --init -r epel-5-x86_64

su to user

You can not run mock as root so ….

su rpmbuild
Install required packages

I found that installed package stays installed during cycles.
So you do not require to install packages every time unless you initialize env.

/usr/bin/mock --install -r epel-5-x86_64 perl-libwww-perl.noarch
Building SRPM
mock -r epel-6-x86_64 --spec icinga-web.spec --sources=../SOURCES/ --resultdir=../RPMS/ --buildsrpm

Copying Files

<note important>Dont scratch over –copyin check spelling one more time</note>

/usr/bin/mock -r epel-5-x86_64 --copyin pgpool-II-3.1.2.tar.gz /tmp/
Get SRPM
cd ~
wget http://ftp.arix.com/cpan2rpm-2.028-1.src.rpm
Finally Building RPM

<note> –no-clean : this will keep your files intact in build env.
–no-cleanup-after : i wanted to keep all work file so i used this just incase. </note>

/usr/bin/mock --rebuild --no-clean --no-cleanup-after -r epel-5-x86_64 cpan2rpm-2.028-1.src.rpm

In general case result will be stored in '/var/lib/mock/epel-5-x86_64/result/'

SPEC file Overview

This is mostly from following URL Fedora Project

Other useful guides:
 
RPM Guide describes how to write a SPEC file.
The IBM series "Packaging software with RPM" Part 1, Part 2, and Part 3.
Maximum RPM has the most complete information, but is dated.
You will need to follow the Fedora guidelines: Package Naming Guidelines, Packaging guidelines, and Package review guidelines.
 
Insert comments with a leading "#" character, but avoid macros (beginning with %) that are potentially multiline (as they are expanded first).
If commenting out a line, double the percent signs (%%). Also avoid inline comments on the same line as a script command.
 
The major tags are listed below. Note that the macros %{name}, %{version} and %{release} can be used to refer to the Name,
Version and Release tags respectively. When you change the tag, the macros automatically update to use the new value.
 
Name: The (base) name of the package, which should match the SPEC file name. 
It must follow the Package Naming Guidelines and generally be lowercase.
Version: The upstream version number. See Version tag section of the packaging guidelines.
If the version contains tags that are non-numeric (contains tags that are not numbers),
you may need to include the additional non-numeric characters in the Release tag.
If upstream uses full dates to distinguish versions, consider using version numbers of the form yy.mm[dd] (e.g. 2008-05-01 becomes 8.05).
 
Release: The initial value should normally be 1%{?dist}. 
Increment the number every time you release a new package for the same version of software. 
When a new upstream version is released, change the Version tag to match and reset the Release number to 1. 
See Release tag section of the packaging guidelines. The optional Dist tag might be useful.
 
Summary: A brief, one-line summary of the package. Use American English. Do not end in a period.
 
Group: This needs to be a pre-existing group, like "Applications/Engineering"; 
run "less /usr/share/doc/rpm-*/GROUPS" to see the complete list. 
Use the group "Documentation" for any sub-packages (e.g. kernel-doc) containing documentation.
 
License: The license, which must be an open source software license. 
Do not use the old Copyright tag. Use a standard abbreviation (e.g. "GPLv2+") and be specific 
(e.g. use "GPLv2+" for GPL version 2 or greater instead of just "GPL" or "GPLv2" where it's true). 
See Licensing and the Licensing Guidelines. 
You can list multiple licenses by combining them with "and" and "or" (e.g. "GPLv2 and BSD").
 
URL: The full URL for more information about the program (e.g. the project website). 
 
Note: This is not where the original source code came from which is meant for the Source0 tag below.
 
Source0: The full URL for the compressed archive containing the (original) pristine source code,
as upstream released it. "Source" is synonymous with "Source0".
If you give a full URL (and you should), its basename will be used when looking in the SOURCES directory.
If possible, embed %{name} and %{version}, so that changes to either will go to the right place.
Preserve timestamps when downloading source files. If there is more than one source, name them Source1,
Source2 and so on. If you're adding whole new files in addition to the pristine sources,
list them as sources after the pristine sources. A copy of each of these sources will be included in any SRPM you create,
unless you specifically direct otherwise. See Source URL for more information on special cases (e.g. revision control).
 
Patch0: The name of the first patch to apply to the source code.
If you need to patch the files after they've been uncompressed,
you should edit the files and save their differences as a "patch" file in your ~/rpmbuild/SOURCES directory.
Patches should make only one logical change each, so it's quite possible to have multiple patch files.
 
BuildArch: If you're packaging files that are architecture-independent (e.g. shell scripts, data files),
then add "BuildArch: noarch". The architecture for the binary RPM will then be "noarch".
 
BuildRoot: This is where files will be "installed" during the %install process (after the %build process).
This is now redundant in Fedora and is only needed for EPEL5. By default, the build root is placed in "%{_topdir}/BUILDROOT/".
 
BuildRequires: A comma-separated list of packages required for building (compiling) the program.
This field can be (and is commonly) repeated on multiple lines. These dependencies are not automatically determined,
so you need to include everything needed to build the program. Some common packages can be omitted, such as gcc.
You can specify a minimum version if necessary (e.g. "ocaml >= 3.08").
If you need the file /EGGS, determine the package that owns it by running "rpm -qf /EGGS".
If you need the program EGGS, determine the package that owns it by running "rpm -qf `which EGGS`".
Keep dependencies to a minimum (e.g. use sed instead of perl if you don't really need perl's abilities),
but beware that some applications permanently disable functions if the associated dependency is not present;
in those cases you may need to include the additional packages. The "auto-br-rpmbuild" command may be helpful.
 
Requires: A comma-separate list of packages that are required when the program is installed.
Note that the BuildRequires tag lists what is required to build the binary RPM,
while the Requires tag lists what is required when installing/running the program;
a package may be in one list or in both. In many cases,
rpmbuild automatically detects dependencies so the Requires tag is not always necessary.
However, you may wish to highlight some specific packages as being required, or they may not be automatically detected.
 
%description: A longer, multi-line description of the program.
Use American English. All lines must be 80 characters or less.
Blank lines indicate a new paragraph. Some graphical user interface installation programs will reformat paragraphs;
lines that start with whitespace will be treated as preformatted text and displayed as is, normally with a fixed-width font.
See RPM Guide.
 
%prep: Script commands to "prepare" the program (e.g. to uncompress it) so that it will be ready for building.
Typically this is just "%setup -q"; a common variation is "%setup -q -n NAME" if the source file unpacks into NAME.
See the %prep section below for more.
 
%build: Script commands to "build" the program (e.g. to compile it) and get it ready for installing. 
The program should come with instructions on how to do this. See the %build section below for more.
 
%check: Script commands to "test" the program. This is run between the %build and %install procedures,
so place it there if you have this section. Often it simply contains "make test" or "make check".
This is separated from %build so that people can skip the self-test if they desire.
 
%install: Script commands to "install" the program.
The commands should copy the files from the BUILD directory %{_builddir} into the buildroot directory, 
%{buildroot}. See the %install section below for more.
 
%clean: Instructions to clean out the build root. Note that this section is now redundant in Fedora and is only necessary for EPEL. 
Typically this contains only:
rm -rf %{buildroot}
 
%files: The list of files that will be installed. See the %files section below for more.
 
%changelog: Changes in the package. Use the format example above.
 
ExcludeArch: If the package does not successfully compile, build or work on a particular architecture,
list those architectures under this tag.
You can add sections so that code will run when packages are installed or removed on the real system 
(as opposed to just running the %install script, which only does a pseudo-install to the build root).
These are called "scriptlets", and they are usually used to update the running system with information from the package.
See the "Scriptlets" section below for more. RPM also supports the creation of several packages (called subpackages) 
from a single SPEC file, such as name-libs and name-devel packages.
 
Do not use these tags:
 
Packager
Vendor
Copyright
Do not create a "relocatable" package; they don't add value in Fedora and make things more complicated.

SPEC file sections explained

 %prep section
The %prep section describes how to unpack the compressed packages so that they can be built. 
Typically, this includes the "%setup" and "%patch" commands with reference to the Source0 
(and Source1 etc.) lines. See the Maximum RPM section on %setup and %patch for more details.
 
The %{patches} and %{sources} macros are available since RPM 4.4.2 and are useful
if you have a large list of patches or sources:
 
for p in %{patches}; do
    ...
done
However, keep in mind that using these will make your SPEC incompatible with RPMS
used in RHEL and other RPM-based dirstributions.
 
 %prep section: %setup command
The "%setup" command unpacks a source package. Switches include:
 
-q : Suppress unecessary output. This is commonly used.
 
-n name : If the Source tarball unpacks into a directory whose name is not the RPM name,
 
this switch can be used to specify the correct directory name. For example,
if the tarball unpacks into the directory FOO, use "%setup -q -n FOO".
 
-c name : If the Source tarball unpacks into multiple directories instead of a single directory, 
this switch can be used to create a directory named name and then unpack into it.
There are more %spec options if you are unpacking multiple files,
which is primarily useful if you are creating subpackages (see below). The key ones are:
 
-a number	 Only unpack the Source directive of the given number after changing directory 
(e.g. "–a 0" for Source0).
-b number	 Only unpack the Source directive of the given number before changing directory
(e.g. "–b 0" for Source0).
-D	 Do not delete the directory before unpacking.
-T	 Disable the automatic unpacking of the archives.
 
 %prep section: %patch commands
The "%patch0" command applies Patch0 (and %patch1 applies Patch1 etc.).
Patches are the normal method of making necessary changes to the source code for packaging.
The usual "-pNUMBER" option applies, which passes that argument onto the program patch.
 
Patch file names often look like "telnet-0.17-env.patch",
which is the format %{name} - %{version} - REASON.patch" (though sometimes version is omitted).
Patch files are typically the result of "diff -u";
if you do this from the subdirectory of ~/rpmbuild/BUILD then you won't have to specify a -p level later.
 
This is a typical procedure for creating a patch for a single file:
 
cp foo/bar foo/bar.orig
vim foo/bar
diff -u foo/bar.orig foo/bar > ~/rpmbuild/SOURCES/PKGNAME.REASON.patch
If editing many files, one easy method is to copy the 
whole subdirectory underneath BUILD and then do subdirectory diffs. 
After you have changed directory to "~rpmbuild/BUILD/NAME", do the following:
 
cp -pr ./ ../PACKAGENAME.orig/
... many edits ...
diff -u ../PACKAGENAME.orig . > ~/rpmbuild/SOURCES/NAME.REASON.patch
If you edit many files in one patch, you can also copy the original files
 using some consistent ending such as ".orig" before editing them.
Then, you can use "gendiff" (in the rpm-build package) to create a patch with the differences.
 
Try to ensure that your patch match the context exactly.
The default "fuzz" value is "0", requiring matches to be exact.
You can work around this by adding "%global _default_patch_fuzz 2" 
to revert to the value found in older versions of RPM in Fedora, 
but it is generally recommended to avoid doing this.
 
As explained in Packaging/PatchUpstreamStatus,
all patches should have a comment above them in the SPEC file about their upstream status.
This should document the upstream bug/email that includes it (including the date).
If it is unique to Fedora, you should mention why it is unique.
The Fedora Project tries not to deviate from upstream;
see PackageMaintainers/WhyUpstream for the importance of this.
 
 %prep section: Unmodified files
Sometimes, one or more of the Source files do not need to be uncompressed. 
You can "prep" those into the build directory like this (where SOURCE1 refers to the relevant Source file):
 
cp -p %SOURCE1 .
 %build section
The "%build" section is sometimes complicated; 
here you configure and compile/build the files to be installed.
 
Many programs follow the GNU configure approach (or some variation).
By default, they will install to a prefix of "/usr/local", which is reasonable for unpackaged files.
However, since you are packaging it, change the prefix to "/usr".
Libraries should be installed to either /usr/lib or /usr/lib64 depending on the architecture.
 
Since GNU configure is so common, the macro "%configure" can be used to automatically
invoke the correct options (e.g. change the prefix to /usr). Some variation of this often works:
 
 %configure
 make %{?_smp_mflags}
To override makefile variables, pass them as parameters to make:
 
make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir}
More more information, see "GNU autoconf, automake, and libtool"
 and 
"Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf" by Stefan Hundhammer.
 
Some programs use cmake. See Packaging/cmake.
 
 %check section
If self-tests are available, it is generally a good idea to include them.
They should be placed in the %check section (which immediately follows the %build section)
instead of within the %build section itself, so that they can be easily skipped when necessary.
 
Often, this section contains:
 
make test
 %install section
This section involves script commands to "install" the program,
copying the relevant files from %{_builddir} to %{buildroot}
(which usually means from ~/rpmbuild/BUILD to ~/rpmbuild/BUILDROOT)
and creating directories inside %{buildroot} as necessary.
 
Some of the terminology can be misleading:
 
The "build directory", also known as %{_builddir} is not the same as the "build root",
also known as %{buildroot}. Compilation occurs in the former directory,
while files to be packaged are copied from the former to the latter.
 
During the %build section, the current directory will start at %{buildsubdir},
which is the subdirectory within %{_builddir} that was created during %prep stage.
This is usually something like ~/rpmbuild/BUILD/%{name}-%{version}.
The %install section is not run when the binary RPM package is installed by the end-user,
but is only run when creating a package.
Normally, some variation of "make install" is performed here:
 
%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
Removal of %{buildroot} is no longer necessary, except for EPEL 5.
 
Ideally you should use DESTDIR=%{buildroot} if the program supports it,
as it redirects file installations to the specified directory and is exactly
what we want to happen during the %install section.
 
If the program does not support DESTDIR (and only if),
you can workaround it in one of several (inferior) ways:
 
Patch the makefile so that is supports DESTDIR.
Create directories inside DESTDIR where necessary and submit the patch upstream.
 
Use the "%makeinstall" macro. This method might work, but can lead to subtle failures.
It expands to something like 
"make prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install",
which can result in some programs failing to work properly.
Create directories inside %{buildroot} where necessary.
 
Consider using the auto-destdir package. This requires 
"BuildRequires: auto-destdir", and changing "make install" to "make-redir DESTDIR=%{buildroot} install".
This only works well if the installation uses only certain common commands to install files,
like cp and install.
 
Perform the installation by hand. This would involve creating the necessary directories under
%{buildroot} and copying files from %{_builddir} to %{buildroot}.
Be especially careful with updates, which often contain new or changed filenames.
An example of this procedure:
 
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}%{_bindir}/
cp -p mycommand %{buildroot}%{_bindir}/
As noted in Packaging:Guidelines#Timestamps, 
try to preserve timestamps if the makefile lets you override commands:
 
make INSTALL="install -p" CP="cp -p" DESTDIR=%{buildroot} install
 
 %files section
This section declares which files and directories are owned by the package,
and thus which files and directories will be placed into the binary RPM.
 
 %files basics
The %defattr set the default file permissions, and is often found at the start of the %files section.
Note that this is no longer necessary unless the permissions need to be altered. The format of this is:
 
%defattr(<file permissions>, <user>, <group>, <directory permissions>)
The fourth parameter is often omitted. 
Usually one uses %defattr(-,root,root,-), where "-" uses the default permissions.
 
You should then list all the files and directories to be owned by the package.
Use macros for directory names where possible,
which can be viewed at Packaging:RPMMacros (e.g. use %{_bindir}/mycommand instead of /usr/bin/mycommand).
If the pattern begins with a "/" (or when expanded from the macro) 
then it is taken from the %{buildroot} directory. Otherwise, 
the file is presumed to be in the current directory (e.g. inside %{_builddir} 
(such as documentation files that you wish to include). 
If your package only installs a single file /usr/sbin/mycommand, 
then the %files section can simply be:
 
%files
%{_sbindir}/mycommand
To make your package less sensitive to upstream changes,
declare all files within a directory to be owned by the package with a pattern match:
 
%{_bindir}/*
To include a single directory:
 
%{_datadir}/%{name}/
Note that %{_bindir}/* does not claim that this package owns the /usr/bin directory,
but only the files contained within. If you list a directory,
then you are claiming that the package owns that directory and 
all files and subdirectories contained within. Thus, do not list %{_bindir} and 
be careful of directories that may be shared with other packages.
 
An error will occur if:
 
a pattern match does not match any file or directory
a file or directory is listed or matched more than once
a file or directory in the %{buildroot} has not been listed
It is also possible to exclude files from a previous match by using the %exclude glob.
This can be useful for including almost all of the files included by a different pattern match,
but note that it will also fail if it does not match anything.
 
 %files prefixes
You may need to add one or more prefixes to lines in the %files section;
seperate them with a space. See Max RPM section on %files directives.
 
Usually, "%doc" is used to list documentation files within 
%{_builddir} that were not copied to %{buildroot}. 
A README and INSTALL file is usually included. 
They will be placed in the directory /usr/share/doc/%{name}-%{version}, 
whose ownership does not need to be declared.
 
Note: If specifying a %doc entry, 
then you can't copy files into the documentation directory during the %install section.
If, for example, you want an "examples" subdirectory within the documentation directory,
don't use %doc, but instead create the directories and copy files over manually
 into %{buildroot}%{_defaultdocdir}/%{name}-%{version} during the %install section.
They will be correctly marked as documentation.
Make sure you include %{_defaultdocdir}/%{name}-%{version}/ as an entry in the %files section.
 
Configuration files should be placed in /etc and are normally specified like this
(which makes sure user changes aren't overwritten on update):
 
%config(noreplace) %{_sysconfdir}/foo.conf
If the update uses a non-backwards-compatible configuration format, then specify them like this:
 
%config %{_sysconfdir}/foo.conf
"%attr(mode, user, group)" can be used for finer control over permissions,
where a "-" means use the default:
 
%attr(0644, root, root) FOO.BAR
If a file is in particular natural language, use %lang to note that:
 
%lang(de) %{_datadir}/locale/de/LC_MESSAGES/tcsh*
Programs using Locale files should follow the recommended method of handling i18n files:
 
find the filenames in the %install step:  %find_lang ${name}
add the required build dependencies: BuildRequires: gettext
use the found filenames: %files -f ${name}.lang
These prefixes are not valid in Fedora: %license and %readme.
 
 %files and Filesystem Hierarchy Standard (FHS)
You should follow the Filesystem Hierarchy Standard (FHS).
Executables go in /usr/bin, global configuration files go in /etc,
libraries go into /usr/lib (or /usr/lib64) and so on.
There is one exception: executables that should not normally be executed
directly by users or administrators should go in a subdirectory of /usr/libexec,
which is referred to as %{_libexecdir}/%{name}.
 
Do not install files into /opt or /usr/local.
 
Unfortunately, many programs do not follow the FHS by default.
In particular, architecture-independent libraries get placed in /usr/lib instead of /usr/share.
The former is for architecture-dependent libraries,
while the latter is for architecture-independent libraries,
which means that systems with different CPU architectures can share /usr/share.
There are many exceptions in Fedora (such as Python and Perl),
but Fedora applies this rule more strictly than some distributions.
rpmlint will generally complain if you put anything other than ELF files into /usr/lib.
 
 %files example
Here's a simple example of a %files section:
 
%files
%doc README LICENSE
%{_bindir}/*
%{_sbindir}/*
%{_datadir}/%{name}/
%config(noreplace) %{_sysconfdir}/*.conf
Finding duplicates
You can list any duplicates of two binary packages by doing:
 
cd ~/rpmbuild/RPMS/ARCH # Substitute "ARCH" for your architecture
rpm -qlp PACKAGE1.*.rpm | sort > ,1
rpm -qlp PACKAGE2.*.rpm | sort > ,2
comm -12 ,1 ,2
Scriptlets
When an end-user installs the RPM, you may want some commands to be run.
This can be achieved through scriptlets. See Packaging/ScriptletSnippets.
 
Scriptlets can be run:
 
before (%pre) or after (%post) a package is installed
before (%preun) or after (%postun) a package is uninstalled
at the start (%pretrans) or end (%posttrans) of a transaction
For example, every binary RPM package that stores shared library files
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 perform the same actions.
 
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
If only running a single command, then the "-p" option runs the adjacent
command without invoking the shell. However, for several commands,
omit this option and include the shell commands beneath.
 
If you run any programs within the scriptlets, then you must specify any
requirements in the form "Requires(CONTEXT)" (e.g. Requires(post)).
 
%pre, %post, %preun, and %postun provide the argument $1,
which is the number of packages of this name which will be left on the system
when the action completes. Don't compare for equality with 2,
but instead check if they are greater than or equal to 2.
For %pretrans and %posttrans, $1 is always 0.
 
For example, if the package installs an info manual,
then the info manual index must be updated with install-info from the info package.
Firstly, there is no guarantee that the info package will be available unless
we explicitly declare it as required, and secondly,
we don't want to fail completely if install-info fails:
 
Requires(post): info
Requires(preun): info
...
%post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi
There is one other glitch related to installing info manuals.
The install-info command will update the info directory,
so we should delete the useless empty directory from the %{buildroot} during the %install section:
 
rm -f %{buildroot}%{_infodir}/dir
Another scriptlet-like abilility are "triggers",
which can be run for your package when other packages are installed or uninstalled.
See RPM Triggers.
 
Macros
Macros are text in the format %{string}. Typical macros:
Macro Typical Expansion Meaning
%{_bindir} /usr/bin Binary directory: where executables are usually stored.
%{_builddir} ~/rpmbuild/BUILD Build directory: files are compiled within a subdirectory of the build directory. See %buildsubdir.
%{buildroot} ~/rpmbuild/BUILDROOT Build root: where files are “installed” during the %install stage, which copies files from a subdirectory of %{_builddir} to a subdirectory of %{buildroot}. (Historically, %{buildroot} was in “/var/tmp/”.)
%{buildsubdir} %{_builddir}/%{name} Build subdirectory: a subdirectory within %{_builddir} where files are compiled during the %build stage. It is set after %setup.
%{_datadir} /usr/share Share directory.
%{_defaultdocdir} /usr/share/doc Default documentation directory.
%{dist} .fcNUMBER Distribution+version short name (e.g. “.fc9”)
%{fedora} NUMBER Number of fedora release (e.g. “9”)
%{_includedir} /usr/include
%{_infodir} /usr/share/info
%{_initrddir} /etc/rc.d/init.d
%{_libdir} /usr/lib
%{_libexecdir} /usr/libexec
%{_localstatedir} /var
%{_mandir} /usr/share/man
%{name} Name of package, set by Name: tag
%{_sbindir} /usr/sbin
%{_sharedstatedir} /var/lib
%{_sysconfdir} /etc
%{version} Version of package, set by Version: tag
Learn more about macros by looking in /etc/rpm/* and /usr/lib/rpm, especially /usr/lib/rpm/macros.
Also use rpm --showrc to show values that RPM will use for macros (altered by rpmrc and macro configuration files).
 
You can set your own macro values using %global,
but be sure to define them before you use them.
(Macro definitions can also refer to other macros.) For example:
 
%global date 2012-02-08
Use the "-E" option of rpmbuild to find the value of a macro in a SPEC file:
 
rpmbuild -E '%{_bindir}' myfile.spec
Also see Packaging/RPMMacros and RPM Guide chapter 9.

Custom Built RPM

rpm.txt · Last modified: 2020/08/10 02:35 (external edit)