RPM: proof of concept

Alexander E. Patrakov patrakov at gmail.com
Sun Mar 2 08:07:31 MST 2008


Hello,

I have digged up the archives of LeafOS lists and extracted RPM instructions and 
spec files from them. Spec files up to and including Chapter 6 bash are attached 
(slightly modified).

Dan: sorry for ignoring your superior work.

Differences from the book: the toolchain adjustment method is from DIY 
next-generation build, the /usr/{man,info,doc} directories are removed.

Bugs:

1) I don't split away -devel packages and binaries. This split is absolutely 
required for doing library transitions (such as changing over from libfoo.so.1 
to libfoo.so.2) smoothly, because otherwise the two packages with different 
versions of the library cannot be installed simultaneously (they provide the 
same headers, and RPM doesn't allow one file to belong to two different 
packages). However, I expect disagreement among editors about the best way to 
split packages.

2) RPM-specific variables such as %{optflags} are ignored, because they are 
incompatible with the concept of making instructions for several package 
managers from the same XML source, proposed by Jeremy Huntwork.

3) The unpacking-and-patching part (%setup) is still in a state when we can't 
easily generate it.

4) Upstream RPM bugs noticed in LeafOS (namely: not stripping shared libraries 
by default; wrong check for "file" output that leads to non-stripping setuid ELF 
binaries; missing "exit 0" at the end of the brp-nobuildrootpath script) are not 
fixed.

5) The list of installed files should not be just "/*".

6) Configuration files should come together with packages (as done in my spec 
files with readline and not done with bash).

Features: the --force switch is never used.

Instructions:

Manually follow the Chapter 5 of the regular LFS book (well, I deviated and used 
the next-generation toolchain instructions from DIY but that shouldn't matter), 
with the following changes:

a) When building bash, apply the attached bash-requires.patch (from Fedora). It 
adds the --rpm-requires option that is used by RPM to find out the dependencies 
of post-installation and pre-removal scripts.

b) When building gettext, instead of "make -C src msgfmt", do "make -C src 
msgfmt xgettext", and, accordingly, instead of "cp -v src/msgfmt /tools/bin", do 
"cp -v src/{msgfmt,xgettext} /tools/bin". This is necessary because popt can't 
be built without xgettext.

In Section "Creating Essential Files and Symlinks", also add the user "build" 
with uid and gid 98. This is only needed to demonstrate the "build as non-root, 
create a package as non-root, install the resulting package as root" technique, 
which is much safer than the "build as non-root, install as root without 
packaging" method described in BLFS. Of course, when things go beyond just a 
proof of concept, the process of changing from root to the user "build" should 
be replaced with the opposite process, e.g., via sudo.

As the first few steps in Chapter 6, just after "Creating Essential Files and 
Symlinks", compile a few packages. This has the following advantage as compared 
to building them at the end of Chapter 5 (i.e., before the chroot): there are 
absolutely no chances that unwanted dependencies from the host will be picked up.

# m4-1.4.10: beecrypt depends on it at build time
# http://www.gnu.org/software/m4/
# http://ftp.gnu.org/gnu/m4/m4-1.4.10.tar.bz2

./configure --prefix=/tools
make
make install

# beecrypt-4.1.2: rpm depends on it
# http://beecrypt.sourceforge.net/
# http://prdownloads.sourceforge.net/beecrypt/beecrypt-4.1.2.tar.gz

./configure --prefix=/tools
make
make install

# popt-1.13: rpm depends on it
# http://rpm5.org/
# http://rpm5.org/files/popt/popt-1.13.tar.gz

./configure --prefix=/tools
make
make install

# elfutils-0.131: optional dependency of RPM, provides better tracking
# of library dependencies, required for compatibility with third-party
# RPMs that list symbol-versioned dependencies such as "libc.so.6(GLIBC_2.4)"
# ftp://sourceware.org/pub/systemtap/elfutils/elfutils-0.131.tar.gz

./configure --prefix=/tools --enable-tls
# Don't install the whole package--it will overwrite binutils!
make -C libelf
make -C libelf install

# file-4.23: called at runtime by scripts that come with RPM
# ftp://ftp.gw.com/mirrors/unix/file/file-4.23.tar.gz

./configure --prefix=/tools
make
make install

# rpm-5.0.2: subject of this mail
# Note that there are two different package managers named "RPM".
# One is maintained by RedHat and is located at http://www.rpm.org/
# I use a fork by Jeff Johnson, for no particular reason.
# The attached spec files are incompatible with RedHat RPM, e.g.,
# because they use the automatic setting of the BuildRoot variable.
# http://rpm5.org/
# http://rpm5.org/files/rpm/rpm-5.0/rpm-5.0.2.tar.gz

# goal: install to /tools, kee the database in /var, guess the default macros
# in a way suitable for installing packages to /usr

./configure --prefix=/usr --bindir=/tools/bin --libdir=/tools/lib \
     --includedir=/tools/include --datarootdir=/tools/share \
     --with-path-lib=/tools/lib/rpm --with-path-locale=/tools/share/locale \
     --without-perl --without-python --with-bzip2 --with-libelf
