[pacman-dev] Alternative to autotools: waf?

Sebastian Nowicki sebnow at gmail.com
Mon Jun 30 15:38:42 EDT 2008


Hi,
I have been looking for a nice build system, for personal, for quite  
some time now. I saw waf at one point and thought it might be a good  
system, but I never paid much attention to it. Recently I again  
started looking into it and I decided to use pacman to test out how  
good it is. In comparison to autotools, the language (python) is a lot  
simpler and easier to understand, although it still took a while to  
understand waf. The size of the configuration script is significantly  
smaller (see statistics below). The waf website also claims that it is  
faster than autotools, I believe it is, but I did not actually  
benchmark anything. So far I've managed to get libalpm to compile  
(shared library only), and pacman shouldn't be too hard since most of  
the stuff is already there. The script is far from being finished, I  
simply wanted to see how difficult it was to get something compiled,  
while linking against external libraries. I just wanted to see if  
anyone was interested in actually using waf as the build system for  
pacman. If not, I'm not sure that I'll be bothering with compiling  
pacman, since I only really need libalpm.

Not sure if all these files are created by people, but even  
configure.ac alone is larger;
> $ wc -l configure.ac Makefile.am config.* acinclude.m4
>      404 configure.ac
>       29 Makefile.am
>     1526 config.guess
>      614 config.rpath
>     1658 config.sub
>     4952 acinclude.m4
>     9183 total
>
> $ wc -l wscript
>      143 wscript

Note: The build script has only been tested on Mac OS X, and thus I  
don't know if it links properly against libdownload.

 From wscript:
