By thomas, Tue, 09/22/2009 - 09:23
The main thing to remember in this section is to always define config files as %config. There are subtleties to the way you define directories, but for the most part as long as you define a set of default owner and permissions (%defattr), your RPMs should turn out fine.

I usually start with a default attribute setting and then look for files that should be marked as documentation (%doc). Files marked with %doc are placed in /usr/share/doc/%{name}-%{version}. Populating this directory with files is very useful to the users of your package, most problems can be solved by looking in the /usr/share/doc directory.

%files
%defattr(-,root,root,-)
%defattr sets the default permissions for files using octal notation. The first parameter is the file mode, the permissions applied to files, a '-' means to keep the existing permissions. The last parameter is the directory mode, you can omit this completely and just put %defattr(-,root,root). root,root are the file owner and group respectively.

I usually look in the BUILD directory at this point to see which files should be included in doc, the general rule is anything marked Readme, README, README.txt or similar plus any files that are all CAPS. If there is a doc or html directory, just include the whole directory.

[build@client11 SPECS]$ ls ../BUILD/tar-1.22/
ABOUT-NLS   ChangeLog    configure.ac  lib          NEWS    rmt      THANKS
aclocal.m4  ChangeLog.1  COPYING       m4           po      scripts  TODO
AUTHORS     config.hin   doc           Makefile.am  PORTS   src
build-aux   configure    INSTALL       Makefile.in  README  tests
[build@client11 SPECS]$ 

In the above we should include ABOUT-NLS AUTHORS ChangeLog COPYING doc INSTALL NEWS PORTS README scripts THANKS TODO

%doc ABOUT-NLS AUTHORS ChangeLog COPYING doc INSTALL NEWS PORTS README scripts THANKS TODO 
Next we look in the install directory for the files that were installed by our %makeinstall.
[build@client11 SPECS]$ pushd /tmp/rpm-buildroot-tar-1.22/
/tmp/rpm-buildroot-tar-1.22 ~/rpmbuild/SPECS
[build@client11 rpm-buildroot-tar-1.22]$ cd usr
[build@client11 usr]$ ls
bin  doc  info  libexec  sbin  share
[build@client11 usr]$ ls doc/tar-1.22/
ABOUT-NLS  ChangeLog  doc      NEWS   README   THANKS
AUTHORS    COPYING    INSTALL  PORTS  scripts  TODO
[build@client11 usr]$ ls bin
tar
[build@client11 usr]$ ls libexec
rmt
...
Looking through the directory we see that the usr/doc directory has all the files we specified as %doc in it. tar itself is in usr/bin and rmt is in usr/libexec. There are some localisation files in share/locale that we should include. sbin is empty. We continue looking through directories until we come up with a files section and test it out. If we missed anything, rpm will be sure to tell us.
%files
%defattr(-,root,root)
%doc ABOUT-NLS AUTHORS ChangeLog COPYING doc INSTALL NEWS PORTS README scripts THANKS TODO
/usr/bin/tar
/usr/info/tar.*
/usr/share/locale/*
We omitted a file on purpose to see the error, running rpmbuild will fail because rmt is not listed.
RPM build errors:
    Installed (but unpackaged) file(s) found:
   /usr/libexec/rmt
If we now add rmt into our files, section, the rpm will build.
Checking for unpackaged file(s): /usr/lib/rpm/check-files /tmp/rpm-buildroot-tar-1.22
Wrote: /home/build/rpmbuild/RPMS/x86_64/tar-1.22-1.x86_64.rpm
We aren't finished though, we should really add a %changelog section to our spec file, so we can track the changes we make to it as the package is updated. But, before we do that, I should mention variables. There are many variables available to you when writing your spec files. Variables like %{name} and %{version} we've already seen, but there are variables for directories on the system. If you use these variables your rpm can more easily be ported to another rpm based system. Also, if your system ever decides to move directories you won't have to rewrite your spec file.

You can view all the variables available to you by running rpm --showrc |grep -- ^-14:. One important variable is _prefix, _prefix is used as a prefix for many of the other variables. On my system _prefix is /usr, on some systems it may be /opt or something different. The other 'usual suspects' when trying to use variables are _bindir, _datadir (which is /usr/share), _sbindir and _mandir. Using variables, our new files section is below.

%files
%defattr(-,root,root)
%doc ABOUT-NLS AUTHORS ChangeLog COPYING doc INSTALL NEWS PORTS README scripts THANKS TODO
%{_bindir}/tar
%{_infodir}/tar.*
%{_libexecdir}/rmt
%{_datadir}/locale/*
This version is more portable and maintainable, but also looks cooler and all your friends will be impressed by your use of variables.