sed -i 's@/tools/bin/@@' macros
sed -i 's@/doc@/share/doc@' macros
sed -i 's@/info@/share/info@' macros
sed -i 's@/man@/share/man@' macros
sed -i 's@/usr/X11R6@/tools@' macros
ln -s /tools/share/file/magic /tools/lib/rpm/
make
make install
# /usr/lib/rpm is hard-coded in several places
# but I have missed this fact during my test,
# so let's have it commented out for reproducibility of my results
# ln -s /tools/lib/rpm /usr/lib

Copy sources and patches to /usr/src/rpm/SOURCES, and copy specs to 
/usr/src/rpm/SPECS.

Change the ownership of the build tree:

chown -R build:build /usr/src/rpm

In the following instructions, it is assumed that /usr/src/rpm/SPECS is the 
current directory.

Create and install two fake (empty) packages that work around circular 
dependencies by (virtually) providing /bin/sh and /usr/bin/perl:

su-tools build -c "rpm --clean -bb fake-bash.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/bash-0.0-1.i686.rpm
su-tools build -c "rpm --clean -bb fake-perl.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/perl-0.0-1.i686.rpm

Compile and install packages up to and including glibc:

su-tools build -c "rpm --clean -bb linux-headers.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/linux-headers-2.6.24-1.i686.rpm
su-tools build -c "rpm --clean -bb man-pages.spec"
rpm -ivh /usr/src/rpm/RPMS/noarch/man-pages-2.78-1.noarch.rpm
su-tools build -c "rpm --clean -bb glibc.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/glibc-2.7-1.i686.rpm

Adjust the toolchain the way DIY does it:

ln -sv /tools/bin/ld-new /usr/bin/ld

The whole procedure of changing the gcc specs is in the spec files of gcc and 
binutils, so install these two packages:

su-tools build -c "rpm --clean -bb binutils.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/binutils-2.18-1.i686.rpm
su-tools build -c "rpm --clean -bb gcc.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/gcc-4.2.3-1.i686.rpm

(sorry, the testsuites are commented out, but in my initial testing, the results 
were good)

Compile some more packages:

su-tools build -c "rpm --clean -bb db.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/db-4.6.21-1.i686.rpm
su-tools build -c "rpm --clean -bb sed.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/sed-4.1.5-1.i686.rpm
su-tools build -c "rpm --clean -bb e2fsprogs.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/e2fsprogs-1.40.6-1.i686.rpm
su-tools build -c "rpm --clean -bb coreutils.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/coreutils-6.10-1.i686.rpm
su-tools build -c "rpm --clean -bb iana-etc.spec"
rpm -ivh /usr/src/rpm/RPMS/noarch/iana-etc-2.20-1.noarch.rpm
su-tools build -c "rpm --clean -bb m4.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/m4-1.4.10-1.i686.rpm
su-tools build -c "rpm --clean -bb bison.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/bison-2.3-1.i686.rpm
su-tools build -c "rpm --clean -bb ncurses.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/ncurses-5.6-1.i686.rpm
su-tools build -c "rpm --clean -bb procps.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/procps-3.2.7-1.i686.rpm
su-tools build -c "rpm --clean -bb libtool.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/libtool-1.5.26-1.i686.rpm

Compile perl and upgrade from the fake perl package to the real one:

su-tools build -c "rpm --clean -bb perl.spec"
rpm -Uvh /usr/src/rpm/RPMS/i686/perl-5.8.8-1.i686.rpm

Compile some more packages:

su-tools build -c "rpm --clean -bb readline.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/readline-5.2-1.i686.rpm
su-tools build -c "rpm --clean -bb zlib.spec"
rpm -ivh /usr/src/rpm/RPMS/i686/zlib-1.2.3-1.i686.rpm
su-tools build -c "rpm --clean -bb autoconf.spec"
rpm -ivh /usr/src/rpm/RPMS/noarch/autoconf-2.61-1.noarch.rpm
su-tools build -c "rpm --clean -bb automake.spec"
rpm -ivh /usr/src/rpm/RPMS/noarch/automake-1.10.1-1.noarch.rpm

Compile bash and replace the fake package:

su-tools build -c "rpm --clean -bb bash.spec"
rpm -Uvh /usr/src/rpm/RPMS/i686/bash-3.2-1.i686.rpm

I have not written spec files past this point, but, because both fake packages 
are already removed, I don't expect any problems down the road. Setuid programs 
in, say, shadow, can be handled by adding %attr statements to the corresponding 
spec file, so it doesn't even interfere with the "build package as non-root" 
technique.

-- 
Alexander E. Patrakov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: SPECS.tar.gz
Type: application/gzip
Size: 9208 bytes
Desc: not available
Url : http://linuxfromscratch.org/pipermail/lfs-dev/attachments/20080302/fdc659b2/attachment.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bash-requires.patch
Type: text/x-diff
Size: 10425 bytes
Desc: not available
Url : http://linuxfromscratch.org/pipermail/lfs-dev/attachments/20080302/fdc659b2/attachment-0001.bin 


More information about the lfs-dev mailing list