?TableOfContents()
How to split a package into several smaller packages
You want to create multiple binaries packages from one source package.
Please examine the php-java-bridge /debian/* files, as this source package contains many tricks and hints leveraging debhelper scripts and avoiding pitfalls.
Ideas collected from other package sources, discussion lists, debian-mentors hints and guidance, Debian Policy, maintainers guide, man pages.
Special attention to /debian/rules and subpackage_name.* files, like php-java-bridge-j2ee.install , php-java-bridge-j2ee.dirs and so on.
The approach used is a fine grained control, specifying each control file and its contents for each individual target.
This allows you to compile each target individually. Usefull when you have big programs that take hours to compile. Or you want to compile each target with different options. Or you have specific individual installation procedures [31].
Also, see the README.Debian file, containing many hints and instructions.
Please, note that this source package is a dynamic work in progress, constantly evolving. All suggestions are welcome at the php-java-bridge-users mailing list.
This text concept is explaining from bottom to up abstraction level building the packages.
Readings
Splitting a Debian source package into several smaller binary packages is not trivial.
Before you start, you must read the essential guides [1] to [7], [10] to [12], [19], [29], [30] and feeling already comfortable creating single binary packages.
Variables in rules makefile
You must remember that /debian/rules is a makefile. It is not a shell batch script.
Read the following code:
BUILDDIR := debian/php-java-bridge DESTDIR := ${CURDIR}/${BUILDDIR}
- Variables MUST be set outside target rules
- Target rules MUST start at column 1, then followed by ":"
- Actions MUST start after a TAB, not blank spaces
The BUILDDIR was set to allow use of dh_install for .war files.
The Debian package makefile must be fully relocatable.
The build directory must be at a package tool discretion (usually at some source temporary subdirectory) and must not need root privileges.
For the installation, the destination directory MUST NOT be hard coded into the source.
If the upstream source has hardcoded directories, you must apply patches even before the configure target rule.
You must know the different types of makefile variables reading [20].
The effects of using a simply expanded variable ( := ) or a recursively expanded variable ( = ) are very different in a rules makefile.
At our example we want the simply expanded variable behaviour.
Shell command output into rules makefile
We want also collect some shell command output into some variables. [21]
There are some misconceptions that you should avoid [27].
PHP_EXT_DIR := $(shell /usr/bin/php-config --extension-dir) PHP_INCLUDE_DIR := $(shell /usr/bin/php-config --include-dir)
Leveraging dpatch
dpatch is a clever development tool. Its use is not limited nor specific to multiple binary packages. You could use it for single binary packages too. This topic could be safely skipped if you do not intend to modify upstream code.
If you must have to apply some modifications to the upstream code before packaging for Debian, then one of the easiest modes is to use dpatch.
When you execute dpatch in a shell prompt, it opens a session and from now on until you exit the session, all you do will be recorded and converted to a patch for your upstream code into /debian/patches directory.
A good practice is to create small patches with clear, self explanatory and different names. For example, 10_relocate_build , 20_relocate_install, 30_correct_env_variable.
You must read the dpatch man page.
The following code snippet will apply the patches to source, walking through all patches into /debian/patches directory in the ascendant patchnamefile order.
And then stamp the configure step.
configure: patchsource configure-stamp patchsource: patch-stamp patch-stamp: dpatch apply-all dpatch cat-all >patch-stamp configure-stamp: dh_testdir phpize ./configure --with-java=/usr/lib/jvm/java-1.5.0-sun --prefix=${DESTDIR} touch configure-stamp
Cleaning and deapplying patches
You must have a clean rule. Also, if you applied patches, you must deapply them in reverse order.
The dpatch helper will take care of this if you created the patches in a planned naming convention.
clean: clean-patched unpatch clean-patched: dh_testdir dh_testroot rm -f build-stamp configure-stamp -$(MAKE) clean dh_clean unpatch: dpatch deapply-all rm -rf patch-stamp debian/patched
Compiling the binaries
The rule calls the "configure" phony target and then test if it is at the correct directory for the step and if the /debian/control file exists. Finally, touch the build-stamp file.
build: build-stamp build-stamp: configure dh_testdir $(MAKE) #docbook-to-man debian/php-java-bridge.sgml > php-java-bridge.1 touch $@
The phony targets
You must read the Make Manual, about phony targets [28].
Here, we intend to use them as like "subroutines".
.PHONY: build clean binary-indep binary-arch binary install configure installdocs installbasic installini
The relocatable install
Now we will use the "dirs" file and some inline commands to install into the relocated tree.
The "dirs" file is applicable to the default package, the first target rule. The debhelper dh_installdirs will create the listed directories if they not exist.
usr/bin usr/sbin etc/php5/conf.d var/lib/tomcat5/webapps
Please, note the -k option for dh_clean. It keeps the files between binary packages generations. Study the man page for this and other options.
installbasic: build dh_testdir dh_testroot dh_clean -k dh_installdirs install: installbasic $(MAKE) install DESTDIR=${DESTDIR}
This "installini" rule will be used to install some files in desired directories.
Use the dh_installdirs and dh_install instead or cp or mv for cleaner and tracked installation.
This rule could be substituded by a suitable "binary_package_name.install" file, used by dh_install.
Note the absence of leading "/" (for relocation) and one per line to avoid jumping to next rule (a debhelper behaviour of this version).
installini: dh_install java.ini etc/php5/conf.d dh_install mono.ini etc/php5/conf.d
The spliting begins
The compiled code is installed (almost) as the original upstream code intended.
It was sanely relocated.
Now you will distribute the installed files inside the multiple binary packages.
The first binary independent target
/debian/php-java-bridge-j2ee.dirs file
usr/bin usr/sbin etc/php5/conf.d var/lib/tomcat5/webapps
/debian/php-java-bridge-j2ee.docs file
ABOUT.HTM ChangeLog COPYING CREDITS FAQ.html INSTALL.J2EE INSTALL.J2SE INSTALL.LINUX INSTALL.MONO+NET INSTALL.ORACLE INSTALL.WEBSPHERE NEWS PROTOCOL.TXT README README.GNU_JAVA README.MONO+NET VERSION
/debian/php-java-bridge-j2ee.install file for some file almost moved "by hand" after the make install. You use this file with dh_install instead a mv or cp.
java-servlet.ini etc/php5/conf.d
/debian/control snippet.
Please, note the "all" architecture argument. It will be used with the -i option ahead.
Package: php-java-bridge-j2ee Architecture: all
Note the -p$@ to use target name package files in /debian as parameters. [24]
Use the dh_installdirs and dh_install instead or cp or mv for cleaner and tracked installation.
Note the inline dh_install using dynamic variables referring to some directory configured at the begining of the rule file. [23]
Note the use of -i option, indicating a binary architecture independent package.
The inline code does not have a leading "/" for relocating.
See how debhelper apps is leveraged, executing the hard detailed work for you.
Also, the /debian/control file must have some special variables for use here. [22] If they are not used, only a warning will be issued. They do not make harm. For sake of future builds, place them on the control file.
php-java-bridge-j2ee: build install dh_testdir dh_testroot dh_installdirs -i -p$@ dh_installchangelogs -i -p$@ ChangeLog dh_installdocs -i -p$@ dh_install -i -p$@ ${BUILDDIR}$(PHP_EXT_DIR)/JavaBridge.war var/lib/tomcat5/webapps dh_install -i -p$@ dh_installman -i -p$@ dh_link -i -p$@ dh_strip -i dh_compress -i -p$@ dh_fixperms -i -p$@ dh_installdeb -i -p$@ dh_shlibdeps -i -p$@ dh_gencontrol -i -p$@ dh_md5sums -i -p$@ dh_builddeb -i -p$@
The second binary independent target
/debian/php-java-bridge-devel.docs file
ABOUT.HTM ChangeLog COPYING CREDITS FAQ.html INSTALL.J2EE INSTALL.J2SE INSTALL.LINUX INSTALL.MONO+NET INSTALL.ORACLE INSTALL.WEBSPHERE NEWS PROTOCOL.TXT README README.GNU_JAVA README.MONO+NET VERSION
/debian/php-java-bridge-devel.examples file for the debhelper placing at the correct directory.
examples test.php run-tests.php security tests.mono+net tests.php4 tests.php5 unsupported server/php/ server/test/ php_java_lib
/debian/control snippet.
Please, note the "all" architecture argument. It will be used with the -i option ahead.
Package: php-java-bridge-devel Architecture: all
pitfall-> packages may have "-" in their name. Do not create intermediate (phony) rules with this character or things may go really weird and unexpected (as of april 2007 versions).
See how variables are used at dh_install to point to directories that may be different as different related packages are released (php5).[23], [20]
php-java-bridge-devel: build install dh_testdir dh_testroot dh_installdirs -i -p$@ dh_installchangelogs -i -p$@ ChangeLog dh_installdocs -i -p$@ dh_installexamples -i -p$@ dh_install -i -p$@ ${BUILDDIR}$(PHP_EXT_DIR)/*.jar $(PHP_INCLUDE_DIR)/ext/php-java-bridge dh_installman -i -p$@ dh_link -i -p$@ dh_strip -i dh_compress -i -p$@ dh_fixperms -i -p$@ dh_installdeb -i -p$@ dh_shlibdeps -i -p$@ dh_gencontrol -i -p$@ dh_md5sums -i -p$@ dh_builddeb -i -p$@
The third binary independent package
/debian/php-java-bridge-docs.docs file
documentation
The trick here is to reuse a phony rule and specify desired files at the specific configuration file.
php-java-bridge-docs: installdocs
The fourth binary independent package
/debian/php-java-bridge-j2ee-docs.docs file
server/documentation/
/debian/control snippet.
Please, note the "all" architecture argument. It will be used with the -i option ahead.
Package: php-java-bridge-j2ee-docs Architecture: all
See the reusable phony rules. We use build and installbasic and then, the installdocs phony rule becomes reusable too.
php-java-bridge-j2ee-docs: installdocs installdocs: build installbasic dh_testdir dh_testroot dh_installchangelogs ChangeLog dh_installdocs -i dh_installman -i dh_link -i dh_strip -i dh_compress -i dh_fixperms -i dh_installdeb -i dh_shlibdeps -i dh_gencontrol -i dh_md5sums -i dh_builddeb -i
The first binary dependent package
/debian/control snippet.
Please, note the "any" architecture argument. It will be used with the -a option ahead.
Package: php-java-bridge Architecture: any
The package name is implicit. We reuse other phony rules to reduce rule size.
Close attention to the execution path and realize why we do not have a dh_install at this rule.
Note the use of -a option, indicating a binary architecture dependent package.
binary-arch: build install installini dh_testdir dh_testroot dh_installchangelogs -a ChangeLog dh_installdocs -a dh_installman -a dh_link -a dh_strip -a dh_compress -a dh_fixperms -a dh_installdeb -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a
The closing: defining the binary rules
Here you define the whole thing. It is the top level abstraction rule.
binary: binary-indep binary-arch
That is it. You have a complete set of files and rules ready for building your first multiple binary packages software.
External useful links
[0] php-java-bridge source tree http://php-java-bridge.cvs.sourceforge.net/php-java-bridge/php-java-bridge/debian
[1] Debian policy http://www.debian.org/doc/devel-manuals#policy
[2] Debian develpers reference http://www.debian.org/doc/devel-manuals#devref
[3] Debian new maintainers guide http://www.debian.org/doc/devel-manuals#maint-guide
[4] Debian developers manuals http://www.debian.org/doc/devel-manuals
[5] Create Debian Linux packages http://www-128.ibm.com/developerworks/linux/library/l-debpkg.html
[6] Debian Binary Package Building HOWTO http://www.tldp.org/HOWTO/Debian-Binary-Package-Building-HOWTO/
[7] How to backports packages to your version http://selinux.alioth.debian.org/sesarge/HOWTO-Backport.txt
[8] Debian Mentors site http://mentors.debian.net
[9] debian-mentors mailing list http://lists.debian.org/debian-mentors/
[10] Debian packaging tutorial http://debian-news.net/modules/news/article.php?storyid=1075
[11] How to package for Debian http://wiki.debian.org/HowToPackageForDebian
[12] Debian Packaging http://www.linuks.mine.nu/irc/debian-packaging/
[13] Collaborative Maintenance http://wiki.debian.org/CollaborativeMaintenance
[14] Debian for Developers Tutorial http://www.wiggy.net/presentations/2001/DebianWalkThrough/handouts/handouts.html
[15] The Debconf Programmer's Tutorial http://www.fifi.org/doc/debconf-doc/tutorial.html
[16] DEBCONF man page http://www.fifi.org/cgi-bin/man2html/usr/share/man/man8/debconf.8.gz
[17] DEBCONF-DEVEL man page http://www.fifi.org/cgi-bin/man2html/usr/share/man/man8/debconf-devel.8.gz
[18] DEBCONF.CONF man page http://www.fifi.org/cgi-bin/man2html/usr/share/man/man5/debconf.conf.5.gz
[19] DEBHELPER man page http://www.fifi.org/cgi-bin/man2html/usr/share/man/man1/debhelper.1.gz
[20] Make manual - variables flavours http://www.gnu.org/software/make/manual/make.html#Flavors
[21] Make manual - shell function http://www.gnu.org/software/make/manual/make.html#Shell-Function
[22] substitution variables ${misc:Depends}, ${python:Depends}, ${perl:Depends} and package_name.substvars and control files http://help.lockergnome.com/linux/dpkg-gencontrol-warning-unknown-substitution-variable-Depend-ftopict417834.html
[23] thread: how pass variables from files for dh_install into rules? http://lists.debian.org/debian-mentors/2007/04/msg00019.html http://lists.debian.org/debian-mentors/2007/04/msg00031.html
[24] thread: arguments of some dh_* into rules http://lists.debian.org/debian-mentors/2007/04/msg00028.html
- [25] some debhelper clever examples /usr/share/doc/debhelper/examples
[26] debhelper homepage http://kitenet.net/programs/debhelper
[27] thread: variables from shell output in rules makefile http://lists.debian.org/debian-mentors/2006/11/msg00485.html
[28] Make manual - the phony targets http://www.gnu.org/software/make/manual/make.html#Phony-Targets
[29] Autobook - GNU autoconf, automake, libtool book (online and paper) http://sourceware.org/autobook/
[30] Learning the GNU development tools http://autotoolset.sourceforge.net/tutorial.html
[31] list thread: simplifying the targets for spliting http://lists.debian.org/debian-mentors/2007/04/msg00344.html