Home

Compiling RPM on Solaris 9 Print E-mail
User Rating: / 2
PoorBest 
Last Updated: Thursday, 21 December 2006

1. Introduction
     1.1. Software dependencies
     1.2. Notational conventions
     1.3. Context
     1.4. Pre-requisite
     1.5. Environment
2. Building
     2.1. Creating the target structure
     2.2. Embedding a private libgcc library (4.1.1)
     2.3. Compiling libstdc++ (4.1.1)
     2.4. Compiling zlib (1.2.3)
     2.5. Compiling bzip2 (1.0.1)
     2.6. Compiling OpenSSL (0.9.7i)
     2.7. Compiling libiconv (1.9.2)
     2.8. Compiling beecrypt (4.1.2)
     2.9. Compiling expat (2.0.0)
     2.10. Compiling gettext (0.14.5)
     2.11. Compiling neon (0.26.1)
     2.12. Compiling ncurses (5.5)
     2.13. Compiling RPM (4.4.7-0.17)
     2.14. Creating the database
     2.15. Initializing the database
3. Checking
     3.1. TODO
     3.2. Checking the shared library dependencies
4. The end
5. Installing the package

Document history
V 1.0-3 OCT 2006 First release

1 - Introduction

As we did with Apache, the goal here is to build a package including every libraries it depends on (except system libraries). And everything must be located under a single directory tree.

:note The RPM tool we build here does not support the sqlite DB API. There is very few documentation on this API, it is written nowhere whether it is supposed to become the default DB format or not. Until all this is clear for me, I will keep the db3 format.

1.1 - Software dependencies

The following diagram displays the dependencies between the software packages and libraries we are integrating together.

Image

1.2 - Notational conventions

Everything written in red and between '<' and '>' characters must be manually adapted to your configuration.

Everything in black on grey can be copy/pasted as-is.

For instance :

dir=<$BASE>

means that you must replace the '<$BASE>' part with your base directory before typing the line, but :

dir=$BASE

must be entered as-is.

;

1.3 - Context

Host model : V 490
OS : Solaris 9 (64 bit, Generic_118558-06)
Date : Oct 2006
Shell : /bin/ksh (Kshell)
User : root (not mandatory)

1.4 - Pre-requisite

Product Version Source
gcc 3.4.2 http://www.sunfreeware.com
GNU make 3.80
GNU tar *

1.5 - Environment

First, we set the environment variables specific to our environment :

export BASE=<your install directory>

We ensure that the LIBPATH, LD_LIBRARY_PATH, and SHLIB_PATH variables are not set. Only one is used on this system but it is easier to unset them all on every OS :

unset LIBPATH LD_LIBRARY_PATH SHLIB_PATH \
    || echo dont care

If your shell defines alias commands for cp, rm, or mv, you must unalias them now :

unalias cp rm mv || echo dont care

Now, we set some variables that we use in the rest of the document. We ensure /usr/local/bin and /usr/ccs/bin are in the path. We also set CPPFLAGS :

export BLIB=$BASE/libs
export PKG_CONFIG_PATH="$BLIB/pkg_common"

export CC=gcc
export MAKE=gmake
export CF_OPTS="--enable-shared --disable-static"
export PATH="$PATH:/usr/local/bin:/usr/ccs/bin"

export CPPFLAGS="-I $BLIB/beecrypt/include \
    -I $BLIB/beecrypt/include/beecrypt -I $BLIB/neon/include/neon \
    -I $BLIB/dummy \
    -I $BLIB/expat/include"

export LDFLAGS="-L$BLIB/common -Wl,-R,$BLIB/common"

2 - Building

2.1 - Creating the target structure

[ -d $BLIB/common ] || mkdir -p $BLIB/common
[ -d $BLIB/pkg_common ] || mkdir -p $BLIB/pkg_common

Now, we create the script that we will use to create symbolic links from a common directory to every file in a lib directory. This way, we can keep only this directory in the dynamic lib search path (LDFLAGS). We also create links to the pkgconfig files.

export LINKDIR=/tmp/linkdir
echo 'cd $BLIB/$1
cdir=$2
[ -z "$2" ] && cdir=common

