x72.html
Building Packages with OpenPKG
OpenPKG uses a version of RPM modified to work entirely within a package's directory structure. There are some changes in the way RPMs are built, some the result of encouraging non-root users to build the RPMs, others in the way the RPM sources, builds, and packages are handled in the file system.
Changes in RPM
There have been several changes to the ``rpm'' program:
Build by non-root users.
More rational directory structure.
Cleaner formatting of specfiles.
Utility macros for common functions such as file editing and building a list of files installed.
Encourages building packages with user specified options.
An add-on perl script that rebuilds multiple packages based on dependencies and user defined options.
Packages are built by non-root users, limiting the amount of damage done by bad specfiles.
More rational directory structure -- instead of the SOURCES, SPECS, BUILD, RPMS, and SRPMS directories found under the standard RPM directory, OpenPKG's RPMs are all built under the %{l_prefix}/RPM/{PKG,SRC,TMP} directories. The RPM database is under the %{l_prefix}/RPM/DB directory instead of someplace under /var/lib.
Each package's sources, patches and spec files are in one directory, %{l_prefix}/RPM/SRC/%{name} instead of being split between the SOURCES and SPECS directories as done with standard RPM. I find this much easier to use than having spec files and sources in different directories.
The BUILD directory is replaced by the %{l_prefix}/RPM/TMP directory, and by convention the BUILD_ROOT directory is the same as the build directory with a ``-root'' suffix. This convention makes it easy to look at the installed files using $PWD-root when in the build directory.
A second advantage to using the %{l_prefix}/RPM/TMP directory is that this can be easily symlinked to a directory on a UFS file system when running on Apple's OS\ X OS where the default file system is case insensitive.
The specfile handling has been cleaned up so that macros such as %setup and %patch may be indented from the left margin. This permits indentation of all the major specfile sections for easier reading.
The specfiles can contain options which control the build process making it far easier to build complex programs such as ``apache''.
One of the most important features of the OpenPKG system is the ``openpkg'' script that is used to build and maintain OpenPKG instances. This works in conjunction with the user's ~/.openpkg/build file which contains the location of the SRPMS, and various build options to generate scripts to rebuild and install all packages necessary to one or more packages.
``openpkg build -Ua > /tmp/build.all'' creates a script that will rebuild all packages that are installed on the system, and out of date compared to the archive.
``openpkg build apache > /tmp/build.apache'' creates a script that will build apache and any other packages that apache needs based on the options selected in the ~/.openpkg/build file.
# OpenPKG default parameters for ``openpkg build'' # | -r /e/openpkg/SRC # | -f /e/openpkg/SRC/00INDEX.rdf.bz2 # -f ftp://ftp.celestial.com/mirrors/ftp.openpkg.org/current/00INDEX.rdf # -f ftp://ftp.celestial.com/mirrors/ftp.openpkg.org/release/1.2/00INDEX.rdf #-r ftp://ftp.celestial.com/private/ftp.openpkg.org/current/SRC #-f ftp://ftp.celestial.com/private/ftp.openpkg.org/current/SRC/00INDEX.rdf.bz2 -r ftp://ftp.celestial.com/private/ftp.openpkg.org/release/1.3/SRC -f ftp://ftp.celestial.com/private/ftp.openpkg.org/release/1.3/SRC/00INDEX.rdf.bz2 #-f ftp://ftp.celestial.com/private/ftp.openpkg.org/release/1.3/SRC/00INDEX.rdf -P sudo # -N sudo # the newest version breaks postfix # -E openldap # We're modifying these ourselves # -E postfix # -E myodbc # -E unixodbc -E smail -D smail::with_sendmail=no -D samba::with_docs -D coreutils::with_legacy -D with_cvs_badroot -D gdbm::with_ndbm -D perl::with_shared # openssh options # -D openssh::with_pam -D openssh::with_pcre -D openssh::with_tcp_wrappers -D openssh::with_x11 # This is for vim at least. -D with_x11 -D vim::with_x11=no # Apache -D apache::with_mod_auth_mysql -D apache::with_mod_php_gettext -D with_mod_access_referer=no -D with_mod_auth_ldap -D with_mod_auth_pam=no -D with_mod_dav=no -D apache::with_mod_php_pgsql=yes -D with_mod_fastcgi=no -D with_mod_gzip -D with_mod_layout=no -D with_mod_macro=no -D with_mod_perl -D with_mod_php -D with_mod_php3=no -D with_mod_php3_ftp=no -D with_mod_php3_gd=no -D with_mod_php3_jpeg=no -D with_mod_php3_mysql=no -D with_mod_php3_openssl=no -D with_mod_php3_zlib=no -D with_mod_php_bc -D with_mod_php_bzip2 -D with_mod_php_calendar -D with_mod_php_curl -D with_mod_php_db -D with_mod_php_debug -D with_mod_php_freetype -D with_mod_php_ftp -D with_mod_php_gd=no -D with_mod_php_imap -D with_mod_php_java=no -D with_mod_php_mhash -D with_mod_php_mm -D with_mod_php_mysql -D with_mod_php_oci8=no -D with_mod_php_openldap -D with_mod_php_openssl -D with_mod_php_pcre -D with_mod_php_pdflib -D with_mod_php_transsid -D with_mod_php_xml -D with_mod_php_zlib -D with_mod_relocate=no -D with_mod_roaming=no -D with_mod_ssl -D with_mod_throttle=no # perl dbi -D perl-dbi::with_dbd_mysql -D perl-dbi::with_dbd_pg -D perl-dbi::with_dbd_odbc # perl-xml -D with_libxml -D with_libxslt # glib -D with_threads # postfix -D postfix::with_tls -D postfix::with_ldap -D postfix::with_whoson # postgres -D postgresql::with_cxx=yes -D postgresql::with_perl=yes -D postgresql::with_odbc=yes -D postgresql::with_compat=no |
Building RPMS
RPM works on the principle of building software packages from pristine sources, applying patches as necessary, compiling, and building binary and source RPM files under the control of a single specification file. The spec file controls package building, creation of binary files for installation and source, and anything necessary when the package is installed, updated, or removed. Here is an example of the gcc.spec file used for the OpenPKG build of gcc. It is fairly complex, and has good examples of many of the features of rpm.
##
## gcc.spec -- OpenPKG RPM Specification
## Copyright (c) 2000-2003 The OpenPKG Project <http://www.openpkg.org/>
## Copyright (c) 2000-2003 Ralf S. Engelschall <rse@engelschall.com>
## Copyright (c) 2000-2003 Cable & Wireless <http://www.cw.com/>
##
## Permission to use, copy, modify, and distribute this software for
## any purpose with or without fee is hereby granted, provided that
## the above copyright notice and this permission notice appear in all
## copies.
##
## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
## SUCH DAMAGE.
##
# package version
%define V_full 3.3
%define V_comp %nil
%define V_bounds 1.01
%define V_spp 3
# package information
Name: gcc
Summary: GNU Compiler Collection
URL: http://gcc.gnu.org/
Vendor: Free Software Foundation
Packager: The OpenPKG Project
Distribution: OpenPKG [CORE]
Group: Language
License: GPL
Version: %{V_full}
Release: 1.3.0
# package options
%option with_cxx yes
%option with_optimize yes
%option with_binutils yes
%option with_threads yes
%option with_bounds no
%option with_spp no
%option with_gcc no
# options sanity check
%if "%{with_bounds}" == "yes" && "%{with_spp}" == "yes"
RPM ERROR: options with_bounds and with_ssp conflict
%endif
# list of sources
Source0: ftp://gcc.gnu.org/pub/gcc/releases/gcc-%{version}/gcc-%{version}.tar.bz2
Patch0: gcc.patch
Patch1: http://web.inter.nl.net/hcc/Haj.Ten.Brugge/bounds-checking-gcc-%{version}-%{V_bounds}.patch.bz2
Patch2: http://www.trl.ibm.com/projects/security/ssp/gcc3_3/protector-%{version}-%{V_spp}.tar.gz
# build information
Prefix: %{l_prefix}
BuildRoot: %{l_buildroot}
BuildPreReq: OpenPKG, openpkg >= 1.3.0, make
PreReq: OpenPKG, openpkg >= 1.3.0
%if "%{with_binutils}" == "yes"
BuildPreReq: binutils >= 2.13
PreReq: binutils >= 2.13
%endif
AutoReq: no
AutoReqProv: no
%if "%{with_gcc}" == "yes"
Provides: gcc = %{version}-%{release}
%endif
%description
The GNU Compiler Collection (GCC) provides a standard conforming and
highly portable ISO C and ISO C++ compiler.
%prep
%setup -q -n gcc-%{version}
%patch0 -p0
%if "%{with_bounds}" == "yes"
%patch1 -p1
%endif
%if "%{with_spp}" == "yes"
( cd gcc
%{l_gzip} -d -c %{PATCH protector-%{version}-%{V_spp}.tar.gz} | %{l_tar} xf -
%{l_patch} -p1 <protector.dif ) || exit $?
%endif
%{l_shtool} subst -v -s \
-e "s;PREFIX_INCLUDE_DIR;PREFIX_INCLUDE_DIR_DISABLED;g" \
gcc/configure
%build
# create build sub-directory
mkdir obj
cd obj
# determine ld(1) and as(1) usage
l_with_gnu_ld_as=""
%if "%{with_binutils}" == "yes"
l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-gnu-ld --with-ld=%{l_prefix}/bin/ld"
l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-gnu-as --with-as=%{l_prefix}/bin/as"
%else
case "%{l_target}" in
*-linux* | *-freebsd* )
l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-gnu-as --with-gnu-ld"
;;
esac
%endif
# determine threads usage
%if "%{with_threads}" == "yes"
l_enable_threads="posix"
%else
l_enable_threads="single"
%endif
# determine language usage
l_enable_languages="c"
%if "%{with_cxx}" == "yes"
l_enable_languages="${l_enable_languages},c++"
%endif
# configure the package
CC="%{l_cc}" \
CFLAGS="%{l_cflags}" \
../configure \
--prefix=%{l_prefix} \
--exec-prefix=%{l_prefix} \
--includedir=%{l_prefix}/include/gcc%{V_comp} \
--with-gxx-include-dir=%{l_prefix}/include/g++%{V_comp} \
--with-local-prefix=%{l_prefix}/lib/gcc%{V_comp}-lib \
--enable-languages="${l_enable_languages}" \
--enable-threads="${l_enable_threads}" \
--disable-maintainer-mode \
--disable-shared \
--disable-nls \
${l_with_gnu_ld_as}
# explicitly redirect remaining gcc-lib directories
%{l_shtool} subst -v -s \
-e "s;/gcc-lib/;/gcc%{V_comp}-lib/;" \
`find . -name Makefile -type f -print`
# determine build flags
l_cflags=""
l_boot_cflags=""
l_libcflags="-g"
l_libcxxflags="-g"
%if "%{with_binutils}" == "yes"
# at least GNU as from GNU binutils supports -pipe always
l_boot_cflags="$l_boot_cflags -pipe"
l_libcxxflags="$l_libcxxflags -pipe"
%endif
%if "%{with_optimize}" == "yes"
# conservatively optimize the generated program code
# (also _tune_ for particular CPUs, but _without_ requiring these CPUs!)
l_cflags="$l_cflags -O"
l_boot_cflags="$l_boot_cflags -O2 -fomit-frame-pointer -funroll-loops"
case "%{l_target}" in
*x86-* ) l_boot_cflags="$l_boot_cflags -mcpu=pentium3" ;;
*sparc64-* ) l_boot_cflags="$l_boot_cflags -mtune=v9" ;;
esac
l_libcxxflags="$l_libcxxflags -O2 -fno-implicit-templates"
%else
# else do no optimizations at all to reduce problems to minimum in advance
l_boot_cflags="$l_boot_cflags -O0"
l_libcxxflags="$l_libcxxflags -O0"
%endif
# build the package
%{l_make} %{l_mflags} \
MAKE="%{l_make} %{l_mflags}" \
BOOT_CFLAGS="${l_boot_cflags}" \
CFLAGS="${l_cflags}" \
LIBCFLAGS="${l_libcflags}" \
LIBCXXFLAGS="${l_libcxxflags}" \
bootstrap-lean
%install
rm -rf $RPM_BUILD_ROOT
# fetch GNU platform triple
triple=`./config.guess`
triple=`./config.sub ${triple}`
# perform the standard installation procedure
( cd obj
%{l_make} %{l_mflags} install DESTDIR=$RPM_BUILD_ROOT
) || exit $?
# cleanup installation tree
mv $RPM_BUILD_ROOT%{l_prefix}/lib/lib*.a \
$RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}-lib/${triple}/%{V_full}/
for multilib in `$RPM_BUILD_ROOT%{l_prefix}/bin/gcc --print-multi-lib`; do
subdir=`echo "$multilib" | sed -e 's/;.*$//'`
[ ".$subdir" = .. ] && continue
mv $RPM_BUILD_ROOT%{l_prefix}/lib/$subdir/lib*.a \
$RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}-lib/${triple}/%{V_full}/$subdir/
rm -rf $RPM_BUILD_ROOT%{l_prefix}/lib/$subdir
done
mv $RPM_BUILD_ROOT%{l_prefix}/${triple}/include/* \
$RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}-lib/${triple}/%{V_full}/include/ \
>/dev/null 2>&1 || true
# strip installation tree
rm -rf $RPM_BUILD_ROOT%{l_prefix}/${triple}
rm -rf $RPM_BUILD_ROOT%{l_prefix}/man/man7 >/dev/null 2>&1 || true
rm -f $RPM_BUILD_ROOT%{l_prefix}/lib/*.la >/dev/null 2>&1 || true
rm -f $RPM_BUILD_ROOT%{l_prefix}/bin/*-gcc* >/dev/null 2>&1 || true
%if "%{with_cxx}" == "yes"
rm -f $RPM_BUILD_ROOT%{l_prefix}/bin/*-c++ >/dev/null 2>&1 || true
rm -f $RPM_BUILD_ROOT%{l_prefix}/bin/*-g++ >/dev/null 2>&1 || true
%endif
strip $RPM_BUILD_ROOT%{l_prefix}/bin/* >/dev/null 2>&1 || true
for prog in cc1 cc1plus collect2 cpp; do
strip $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}-lib/${triple}/%{V_full}/${prog} \
>/dev/null 2>&1 || true
done
# bump up installation tree
ln $RPM_BUILD_ROOT%{l_prefix}/bin/gcc \
$RPM_BUILD_ROOT%{l_prefix}/bin/cc
ln $RPM_BUILD_ROOT%{l_prefix}/man/man1/gcc.1 \
$RPM_BUILD_ROOT%{l_prefix}/man/man1/cc.1
%if "%{with_cxx}" == "yes"
ln $RPM_BUILD_ROOT%{l_prefix}/man/man1/g++.1 \
$RPM_BUILD_ROOT%{l_prefix}/man/man1/c++.1
%endif
# resolve filename conflicts
%if "%{with_gcc}" != "yes" && "%{V_comp}" != ""
( cd $RPM_BUILD_ROOT%{l_prefix}/bin
for file in *; do
mv ${file} ${file}%{V_comp}
done
) || exit $?
( cd $RPM_BUILD_ROOT%{l_prefix}/info
for file in *; do
mv ${file} `echo ${file} | sed -e 's;^\([^.]*\)\(\..*\)$;\1%{V_comp}\2;'`
done
) || exit $?
( cd $RPM_BUILD_ROOT%{l_prefix}/man/man1
for file in *; do
mv ${file} `echo ${file} | sed -e 's;^\([^.]*\)\(\..*\)$;\1%{V_comp}\2;'`
done
) || exit $?
%endif
# determine installation file list
%{l_rpmtool} files -v -ofiles -r$RPM_BUILD_ROOT %{l_files_std}
%files -f files
%clean
rm -rf $RPM_BUILD_ROOT
|
| <<< Previous | Home | Next >>> |
| Bootstrapping OpenPKG | Run Control |