Last time around we talked about the openSUSE Build System (OBS), how it can build packages for a range of Linux distributions from openSUSE, Fedora, Ubuntu, Mandriva, through to the enterprise offerings SUSE Linux Enterprise Desktop (SLED) and Red Hat Enterprise. This time we'll get our hands dirty by rolling a package for siproxd version 0.7.1.
I'll create a network subproject inside my OBS account (home:monkeyiq) so that I can possibly roll packages for other network related tools as well.
These actions can be performed using either the web interface or the osc command line tool. I prefer to setup the project to a degree with the web interface and then check out a copy to my local machine in order to modify and commit using the standard osc update/commit command line options. This way things like subproject creation and repository setup can be handled using the graphic interface without needing to learn much about OBS in order to start packaging something.
The first step is to add the repositories for the Linux distributions, architectures and versions that are of interest. For this article I'll add Fedora versions 10 and 11 along with openSUSE 11.1, and Xubuntu 9.04. This gives a few RPM-based options and also the ability to build DEB files for the latest Ubuntu distribution.
The siproxd requires the libosip2 package. Fedora 11 already packages libosip2 but other distributions and versions might not. Since I am planning to package siproxd, I'll have to allow for this dependency as well.
The "Add Package" page asks for a name, title and description for the package and allows you to then setup where the sources are coming from, the spec file and the files required to build on deb packages. As I mentioned above, I'll create the siproxd package inside my network subproject.
To get sources into OBS for a package you can either add a file from your desktop machine or paste in the URL of the sources and OBS will fetch them for you. For siproxd I brought in the sources directly from the SourceForge.net "direct link" download URL.
Once you bring in the tar.gz file, OBS will report the Build Status for all your distributions as "broken" with a description of "no spec/dsc/kiwi file." In the past, OBS would inspect the tarball and try to find a spec file inside it to start building. I'm not sure why this didn't happen when I was writing this, but it used to be very handy when projects included working spec files in their tarballs.
Downloading the siproxd tarball, extracting it, and then uploading the spec file from the desktop machine got the build going. Soon after the spec file was uploaded the status for Fedora and openSUSE became "scheduled." The OBS includes a farm of machines which are used to complete build tasks. Sometimes there is enough build work that queues can form for those machines, so your build might sit in "scheduled" for a little while awaiting a free machine. If I had to mention a downside to OBS, this would be it, nobody likes to wait in queues right? The flip side of this is that you are taking advantage of the OBS machines free of charge to build your packages, which could be quite computationally intensive.
The Fedora build then failed with the following message. Whoops, looks like the gcc compiler is not being detected properly. Wait, we didn't specify that we needed the gcc C++ compiler in our BuildRequires line. Looking over the build log, gcc is being installed but not the gcc-c++ package.
checking whether we are using the GNU C++ compiler... no checking whether g++ accepts -g... no checking dependency style of g++... none checking how to run the C++ preprocessor... /lib/cpp configure: error: C++ preprocessor "/lib/cpp" fails sanity check See `config.log' for more details. error: Bad exit status from /var/tmp/rpm-tmp.XPTMTZ (%build) RPM build errors: Bad exit status from /var/tmp/rpm-tmp.XPTMTZ (%build) System halted.
Add the following to the spec file and we are on our way again. Since pkgconfig is used by many configure scripts, I normally just add it in as a build dependency to avoid any more head scratching "why did that fail" messages.
BuildRequires: gcc-c++ pkgconfig
Once you save the above BuildRequires line to the spec file, OBS will again attempt to build an RPM for all the distributions you have chosen. You might then see the error shown below for the Fedora 11 build. This is caused by the spec file having a line "BuildRequires: libosip2 >= 3.0.0" whereas what we really want is the BuildRequires to specify the libosip2-devel package in order to build.
checking for cc_r... gcc checking "libosip prefix"... checking for osip_init in -losip2... no *** ERROR: libosip2 is required! Maybe you need to use --with-libosip-prefix ? error: Bad exit status from /var/tmp/rpm-tmp.fKZrwj (%build)
At this stage I could continue to use the web interface to edit the spec file. But everybody has their favourite text editor installed and would much rather use that to edit spec files. The commands shown below will check out a copy of the siproxd package from OBS. Once we have to local spec file, changing the BuildRequires line to have be libosip2-devel should get the build going to the next step. Once the osc commit command is issued, the changes are committed to OBS and a build should automatically be triggered. Not only that, but if a package depended on siproxd then it would be triggered for a rebuild as well. With OBS you shouldn't have to do any manual triggering of a build.
$ mkdir -p ~/obs-checkout $ cd ~/obs-checkout $ osc checkout home:monkeyiq:network $ cd home:monkeyiq:network/Siproxd/ $ emacs siproxd.spec ... Requires: libosip2 >= 3.0.0 BuildRequires: libosip2-devel >= 3.0.0 BuildRequires: gcc-c++ pkgconfig ... $ osc commit
With the above changes in place, the build should continue and build all of the source files. Unfortunately we're not quite done yet and we get the following error. The spec file assumes that the system used to build siproxd will have docbook2html and docbook2pdf installed and so lists generated files in %files which require these programs to be installed during the build. Spec files might not have these tools listed as BuildRequires targets because most normal desktop systems will have them preinstalled. For OBS you have to either remove the pdf and html documentation from the package file listing or add explicit BuildRequires to install the packages needed to generate the documentation.
+ cp -pr COPYING README AUTHORS INSTALL ... + cp -pr 'doc/html/*' 'doc/pdf/*' /home/abuild/rpmbuild/BUILDROOT/siproxd-0.7.1-3.1.i386/usr/share/doc/siproxd-0.7.1 cp: cannot stat `doc/html/*': No such file or directory cp: cannot stat `doc/pdf/*': No such file or directory error: Bad exit status from /var/tmp/rpm-tmp.G3RrAD (%doc)
The files needed to generate the documentation are contained in the packages docbook-utils and docbook-utils-pdf for Fedora. The following line needs to be added to the spec file.
BuildRequires: docbook-utils docbook-utils-pdf
At one stage, when I commited the updated spec file above including these docbook build dependencies I got an error from OBS itself--"have choice for text-www-browser needed by docbook-utils: lynx elinks w3m." This error relates to the aforementioned package name mappings that OBS maintains. In this case, OBS can resolve a package dependency in many ways and so puts up an error rather than making an arbitrary choice. Once again the OBS mailing list can be used to add new default package choices to the repository metadata. Another solution is to explicitly force the package selection by adding "BuildRequires: lynx" to the spec file. OBS as at July 2009 already had a correct resolution for this issue. I mention it in case you get the error with other package names.
At this point, both the Fedora 10 and 11 i386 builds succeed with something like the below shown at the end of the build log. Congratulations, you have built your first packages using the OBS.
+ cd /home/abuild/rpmbuild/BUILD + cd siproxd-0.7.1 + rm -rf /home/abuild/rpmbuild/BUILDROOT/siproxd-0.7.1-4.1.i386 + exit 0 ... checking for files with abuild user/group ... saving built packages /home/abuild/rpmbuild/RPMS/i386/siproxd-0.7.1-4.1.i386.rpm /home/abuild/rpmbuild/SRPMS/siproxd-0.7.1-4.1.src.rpm build21 finished "build siproxd.spec" at Fri Jul 10 06:20:57 UTC 2009. System halted. build: extracting built packages... siproxd-0.7.1-4.1.i386.rpm siproxd-0.7.1-4.1.src.rpm
Unfortunately, the 64-bit Fedora 10 and 11 builds fail with the error message shown below.
RPM build errors: File not found: /home/abuild/rpmbuild/BUILDROOT/siproxd-0.7.1-5.1.x86_64/usr/lib64/siproxd System halted.
This is because the build is using the /usr/lib path when it should be using /usr/lib64 if it is building on a 64-bit machine. To get around this you can change the spec file to use _libdir during configure and make install as shown below.
...
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} \
--sysconfdir=%{sysconfdir} \
--libdir=%{_libdir}
make
...
make prefix=$RPM_BUILD_ROOT%{prefix} \
sysconfdir=$RPM_BUILD_ROOT%{sysconfdir} \
libdir=$RPM_BUILD_ROOT%{_libdir} \
install
...
Unfortunately the openSUSE build is still failing for both 32- and 64-bit with "openSUSE error: nothing provides docbook-utils-pdf." The docbook2pdf command which is in the docbook-utils-pdf package in Fedora is actually in the docbook-utils package in openSUSE. So we do not need the docbook-utils-pdf build dependency on openSUSE. We could chime in on the OBS mailing list here, trying to get docbook-utils-pdf to map simply to docbook-utils so our spec file would work on both. But in the short term, the distribution-specific section below gets us building again.
%if 0%{?suse_version}
BuildRequires: docbook-utils
%else
BuildRequires: docbook-utils docbook-utils-pdf
%endif
Now we almost seem to be winning with the openSUSE packages but get the following error message.
+ /usr/lib/rpm/brp-boot-scripts E: File `siproxd' without LSB header found in /var/tmp/siproxd-0.7.1-root/etc/init.d/ ERROR: found one or more broken init or boot scripts, please fix them. For more information about LSB headers please read the manual page of of insserv by executing the command `man 8 insserv'. If you don't understand this, mailto=werner@suse.de error: Bad exit status from /var/tmp/rpm-tmp.57531 (%install) RPM build errors: cannot open Pubkeys index using db3 - No such file or directory (2) Bad exit status from /var/tmp/rpm-tmp.57531 (%install) System halted.
This is because the init.d file in the siproxd is not Linux Standard Base conformant. This can be fixed by adding a patch including the BEGIN INIT INFO section as shown below.
diff -Nuar siproxd-0.7.1/contrib/siproxd.init siproxd-0.7.1.me/contrib/siproxd.init --- siproxd-0.7.1/contrib/siproxd.init 2004-10-10 02:38:37.000000000 +1000 +++ siproxd-0.7.1.me/contrib/siproxd.init 2009-07-10 17:53:53.000000000 +1000 @@ -8,7 +8,15 @@ # # description: Listen and dispatch SIP messages # processname: siproxd - +### BEGIN INIT INFO +# Provides: siproxd +# Required-Start: $network $syslog +# Required-Stop: $network $syslog +# Default-Start: 3 5 +# Default-Stop: 0 1 6 +# Short-Description: Listen and dispatch SIP messages +# Description: Listen and dispatch SIP messages +### END INIT INFO # Source function library. . /etc/rc.d/init.d/functions
This can be applied from the spec file in the normal way.
...
Source0: %{name}-%{ver}.tar.gz
Patch0: siproxd-lsb.patch
...
%prep
%setup -q
%patch0 -p1
Unfortunately, the above patch is not all that is needed for insserv to be happy as shown by the subsequent error message.
... installing all built rpms
Preparing packages for installation...
siproxd-0.7.1-11.1
Edit the config file %{sysconfigdir}/siproxd.conf!
insserv: Service network has to be enabled to start service siproxd
insserv: Service syslog has to be enabled to start service siproxd
insserv: exiting now!
/sbin/insserv failed, exit code 1
siproxd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
error: %post(siproxd-0.7.1-11.1.x86_64) scriptlet failed, exit status 1
failed to install rpms, aborting build
System halted.
So clearly there is still a little bit of work that needs to be done in order for insserv to be happy with the package. I'll leave this as an exercise for the reader as many packages will not be for system daemons and thus not run afoul of insserv. It should be noted that the build log shows that the siproxd-0.7.1-11.1.x86_64.rpm package was created for openSUSE, it just had trouble being installed because of insserv.
Tune in next time around when we'll take a look at creating DEB files for Ubuntu using OBS.