> VERSION = '3.1.4'
> APPNAME = 'pacman'
> LIB_VERSION = '2.3.1'
> LIB_NAME = 'libalpm'
>
> srcdir = '.'
> blddir = 'build'
>
> def set_options(opt):
> 	opt.tool_options('compiler_cc')
> 	# TODO: Optparse on Mac OSX Leopard seems outdated, this doesn't  
> work there
> 	# opt.set_defaults(
> 	# 	root_dir='/',
> 	# 	pkg_ext='.pkg.tar.gz',
> 	# 	src_ext='.src.tar.gz',
> 	# 	db_ext='.db.tar.gz',
> 	# 	use_internal_download=True,
> 	# 	want_doc=False,
> 	# 	want_doxygen=False,
> 	# 	want_asciidoc=False,
> 	# 	want_debug=False,
> 	# 	want_gitver=False,
> 	# 	pacman_static=True
> 	# )
>
> 	opt.add_option('--with-root-dir', dest='root_dir',
> 		help='set the location of pacman\'s root operating directory [/]',  
> default='/')
> 	opt.add_option('--with-pkg-ext', dest='pkg_ext',
> 		help='set the file extension used by packages [pkg.tar.gz]',  
> default='pkg.tar.gz')
> 	opt.add_option('--with-src-ext', dest='src_ext',
> 		help='set the file extension used by source packages  
> [src.tar.gz]', default='src.tar.gz')
> 	opt.add_option('--with-db-ext', dest='db_ext',
> 		help='set the file extension used by the database [db.tar.gz]',  
> default='db.tar.gz')
> 	# opt.add_option('--disable-internal-download', type='store_false',
> 	# 	dest='use_internal_download',
> 	# 	help='do not build with libdownload/libfetch support')
> 	# opt.add_option('--disable-doc', type='store_false',
> 	# 	dest='want_doc',
> 	# 	help='do not generate documentation')
> 	# opt.add_option('--enable-doxygen', dest='want_doxygen',  
> type='store_true',
> 	# 	help='build your own API docs via Doxygen')
> 	# opt.add_option('--enable-asciidoc', dest='want_asciidoc',  
> type='store_true',
> 	# 	help='build your own manpages with Asciidoc')
> 	# opt.add_option('--enable-debug', dest='want_debug',  
> type='store_true',
> 	# 	help='enable debugging support')
> 	pass
>
> def configure(conf):
> 	import Params
> 	
> 	def conf_check_function(name, mandatory=1, headers=[],  
> header_code='', define=''):
> 		functest = conf.create_function_enumerator()
> 		functest.mandatory = mandatory
> 		functest.function = name
> 		if headers:
> 			functest.headers = headers
> 		if not define:
> 			define='HAVE_' + name.upper()
> 		if header_code:
> 			functest.header_code = header_code
> 		functest.define = define
> 		functest.run()
>
> 	conf.check_tool('compiler_cc checks')
> 	
> 	headers = [
> 		'fcntl.h',
> 		'libintl.h',
> 		'limits.h',
> 		'locale.h',
> 		'string.h',
> 		'strings.h',
> 		'sys/ioctl.h',
> 		'sys/param.h',
> 		'sys/statvfs.h',
> 		'sys/syslimits.h',
> 		'sys/time.h',
> 		'syslog.h',
> 		'wchar.h',
> 	]
> 	
> 	for header in headers:
> 		headerconf = conf.create_header_configurator()
> 		headerconf.name = header
> 		headerconf.mandatory = 1
> 		headerconf.message = header + ' is required.'
> 		headerconf.run()
>
> 	conf_check_function('geteuid', 1, ['unistd.h'])
> 	conf_check_function('realpath', 1, ['stdlib.h'])
> 	conf_check_function('regcomp', 1, ['regex.h'])
> 	conf_check_function('strcasecmp', 1, ['string.h'])
> 	#conf_check_function('strndup', 1, ['string.h'],  
> header_code='#define _GNU_SOURCE') #TODO: FIX
> 	conf_check_function('strrchr', 1, ['string.h'])
> 	conf_check_function('strsep', 1, ['string.h'])
> 	#conf_check_function('strverscmp', 1, ['string.h'],  
> header_code='#define _GNU_SOURCE')
> 	conf_check_function('swprintf', 1, ['stdio.h', 'wchar.h'])
> 	conf_check_function('wcwidth', 1, ['wchar.h'])
> 	conf_check_function('uname', 1, ['sys/utsname.h'])
> 	conf_check_function('archive_read_data', 1, ['archive.h'],  
> define='HAVE_LIBARCHIVE')
> 	conf_check_function('downloadParseURL', 0, ['download.h'],  
> define='HAVE_LIBDOWNLOAD')
> 	conf_check_function('fetchParseURL', 0, ['sys/param.h', 'stdio.h',  
> 'fetch.h'], define='HAVE_LIBFETCH')
> 	if conf.env['HAVE_LIBDOWNLOAD'] != 1 and conf.env['HAVE_LIBFETCH'] ! 
> = 1:
> 		#TODO: Print error
> 		#fatal('libdownload or libfetch are needed to compile with  
> internal download support')
> 		return
> 	
> 	conf.env['LIB_ARCHIVE'] = 'archive'
> 	conf.env['LIB_DOWNLOAD'] = 'download'
> 	conf.env['LIB_FETCH'] = 'fetch'
> 	
> 	conf.define('PACKAGE', APPNAME)
> 	conf.define('PACKAGE_VERSION', VERSION)
> 	conf.define('LIB_VERSION', LIB_VERSION)
> 	conf.define('ROOTDIR', Params.g_options.root_dir)
> 	conf.define('DBEXT', Params.g_options.db_ext)
> 	conf.define('PKGEXT', Params.g_options.pkg_ext)
> 	conf.define('DBPATH', '/usr/lib/pacman/')
> 	conf.define('LOGFILE', '/usr/log/pacman.log')
> 	conf.define('CACHEDIR', '/var/cache/pacman/pkg/')
> 	conf.define('CONFFILE', '/etc/pacman.conf') #TODO: make path  
> configurable
> 	conf.define('RETSIGTYPE', 'int') #TODO: Fix? (AC_TYPE_SIGNAL  
> replacement)
> 	#conf.define('HAVE_CONFIG_H', 1) # autotools compatibility
> 	
> 	conf.write_config_header('config.h')
>
> def build(build):
> 	import Constants
> 	env = build.env()
> 	libalpm = build.create_obj('cc', 'shlib')
> 	libalpm.name = LIB_NAME
> 	libalpm.target = 'alpm' # waf prepends 'lib' (why?)
> 	libalpm.uselib = 'ARCHIVE'
> 	if env['HAVE_LIBDOWNLOAD'] != Constants.UNDEFINED:
> 		libalpm.uselib += ' DOWNLOAD'
> 	elif env['HAVE_LIBFETCH'] != Constants.UNDEFINED:
> 		libalpm.uselib += ' FETCH'
> 	libalpm.find_sources_in_dirs('lib/libalpm', exts=['.c'])
> 	
> 	# pacman = build.create_obj('cc', 'program')
> 	# pacman.name = 'pacman'
> 	# pacman.target = 'pacman'
> 	# pacman.uselib = 'libalpm'
> 	# pacman.find_sources_in_dirs('src/pacman', exts=['.c'])
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2415 bytes
Desc: not available
URL: <http://archlinux.org/pipermail/pacman-dev/attachments/20080701/73fc4a11/attachment.bin>


More information about the pacman-dev mailing list