UserPreferences

ApplicationNotes/RpmNotes


1. RPM Notes

  1. RPM Notes
    1. User RPM Building
    2. Building With a Non-standard Source Tree
    3. Dynamic Build Requirements
    4. Executing Install Scripts
    5. Prevent Stripping
    6. Best or Common Practices
    7. RPM Rollbacks
    8. Undocumented
      1. %setup

1.1. User RPM Building

RPM by default on RedHatLinux builds under /usr/src/redhat, which is not writable for most users. Many source RPMs (SRPMs) can be built easily as non-root, so rather than building as root, it is better to set up a build environment in your home directory. This section describes how to do that and how to get started building SRPMs. These instructions assume a username of username and home directories are in /home, as they are by default.

  1. Set up the ~/.rpmmacros file to point to your personal RPM build directory:

    echo "%_topdir /home/username/rpm" >> ~/.rpmmacros
    
    

  2. Create the directories RPM expects:

    for d in BUILD RPMS SOURCES SPECS SRPMS; do mkdir -p ~/rpm/$d; done
    for d in noarch i386 i686; do mkdir -p ~/rpm/RPMS/$d; done
    
    

To get started building RPMs, install an SRPM (the file name will usually end with .src.rpm): rpm -ivh foo.src.rpm. The spec file will be in ~/rpm/SPECS, usually something like foo.spec ro foo-1.0.spec. You can edit this file with your favorite text editor, like vi. After you've edited the file to your liking, you can build an RPM with rpm -ba foo.spec. In some cases, you only want to rebuild an SRPM without editing the spec file. You can do this with rpm --rebuild foo.src.rpm.

When rebuilding 3rd party SRPMs, there are often instructions on their creators' home pages for changing options or at the top of the spec file itself. The spec file has a lot to it; the [WWW]RPM home page has a fair amount of information, though much of it is terribly out-of-date.

1.2. Building With a Non-standard Source Tree

Most source trees untar into packagename-version. However, occasionally one finds a tarball that does something slightly different, such as the the version in the filename not matching the actual version, or the '-' being omitted, or something similar. In this case, the -n sourcepath must be appended to the %setup macro, like this:

%setup -q -n %{name}%{version}

1.3. Dynamic Build Requirements

Often I want to build an RPM on multiple platforms with differing versions of libraries. Some library verions are different enough that the version is encoded into the package name, like db3 and db4. Or maybe you want to require gcc on Red Hat 7.3 and compat-gcc on RHES 3. I've devised this bit of spec code to generate short tags for the distro I'm building on; I've really only tested it on RH 7.3, RHES 3, and FC 1.
%dist_tag  %(\
    (rpm -q redhat-release \\\
    || rpm -q fedora-release) 2>/dev/null |\
    sed 's/[\.-]//g; \
        s/release//; \
        s/[[:digit:]]$//; \
        s/fedora/fc/; \
        s/redhat/rh/; \
        s/\\([[:digit:]]\\+\\)ES/es\\1/; \
    ')

It generates the following tags:

Tag Distro-Version
rh73 Red Hat Linux 7.3
rhes3 Red Hat Enterprise Linux 3
fc1 Fedora Core 1
You can then use this tag with the {{%(shell command)}} construct to do the right thing. E. g.:
%if %{dist_tag} == 'rh73'
BuildRequires: db3-devel
%else
BuildRequires: db4-devel
%endif

1.4. Executing Install Scripts

There are a few common tasks performed by install scripts, such as adding and removing a user to own part of the package (such as a daemon) and managint init scripts. (This probably covers 90% of the cases.)

%pre
# RH specs don't seem to test $1 here
if [ $1 -eq 1 ]; then
  /usr/sbin/useradd -c "FOO daemon" foo
fi

%post
if [ $1 -eq 1 ]; then
  /sbin/chkconfig --add FOO
fi

# New/updated libraries?
/sbin/ldconfig

%preun
if [ $1 -eq 0 ]; then
  /sbin/service FOO condstop >/dev/null 2>&1
  /sbin/chkconfig --del FOO
fi

%postun
# Removal
if [ $1 -eq 0 ]; then
  /usr/sbin/userdel foo
  # Contains libraries?
  /sbin/ldconfig
fi

# Upgrade
if [ $1 -ge 1 ]; then
  /sbin/service FOO condrestart
fi

1.5. Prevent Stripping

To stop libraries and binaries from being stripped, use the following:
%define __os_install_post %{nil}

1.6. Best or Common Practices

  1. Don't build as root and fix packages not to require it. See above.

  2. You may use $RPM_BUILD_ROOT or %{buildroot}. I prefer the latter, since it's shorter and requires less keyboard-shifting.

  3. It's no longer necessary to check that $RPM_BUILD_ROOT != "/", since RPM itself does that check and does a better job. So you may change this:

    %clean
    [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
    
    Into this:
    %clean
    rm -rf $RPM_BUILD_ROOT
    

  4. Use 'perl(Module::Name)' for Perl dependencies, instead of explicitly naming the RPM, since the names may vary.

  5. Use License:--not Copyright:.

1.7. RPM Rollbacks

http://www.oreillynet.com/pub/wlg/9080

1.8. Undocumented

1.8.1. %setup


See also: