You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
438 lines
12 KiB
438 lines
12 KiB
#!/bin/sh |
|
## |
|
## openpkg.boot -- OpenPKG bootstrap procedure (look Ma, without hands ;) |
|
## Copyright (c) 2000-2001 Cable & Wireless Deutschland GmbH |
|
## Copyright (c) 2000-2001 Ralf S. Engelschall <rse@engelschall.com> |
|
## |
|
|
|
# This is a very tricky procedure for building the OpenPKG bootstrap |
|
# package via the RPM specification openpkg.spec, but without |
|
# requiring that OpenPKG's RPM already exists. For this the |
|
# openpkg.spec file is manually executed here in order to build |
|
# OpenPKG RPM the first time (that is, we emulate a sufficient |
|
# subset of the RPM functionality), followed by a second round over |
|
# openpkg.spec with the real (and then existing) OpenPKG RPM tool. |
|
# Also keep in mind that lots of tricks are played here in order to |
|
# perform all the steps without having to touch the real installation |
|
# location. That is the whole procedure can (and should) be performed |
|
# by a non-priviledged user and no access to the real installation |
|
# location filesystem location. |
|
|
|
## |
|
## command line handling |
|
## |
|
|
|
if [ $# -lt 1 -o $# -gt 3 ]; then |
|
echo "Usage: $0 <prefix> [<user> [<group>]]" 1>&2 |
|
exit 1 |
|
fi |
|
root="$1" |
|
fsusr="$2" |
|
fsgrp="$3" |
|
|
|
## |
|
## determine package information |
|
## |
|
|
|
name="openpkg" |
|
spec="$name.spec" |
|
version=`grep V_openpkg $spec | head -1 | awk '{ printf("%s", $3); }'` |
|
release=`grep R_openpkg $spec | head -1 | awk '{ printf("%s", $3); }'` |
|
|
|
## |
|
## special argument processing |
|
## |
|
|
|
if [ ".$root" = ".-s" ]; then |
|
srcdir=. |
|
if [ -d ../../DST ]; then |
|
dstdir=../../DST/openpkg |
|
else |
|
dstdir=. |
|
fi |
|
tmpdir="/tmp/openpkg.boot.$$" |
|
if [ -d ../PKG ]; then |
|
pkgdir=../PKG |
|
elif [ -d ../../PKG ]; then |
|
pkgdir=../../PKG |
|
elif [ -d ../../ftp/current/SRC ]; then |
|
pkgdir=../../ftp/current/SRC |
|
else |
|
pkgdir=.. |
|
fi |
|
echo "Rolling source bootstrap package: $pkgdir/$name-$version-$release.src.sh" |
|
rm -rf $tmpdir |
|
mkdir $tmpdir |
|
(cd $dstdir && tar cf - *) | (cd $tmpdir && tar xf -) |
|
(cd $srcdir && tar cf - *) | (cd $tmpdir && tar xf -) |
|
sed <$srcdir/wrap1.sh >$pkgdir/$name-$version-$release.src.sh \ |
|
-e "s;@DIR@;$name-$version-$release.src;" -e "s;@TGZ@;$name-$version-$release.src.tar.Z;" |
|
(cd $tmpdir && tar cf - *) | compress |\ |
|
uuencode $name-$version-$release.src.tar.Z \ |
|
>>$pkgdir/$name-$version-$release.src.sh |
|
exit 0 |
|
fi |
|
|
|
## |
|
## calculate location id |
|
## |
|
|
|
if [ ".`expr $root : '/[^/][^/]*$'`" != .0 ]; then |
|
loc=`echo $root | cut -c2-4` |
|
else |
|
loc=`echo $root | sed -e 's;/\(.\)[^/]*;\1;g' | cut -c1-3` |
|
fi |
|
|
|
## |
|
## determine distribution directory (developers only) |
|
## |
|
|
|
V_rpm=`grep V_rpm $spec | head -1 | awk '{ printf("%s", $3); }'` |
|
if [ -f "../../DST/openpkg/rpm-${V_rpm}.tar.gz" ]; then |
|
distdir="`cd ../../DST/openpkg; pwd`" |
|
else |
|
distdir="`pwd`" |
|
fi |
|
|
|
## |
|
## make sure the underlying platform is a supported one |
|
## |
|
|
|
sh ./shtool echo -e "%BOpenPKG Bootstrap Procedure%b" |
|
platform=`sh ./shtool guessos` |
|
support=no |
|
case $platform in |
|
*-solaris* ) |
|
support=maybe |
|
case $platform in |
|
*-solaris2.[678] ) |
|
support=yes |
|
;; |
|
esac |
|
;; |
|
*-linux* ) |
|
support=maybe |
|
if [ -f /etc/debian_version ]; then |
|
debian=`cat /etc/debian_version` |
|
if [ ".$debian" = ".2.2" ]; then |
|
support=yes |
|
fi |
|
fi |
|
;; |
|
*-freebsd* ) |
|
support=maybe |
|
case $platform in |
|
*-freebsd4.[1234] ) |
|
support=yes |
|
;; |
|
esac |
|
;; |
|
*-netbsd* ) |
|
support=maybe |
|
case $platform in |
|
*-netbsd1.5* ) |
|
support=yes |
|
;; |
|
esac |
|
;; |
|
*-osf* ) |
|
support=maybe |
|
case $platform in |
|
*-osf5.[01] ) |
|
support=yes |
|
;; |
|
esac |
|
;; |
|
*-hpux* ) |
|
support=maybe |
|
case $platform in |
|
*-hpux10.20 ) |
|
support=yes |
|
;; |
|
esac |
|
;; |
|
esac |
|
case $support in |
|
yes ) support="Congratulations: fully supported" ;; |
|
maybe ) support="Good luck: still supported in general, but may break!" ;; |
|
no ) support="Sorry: entirely unsupported!" ;; |
|
esac |
|
sh ./shtool echo -e "Platform: %B$platform%b ($support)" |
|
case $support in |
|
no ) exit 1 ;; |
|
esac |
|
|
|
## |
|
## find reasonable run-time paths and tools |
|
## |
|
|
|
# find reasonable temporary directory |
|
tmpdir="/tmp" |
|
test ".$TMPDIR" != . && tmpdir="$TMPDIR" |
|
test ".$TEMPDIR" != . && tmpdir="$TEMPDIR" |
|
|
|
# find reasonable safe program path |
|
test ".$PATH" = . && PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin" |
|
for dir in /usr/ccs/bin /usr/xpg4/bin; do |
|
test -d $dir && PATH="$PATH:$dir" |
|
done |
|
export PATH |
|
|
|
# find reasonable TAR |
|
l_tar='' |
|
for t in gtar tar; do |
|
for p in `IFS=":"; echo . $PATH`; do |
|
if [ -f "$p/$t" ]; then |
|
l_tar="$p/$t" |
|
break |
|
fi |
|
done |
|
[ ".$l_tar" != . ] && break |
|
done |
|
if [ ".$l_tar" = . ]; then |
|
echo "$0:FAILED: required TAR not found" |
|
exit 1 |
|
fi |
|
|
|
# find required Make tool |
|
l_make='' |
|
for t in gmake make; do |
|
for p in `IFS=":"; echo . $PATH`; do |
|
if [ -f "$p/$t" ]; then |
|
l_make="$p/$t" |
|
break |
|
fi |
|
done |
|
[ ".$l_make" != . ] && break |
|
done |
|
if [ ".$l_make" = . ]; then |
|
echo "$0:FAILED: required Make tool not found" |
|
exit 1 |
|
fi |
|
|
|
# find required [GNU] C Compiler |
|
l_cc='' |
|
for t in egcc ggcc gcc cc; do |
|
for p in `IFS=":"; echo . $PATH`; do |
|
if [ -f "$p/$t" ]; then |
|
# if [ ".`$p/$t --version 2>/dev/null | grep '[23]\.[789]'`" != . ]; then |
|
l_cc="$p/$t" |
|
break |
|
# fi |
|
fi |
|
done |
|
[ ".$l_cc" != . ] && break |
|
done |
|
if [ ".$l_cc" = . ]; then |
|
echo "$0:FAILED: required [GNU] C/C++ compiler not found" |
|
exit 1 |
|
fi |
|
|
|
## |
|
## execute the spec file manually by emulating |
|
## the behaviour of the OpenPKG RPM tool. |
|
## |
|
|
|
# create script prolog |
|
prolog="$tmpdir/openpkg.boot.prolog.sh" |
|
cp /dev/null $prolog |
|
( |
|
echo "_specdir=`pwd`" |
|
echo "_sourcedir=$distdir" |
|
echo "_tmppath=$tmpdir" |
|
echo "_builddir=$tmpdir" |
|
echo "l_prefix=$root" |
|
echo "l_location=$loc" |
|
echo "l_buildroot=$tmpdir/$name-$version-root" |
|
echo "l_fsusr=$fsusr" |
|
echo "l_fsgrp=$fsgrp" |
|
echo "l_tar=$l_tar" |
|
echo "l_make=$l_make" |
|
echo "l_cc=$l_cc" |
|
grep '%define' $spec | \ |
|
sed \ |
|
-e 's:^%define *\([^ ]*\) *\(.*\):\1="\2":' |
|
grep "^[A-Za-z0-9]*: *" $spec | \ |
|
sed \ |
|
-e 's;^\([A-Za-z0-9]*\): *\(.*\)$;\1="\2";' \ |
|
-e 's;^A;a;' -e 's;^B;b;' -e 's;^C;c;' -e 's;^D;d;' -e 's;^E;e;' \ |
|
-e 's;^F;f;' -e 's;^G;g;' -e 's;^H;h;' -e 's;^I;i;' -e 's;^J;j;' \ |
|
-e 's;^K;k;' -e 's;^L;l;' -e 's;^M;m;' -e 's;^N;n;' -e 's;^O;o;' \ |
|
-e 's;^P;p;' -e 's;^Q;q;' -e 's;^R;r;' -e 's;^S;s;' -e 's;^T;t;' \ |
|
-e 's;^U;u;' -e 's;^V;v;' -e 's;^W;w;' -e 's;^X;x;' -e 's;^Y;y;' \ |
|
-e 's;^Z;z;' -e 's;^buildRoot;buildroot;' |
|
echo "RPM_BUILD_ROOT=\"%{buildroot}\"" |
|
echo "RPM_BUILD_DIR=\"%{_builddir}\"" |
|
echo "RPM_SOURCE_DIR=\"$distdir\"" |
|
echo "export RPM_BUILD_ROOT" |
|
echo "export RPM_BUILD_DIR" |
|
echo "export RPM_SOURCE_DIR" |
|
echo "set -x" |
|
echo "umask 022" |
|
echo "cd \$RPM_BUILD_DIR" |
|
) | sed -e 's;%{\([^}]*\)};${\1};g' >$prolog |
|
|
|
# install package via RPM spec file by faking a |
|
# sufficiently enough RPM run-time environment |
|
runscript () { |
|
step=$1 |
|
script="$tmpdir/openpkg.boot.$step.sh" |
|
echo ". $prolog" >$script |
|
sed -e "/^%$step/,/^%/ p" -e 'd' <$spec | \ |
|
sed -e '/^%/d' | \ |
|
sed -e 's;%{SOURCE \([^ ]*\.tar[^ ]*\)};${RPM_DIST_DIR}/\1;g' \ |
|
-e 's;%{SOURCE \([^ ]*\)};${RPM_SOURCE_DIR}/\1;g' | \ |
|
sed -e 's;%{[?]\([^:]*\):\([^}]*\)};${\1+\2};g' \ |
|
-e 's;%{![?]\([^:]*\):\([^}]*\)};${\1-\2};g' \ |
|
-e 's;%{\([^}]*\)};${\1};g' >>$script |
|
echo "Executing(%$step): sh $script" |
|
sh $script |
|
if [ $? -ne 0 ]; then |
|
rm -f $script |
|
echo "$0:ERROR: script returned non-null value" |
|
exit 1 |
|
fi |
|
rm -f $script |
|
} |
|
runscript prep |
|
runscript build |
|
runscript install |
|
|
|
## |
|
## adjust build environment so that the installed |
|
## "rpm" is actually useable, although it still resides in |
|
## the temporary location instead of the real location. |
|
## |
|
|
|
# suck in prolog in order to get variables from the spec file |
|
cwd=`pwd` |
|
. $prolog |
|
cd $cwd |
|
|
|
# suck in buildenv script in order to get fsusr/fsgrp |
|
# ???XXX??? |
|
. $tmpdir/openpkg-*/.buildenv |
|
|
|
# create a custom "rpm" command |
|
rm -f $tmpdir/rpm >/dev/null 2>&1 |
|
rmdir $tmpdir/rpm >/dev/null 2>&1 |
|
if [ -d "$tmpdir/rpm" ]; then |
|
echo "$0:ERROR: directory $tmpdir/rpm exists, cannot create file with same name" |
|
exit 1 |
|
fi |
|
if [ -f "$tmpdir/rpm" ]; then |
|
echo "$0:ERROR: file $tmpdir/rpm exists, cannot override" |
|
exit 1 |
|
fi |
|
echo "#!/bin/sh" >$tmpdir/rpm |
|
echo "exec $RPM_BUILD_ROOT$prefix/lib/rpm/rpm --rcfile $tmpdir/rpm.1 \"\$@\"" >>$tmpdir/rpm |
|
chmod a+x $tmpdir/rpm |
|
|
|
# direct our own "rpm" tool to adjusted macro sets |
|
sed <`SOURCE rpmrc` >$tmpdir/rpm.1 \ |
|
-e "s;^\\(macrofiles:\\) .*;\\1 $tmpdir/rpm.2:$tmpdir/rpm.3;" |
|
|
|
# use an adjusted vendor macro set |
|
sed <$RPM_BUILD_ROOT$prefix/lib/rpm/macros >$tmpdir/rpm.2 \ |
|
-e "s;$prefix;$RPM_BUILD_ROOT$prefix;g" |
|
|
|
# override the vendor macro set |
|
sed <`SOURCE rpmmacros` >$tmpdir/rpm.3 \ |
|
-e "s;@FSUSR@;$fsusr;" \ |
|
-e "s;@FSGRP@;$fsgrp;" \ |
|
-e "s;@LOC@;$loc;" \ |
|
-e "s;^\\(%l_root_install *\\)@l_prefix@;\\1 $prefix;" \ |
|
-e "s;^\\(%l_root_rpm *\\)@l_prefix@;\\1 $RPM_BUILD_ROOT$prefix;" \ |
|
-e "s;^\\(%_sourcedir *\\).*;\\1 $distdir;" \ |
|
-e "s;^\\(%_specdir *\\).*;\\1 $RPM_SOURCE_DIR;" \ |
|
-e "s;^\\(%_builddir *\\).*;\\1 $tmpdir;" \ |
|
-e "s;^\\(%_tmppath *\\).*;\\1 $tmpdir;" \ |
|
-e "s;^\\(%_buildshell *\\).*;\\1 /bin/sh;" |
|
|
|
# use an own $HOME/.popt in order to make sure the "rpm" |
|
# tool is able to execute its sub-tools "rpm<x>". |
|
V_rpm=`grep V_rpm $spec | head -1 | awk '{ printf("%s", $3); }'` |
|
sed <$RPM_BUILD_ROOT$prefix/lib/rpm/rpmpopt-${V_rpm} >$tmpdir/.popt \ |
|
-e "s;^\\(rpm.*exec.*\\)\\(rpm[bdeukv]*\\);\\1$RPM_BUILD_ROOT$prefix/lib/rpm/\\2;" |
|
|
|
# activate the .popt file |
|
HOME=$tmpdir |
|
export HOME |
|
|
|
## |
|
## now initialize the RPM database under the temporary install location |
|
## |
|
|
|
$tmpdir/rpm --initdb |
|
|
|
## |
|
## now turn over and re-iterate over the RPM spec, but this time |
|
## with the real RPM tool. |
|
## |
|
|
|
OPENPKG_BOOT=1 |
|
export OPENPKG_BOOT |
|
$tmpdir/rpm -bb $spec |
|
|
|
## |
|
## and finally overwrite the installation again, but this time by |
|
## installing officially through the "rpm" tool. This way we achieve |
|
## that RPM is remembered as an RPM package in its own database. We |
|
## just have to make sure the package is relocated while installing. |
|
## For this we could use --prefix=$RPM_BUILD_ROOT$prefix, but this |
|
## would create an incorrect filelist for "rpm" in the database. |
|
## Instead we use the --justdb option which means "rpm" behaves as it |
|
## would install into the real location, but does not actually install |
|
## anything. But as a side-effect, the database is now correct. |
|
## |
|
|
|
$tmpdir/rpm -Uvh --force --noscripts --justdb --ignoresize \ |
|
$RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-*.rpm |
|
|
|
## Puhhhh!!! what a tricky bootstrapping procedure. But now we are |
|
## mostly finished. All we finally have to do is to roll a bootstrap |
|
## tarball in addition to the binary RPM and save the stuff in a |
|
## permanent location. |
|
|
|
v="$version-$release" |
|
t="`$tmpdir/rpm --eval '%{_target}'`-$loc" |
|
|
|
# find a reasonable destination directory for packages |
|
if [ -d $RPM_SOURCE_DIR/../PKG ]; then |
|
dstdir=$RPM_SOURCE_DIR/../PKG |
|
elif [ -d $RPM_SOURCE_DIR/../../PKG ]; then |
|
dstdir=$RPM_SOURCE_DIR/../../PKG |
|
else |
|
dstdir=$RPM_SOURCE_DIR/.. |
|
fi |
|
|
|
# create Source-RPM file |
|
$tmpdir/rpm -bs --nodeps $RPM_SOURCE_DIR/$spec |
|
cp $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.src.rpm $dstdir/ |
|
rm -f $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.src.rpm |
|
|
|
# create Binary-RPM file |
|
cp $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.$t.rpm $dstdir/ |
|
rm -f $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.$t.rpm |
|
|
|
# create Binary-Bootstrap file |
|
cat $spec | sed -e "/^%pre$/,/^%/ p" -e 'd' | sed -e '/^%/d' -e 's/^ //' >$tmpdir/rpm.pre |
|
sed <`SOURCE wrap2.sh` \ |
|
-e "s;@FSUSR@;$fsusr;" -e "s;@FSGRP@;$fsgrp;" \ |
|
-e "s;@l_prefix@;$prefix;" -e "s;@TGZ@;openpkg-$v.$t.tar.Z;" \ |
|
-e "/^@PRE@/r $tmpdir/rpm.pre" |\ |
|
sed -e '/^@PRE@/d' >$dstdir/openpkg-$v.$t.sh |
|
(cd $RPM_BUILD_ROOT$prefix; tar cf - .[a-zA-Z]* *) |\ |
|
compress | uuencode openpkg-$v.$t.tar.Z >>$dstdir/openpkg-$v.$t.sh |
|
|
|
# cleanup |
|
rm -rf $RPM_BUILD_ROOT |
|
rm -rf $tmpdir/$name-$version |
|
rm -f $tmpdir/rpm $tmpdir/rpm.[123] $tmpdir/.popt $tmpdir/rpm.pre |
|
rm -f $prolog |
|
|
|
# final hint about results |
|
set +x |
|
echo "Resulting files (placed into $dstdir):" |
|
(cd $dstdir; ls -l openpkg-$v.$t.sh openpkg-$v.$t.rpm openpkg-$v.src.rpm) |
|
|
|
|