Topic: ABI and packaging
Hi,
By ABI I mean Application Binary Interface, that is a consistent binary binding to a shared library that will not break across releases.
I have been having a look at the building of the shared library lbnfc.so* and how to deliver a consistent binary package so that end users can get the latest build but do not have to compile the binaries.
In order to meet these goals we need to avoid breaking existing binaries.
The API needs to freeze, or at least existing APIs need to continue to work but new APIs can be added for later revisions. For example, I have noticed that for each major release the nfc_initiator_select seems to change. Similarly structs must not change.
Exported entrypoints from shared libraries should be limited to only those explicitly wanted to be exposed and supported, so internal non-static functions should be hidden. With the GNU toolchain this can be done with -Wl,-retain-symbols-file,nfc.exp where nfc.exp is a file containing a simple list of the exported entry points. You can check the actual exports with
nm libnfc.so | grep " T "This currently shows many acr122_*, arygon_*,pn53x_* and mirror* functions that should be private.
I have put together a couple of scripts to build an RPM and a Debian style package.
Regards
snapdev
mkfs.sh - make an installed directory layout
#!/bin/sh -ex
if test -d root
then
chmod -R +w root
rm -rf root
fi
mkdir -p root/usr/local/lib root/usr/local/include/nfc
find .. -name libnfc.so | while read N
do
(
cd `dirname $N`
tar cf - libnfc.so*
) | (
cd root/usr/local/lib
tar xvf -
)
done
find .. -name nfc.h | while read N
do
(
cd `dirname $N`
tar cf - *.h
) | (
cd root/usr/local/include/nfc
tar xvf -
)
done
find root -type f | xargs chmod -w
find root | xargs ls -lddeb.sh - create a debian package
#!/bin/sh -ex
#
# dpkg -i libnfc*.deb
#
# dpkg -r libnfc*.deb
./mkfs.sh
GTAR=tar
VERSION=1.0
APPNAME=libnfc
rm -rf control
mkdir -p control
(
cd root
if test "$?" != 0
then
exit 1
fi
$GTAR --owner=0 --group=0 --create --file ../data.tar ./*
)
ARCH=`dpkg --print-architecture`
PACKAGE_NAME="$APPNAME"_"$VERSION"_"$ARCH".deb
(
cd control
if test "$?" != 0
then
exit 1
fi
cat >control <<EOF
Package: $APPNAME
Version: $VERSION
Architecture: $ARCH
Maintainer: romuald@libnfc.org
Recommends:
Conflicts: $APPNAME
Provides: $APPNAME
Section: misc
Priority: extra
Description: libnfc
Near Field Communication Library
.
EOF
cat >preinst <<EOF
#!/bin/sh -e
EOF
cat >prerm <<EOF
#!/bin/sh -e
EOF
cat >postrm <<EOF
#!/bin/sh
EOF
cat >postinst <<EOF
#!/bin/sh
EOF
chmod +x preinst prerm postinst postrm
if test "$?" != 0
then
exit 1
fi
$GTAR --owner=0 --group=0 --create --file ../control.tar ./*
)
for d in control data
do
gzip $d.tar
done
if test "$?" != 0
then
exit 1
fi
find root -type f | xargs chmod +w
rm -rf "$PACKAGE_NAME"
echo "2.0" >debian-binary
ar r "$PACKAGE_NAME" debian-binary data.tar.gz control.tar.gz
rm -rf data data.tar.gz control control.tar.gz debian-binary root
if test "$?" != 0
then
exit 1
firpm.sh - build an RPM
#!/bin/sh -ex
# to install
# rpm -i libnfc.rpm
# to remove
# rpm -e libnfc
RPMBUILD=rpm
VERSION=1.0
if rpmbuild --help >/dev/null
then
RPMBUILD=rpmbuild
fi
if $RPMBUILD --help >/dev/null
then
echo RPMBUILD=$RPMBUILD
else
exit 0
fi
./mkfs.sh
BUILDROOT=`pwd`/root
TGTPATH=rpms
SPECFILE=rpm.spec
cat >"$SPECFILE" <<EOF
Summary: libnfc
Name: libnfc
Version: $VERSION
Release: 1
Group: Applications/System
License: LGPL
Prefix: /usr/local
%description
Near Field Communications Library
%files
%defattr(-,root,root)
/usr/local/lib/libnfc.so
/usr/local/lib/libnfc.so.1
%attr(555,root,root) /usr/local/lib/libnfc.so.1.0.0
%attr(555,root,root) /usr/local/include/nfc/nfc.h
%attr(555,root,root) /usr/local/include/nfc/nfc-types.h
%attr(555,root,root) /usr/local/include/nfc/nfc-messages.h
EOF
rm -rf $TGTPATH
mkdir -p $TGTPATH
$RPMBUILD --buildroot "$BUILDROOT" --define "_rpmdir $TGTPATH" -bb "$SPECFILE"
find "$TGTPATH" -name "*.rpm" | while read N
do
mv "$N" .
done
find "$BUILDROOT" -type f | xargs chmod +w
rm -rf "$SPECFILE" "$TGTPATH" "$BUILDROOT"