for i in *
    do
    if [ -f "$i" ] ; then
        echo "Linking $i"
        /bin/rm -rf $BLIB/$cdir/$i
        ln -s ../$1/$i $BLIB/$cdir/$i
    fi
done

[ -d pkgconfig ] && $LINKDIR $1/pkgconfig pkg_common
exit 0
' >$LINKDIR
chmod +x $LINKDIR

2.2 - Embedding a private libgcc library (4.1.1)

Some files we generate have a runtime dependency on the libgcc shared library file. This file belongs to gcc, which means that, by default, we should have libgcc installed on every runtime host ! Workaround : we include the libgcc shared library file in the final package, and we force the executable files to reference this copy :

mkdir -p $BLIB/gcc/lib
cp -p /usr/local/lib/libgcc_s.so* $BLIB/gcc/lib
$LINKDIR gcc/lib

:note If you don't have a shared gcc library on your system (as it happens with the gcc package from HP on HP-UX), the best solution is to rebuild gcc (gmake bootstrap builds the shared gcc lib we need).

2.3 - Compiling libstdc++ (4.1.1)

Source : http://gcc.gnu.org

Here, you have to download gcc-core and gcc-g++. Uncompress/untar them in the same directory. Note that you will need GNU tar to read the gcc-core source package.

:note If you get errors in this part, and if you use a pre-built gcc compiler, the first step is to rebuild your gcc compiler from the sources. Every time I used pre-built gcc binaries, I got errors when recompiling the libstdc++ library, and each time, rebuilding/reinstalling gcc from the sources solved the problem.

cd libstdc++-v3

#-- Work in a build sub-directory

mkdir build
cd build

#-- Configure, build, install

CXX='gcc' \
CPPFLAGS='' \
    ../configure --prefix=$BLIB/g++ $CF_OPTS

gmake
gmake install "INSTALL = $PWD/../../install-sh -c"
/bin/rm -rf $BLIB/g++/include

/bin/rm -rf $BLIB/g++/lib/sparcv9  #--- Remove 64-bit libraries

$LINKDIR g++/lib
cd ../..

2.4 - Compiling zlib (1.2.3)

Source : http://www.zlib.net/

./configure --shared --prefix=$BLIB/z

gmake "LDSHARED = gcc -shared $LDFLAGS"
gmake install

 #-- Cleanup

