AutoTools, tar and paths longer than 99 characters

I tried to build a Debian package for the project I am currently working on. Unfortunately all the paths I used in the structure of my application were very long. While executing make dist command I got lots of errors similar to the one below:

wzt-poc2/media-server/src/[....]wzt-children-manager/tests/: file name is too long (max > 99); not dumped

I found out that the error is due to the tar archiver. It does not support file names (in fact “paths”) longer than 99 characters. This problem can be easily solved by forcing AutoTools to use POSIX version of tar which does not have this limitation.

It is enough to modify a configure.ac file in the following way:

AC_INIT([your-application-name], [0.1.0])
....
AM_INIT_AUTOMAKE([1.9 tar-ustar])

The crucial part is inside the AM_INIT_AUTOMAKE declaration which changes the default tar archiver.

Making Debian library package with dh_make

This post is a short introduction to building *.deb packages using dh_make & dpkg_buildpackage tools.

Let us assume that we want to make a Debian package for a simple library. We are going to create two *.deb files, due to the fact that in Debian-based operating systems, libraries are usually distributed in one of the two forms:

  • dev package – containing both library binaries and header files for programmers. Used mainly by the developers.
  • standard package – storing only the library binaries

Having that in mind, we should start our work from downloading necessary utilities:

apt-get install dpkg-dev dh-make debhelper devscripts pbuilder fakeroot

Next step is to set a proper name for the directory containing the source code of the library.
It should have the following pattern: <package>-<version> ( ex. mylib-0.1.0 )
Inside that directory we execute a command generating files describing the content of the package:


dh_make -l

where “l” stands for library

We can notice that a new directory “debian” was created. It contains several files, the most important are described below:

  • changelog – Changelog for the package from which a number of the latest version is taken
  • control – File containing package description and its dependencies
  • rules – Script responsible for generating package (similar to make)
  • mylib1.install – List of directories containing files which should be copied to the package (normal package)
  • mylib-dev.install – Similar as mylib1.install but related to development package

Just to make it look better, let’s rename all “mylib1*” files into “mylib*” and then delete unnecessary *.EX and *.ex files. (these files are used in more complex packages, for example involving rc.init script modifications)

Exemplary content of the mentioned files is presented below:

debian/changelog

mylib (0.1.0-1) unstable; urgency=low

* Initial release

-- TG <myemail@x.com>  Fri, 05 Sep 2008 17:40:45

debian/control

Source: mylib
Priority: extra
Maintainer: TG <myemail@x.com>
Build-Depends: debhelper (>= 5)
Standards-Version: 3.7.2
Section: libs

Package: mylib-dev
Section: libdevel
Architecture: any
Depends: mylib (= ${Source-Version})
Description:  myITcorner.com Sample Library  (dev)
Development files.

Package: mylib
Section: libs
Architecture: any
Depends: libglib2.0-0 (>= 2.6), openssl (>= 0.9)
Description:  myITcorner.com Sample Library.
Binary package

mylib.install
Copy all the libraries from usr/local/lib

usr/local/lib/lib*.so.*

mylib.install
Copy all the libraries (also dev files) and C headers

usr/local/include/*
usr/local/lib/lib*.a
usr/local/lib/lib*.so
usr/local/lib/pkgconfig/*
usr/local/lib/*.la
usr/local/lib/pkgconfig/*

debian/rules
Content of debian/rules script is more complex and in most of the situations we can base our package on the file generated by dh_make utility. However, some minor modifications presented below should be introduced:

...
#Configure and compile library from the
#source code and install it into temporary location
install: build
	dh_testdir
	dh_testroot
	dh_clean -k 
	dh_installdirs

	# Add here commands to install
        # the package into debian/tmp
	$(MAKE) DESTDIR=$(CURDIR)/debian/tmp install

# Build architecture-dependent files here.
binary-arch: build install
	dh_testdir
	dh_testroot
	dh_installchangelogs ChangeLog
	dh_installdocs
	dh_installexamples
	dh_install --sourcedir debian/tmp

It’s worth mentioning that a structure of the above file is similar to Makefile script. There are some tasks and their dependencies. For example in install task a library is compiled and then installed into debian/tmp directory. Later in binary-arch, a Debian package is generated from the compiled data taken from debian/tmp directory.

Building the package

Package description and configuration files are ready. So how to make a *.deb files? For that purpose we can use the following command:

dpkg-buildpackage -us -uc -rfakeroot

But let’s make it simpler. Why not to add an entry in a Makefile, just to have everything in one place?
Assuming that we are using Autotools, here is the most interesting part of Makefile.am.

Makefile.am

pkg-deb: dist
	- rm -rf  $(TMP_DIR)
	mkdir -p $(TMP_DIR)
	mv $(PACKAGE)-$(VERSION).tar.gz $(TMP_DIR)/

	tar --directory $(TMP_DIR)/ \
         -xf $(TMP_DIR)/$(PACKAGE)-$(VERSION).tar.gz

	cd $(TMP_DIR)/$(PACKAGE)-$(VERSION)/; \
                ./configure; \
                dpkg-buildpackage -us -uc -rfakeroot; \
                mv ../*.deb $(PWD)/pkg/

	rm -rf $(TMP_DIR);

In such a way a new task pkg-deb was defined. It executes another task called dist, which makes a tarball of the library source code. Later dpkg-buildpackage is called and just to clean everything up, some files are either removed or renamed.

It is important not to forget about including debian directory in the tarball generated with dist task. It can be done by adding the following line somewhere at the top of the Makefile.am:

EXTRA_DIST = debian

By the way TMP_DIR stores a location of the directory for the library installation files. In my case I assumed that

TMP_DIR = tmp

Now it’s enough to invoke:


make pkg-deb

Debian packages should be created inside pkg directory.

References:
Debian New Maintainers’ Guide
Andy Balaam’s Blog