rm -rf $BLIB/z/share $BLIB/z/lib/*.a

$LINKDIR z/lib

2.5 - Compiling bzip2 (1.0.1)

Source : http://www.digistar.com/bzip2/

:note Here, we have to modify the makefile before compiling in order to remove some invalid options.

:note As the current makefile does not use our LDFLAGS settings, we must link the shared library with our own command.

:note We also must install the files manually as the Makefile is unable to do it.

#-- Modify the Makefile

sed 's/-Wl,-soname -Wl,libbz2.so.1.0//' <Makefile-libbz2_so >tmp1
cp tmp1 Makefile-libbz2_so

#-- Build

gmake -f Makefile-libbz2_so
gcc -shared -o libbz2.so.1.0.1 $LDFLAGS *.o

#-- Install

mkdir -p $BLIB/bz2/include $BLIB/bz2/lib
cp bzlib.h $BLIB/bz2/include
cp libbz2.so.1.0.1 $BLIB/bz2/lib/libbz2.so.1.0.1
ln -s libbz2.so.1.0.1 $BLIB/bz2/lib/libbz2.so.1.0
ln -s  libbz2.so.1.0 $BLIB/bz2/lib/libbz2.so.1
ln -s libbz2.so.1 $BLIB/bz2/lib/libbz2.so

$LINKDIR bz2/lib

2.6 - Compiling OpenSSL (0.9.7i)

Source : http://www.openssl.org/

./config --openssldir=$BLIB/ssl shared zlib

gmake "SHARED_LDFLAGS = -shared $LDFLAGS"
gmake install

#-- Cleanup

rm -rf $BLIB/ssl/bin/openssl $BLIB/ssl/man $BLIB/ssl/lib/*.a

$LINKDIR ssl/lib

2.7 - Compiling libiconv (1.9.2)

Source : http://www.gnu.org/software/libiconv/

./configure --prefix=$BLIB/iconv $CF_OPTS

gmake
gmake install

rm -rf $BLIB/iconv/bin $BLIB/iconv/share/doc \
    $BLIB/iconv/share/man $BLIB/iconv/lib/*.a

$LINKDIR iconv/lib

2.8 - Compiling beecrypt (4.1.2)

Source : http://sourceforge.net/projects/beecrypt

./configure --prefix=$BLIB/beecrypt \
    --without-java --without-python $CF_OPTS

gmake
gmake install

$LINKDIR beecrypt/lib

2.9 - Compiling expat (2.0.0)

Source : http://expat.sourceforge.net/

./configure --prefix=$BLIB/expat $CF_OPTS

gmake
gmake install

#-- Cleanup

rm -rf $BLIB/expat/bin $BLIB/expat/man

$LINKDIR expat/lib

2.10 - Compiling gettext (0.14.5)

Source : http://directory.fsf.org/gettext.html

./configure --prefix=$BLIB/gettext $CF_OPTS \
    --with-libiconv-prefix=$BLIB/iconv --with-libexpat-prefix=$BLIB/expat

gmake
gmake install

#-- Cleanup

rm -rf $BLIB/gettext/bin $BLIB/gettext/info $BLIB/gettext/share/info \
    $BLIB/gettext/share/man $BLIB/gettext/share/doc

$LINKDIR gettext/lib

2.11 - Compiling neon (0.26.1)

Source : http://www.webdav.org/neon/

./configure --prefix=$BLIB/neon $CF_OPTS\
    --with-zlib  --with-ssl=openssl --with-expat

gmake
gmake install

rm -rf $BLIB/neon/man $BLIB/neon/share/doc

$LINKDIR neon/lib

2.12 - Compiling ncurses (5.5)

Source : http://www.webdav.org/neon/

:note We must unset LDFLAGS here because ncurses uses the ld command for linking.

ldsave=$LDFLAGS
unset LDFLAGS

./configure --prefix=$BLIB/ncurses\
    --without-ada --without-debug --without-cxx \
    --without-cxx-binding --with-shared

gmake
gmake install

export LDFLAGS="$ldsave"

rm -rf $BLIB/ncurses/bin $BLIB/ncurses/lib/*.a \
    $BLIB/ncurses/man $BLIB/ncurses/share

$LINKDIR ncurses/lib

2.13 - Compiling RPM (4.4.7-0.17)

Source : http://wraptastic.org/pub/rpm-devel/

:note We must temporarily suppress the zlib symbolic links in $BLIB/common because rpm also contains a zlib package. We restore it afterwards.

/bin/rm -f $BLIB/common/libz.*

:note rpmio does not reference the neon library at link time although it depends on it. So, we add it to the linker options.

sed 's,^\(librpmio_la_LIBADD =\).*$,\1 $(BLIB)/neon/lib/libneon.la,' \
    <rpmio/Makefile.in >tmp1
cp tmp1 rpmio/Makefile.in

:note The system does not provide definitions for u_int32_t, u_int16_t, or u_int8_t. On Linux, the definitions are contained in a 'stdint.h' file. Workaround : We create a dummy 'stdint.h' file with the required definitions.

mkdir $BLIB/dummy
cat >$BLIB/dummy/stdint.h <<EOF
#ifndef __STDINT_H
#define __STDINT_H
typedef unsigned long u_int32_t;
typedef unsigned short u_int16_t;
typedef unsigned char u_int8_t;
#endif
EOF

:note The base Makefile contains a reference to librpmbuild.a. As we build only shared libraries, we have to modify this.

_src='\(LDADD = .*\)\$(top_builddir)/build/.libs/librpmbuild\.a'
_tgt='\1-L$(top_builddir)/build/.libs -lrpmbuild'
sed "s,$_src,$_tgt,g" <Makefile.in >tmp1
cp tmp1 Makefile.in

_src='\(rpm_DEPENDENCIES = .*\)librpmbuild\.a'
_tgt='\1librpmbuild.so'
sed "s,$_src,$_tgt,g" <Makefile.in >tmp1
cp tmp1 Makefile.in

Now, we can configure and build rpm.

:note I don't know exactly why but, when CPPFLAGS and LDFLAGS are set to non-empty values before calling configure, the parameters are not transmitted correctly to the db3 configure command and it fails. Workaround : before calling the global configure, we rename the db3 subdirectory, so that it is ignored. And then, we run a specific configure stage for db3 and we rename it back for the compile stage.

#-- Configure everything except db3

mv db3 db3.tmp    #-- Hide db3

CPPFLAGS="$CPPFLAGS -DHAVE_NEON_NE_GET_RESPONSE_HEADER \
  -DHAVE_BZ2_1_0 -DHAVE_BEECRYPT_API_H -DHAVE_INET_ATON" \
    ./configure --prefix=$BASE --with-libiconv-prefix=$BLIB/iconv \
    --without-selinux --without-python --without-perl \
    --with-libintl-prefix=$BLIB/gettext $CF_OPTS \
       2>&1  | tee configure.log

mv db3.tmp db3    #-- Restore db3

#-- Configure db3

cd db3
CPPFLAGS="$CPPFLAGS -fPIC" \
    ./configure --prefix=$BLIB/db3 --enable-compat185
cd ..

#-- Build and install

gmake "LDFLAGS = $LDFLAGS"
gmake install

ln -s ../lib $BLIB/rpm
$LINKDIR rpm

#-- Restore the zlib links

$LINKDIR z/lib

2.14 - Creating the database

$BASE/bin/rpm --initdb

2.15 - Initializing the database

Now, we populate the database with some software supposed to be present on any host :

cat >/tmp/t2 <<EOF
Summary: System dependencies
Name: sysdeps
Version: 1.0
Release: 1
Copyright: none
Group: System Environment/Libraries
Source: none
Provides: /bin/sh /bin/csh /bin/ksh /usr/bin/sh /usr/bin/csh /usr/bin/ksh
Provides: /sbin/sh /usr/bin/posix/sh
Provides: libc.sl libm.sl libcl.sl glibc
%description
Virtual package
%files
EOF

$BASE/bin/rpmbuild -bb /tmp/t2
$BASE/bin/rpm -i $BASE/src/rpm/RPMS/*/sysdeps-1.0-1.*.rpm
/bin/rm $BASE/src/rpm/RPMS/*/sysdeps-1.0-1.*.rpm /tmp/t2

3 - Checking

3.1 - TODO

3.2 - Checking the shared library dependencies

unset LIBPATH SHLIB_PATH LD_LIBRARY_PATH
cd $BASE
for i in `find . -type f` ; do
      ldd $i 2>/dev/null
done \
    | sed -e 's!^.*>[[:space:]]*/!/!' -e 's!\.so\.[0-9]$!!' \
    | sort -u \
    | grep -v "^$BASE/" \
    | grep -v '/usr/platform'

This script must display only the following system libraries :

  • /usr/lib/libaio
  • /usr/lib/libc
  • /usr/lib/libdl
  • /usr/lib/libm
  • /usr/lib/libmd5
  • /usr/lib/libmp
  • /usr/lib/libnsl
  • /usr/lib/libpthread
  • /usr/lib/libresolv
  • /usr/lib/librt
  • /usr/lib/libsocket
  • /usr/lib/libthread

4 - The end

Congratulations !

Now, you have a complete RPM software for Solaris in your $BASE directory. You can now tar and compress it to a package file.

5 - Installing the package

In order to install the package to a target host :

  • Uncompress and untar the package file on the target host in the same directory as the source host ($BASE)
  • Check the shared lib dependencies (see above)
  • Add $BASE/bin to your path (optional)
  • :love Enjoy !

Comments

Only registered users can write comments.
Please login or register.

Powered by AkoComment!


All site content is (C) F. Laupretre (wishlist) - Unauthorized reproduction forbidden without express written permission.
Joomla! is Free Software released under the GNU/GPL License. - Template design: JLM@joomlabox