1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3# Tool to extend c_config.check_cfg()
4
5__author__ = __maintainer__ = "Jérôme Carretero <cJ-waf@zougloub.eu>"
6__copyright__ = "Jérôme Carretero, 2014"
7
8"""
9
10This tool allows to work around the absence of ``*-config`` programs
11on systems, by keeping the same clean configuration syntax but inferring
12values or permitting their modification via the options interface.
13
14Note that pkg-config can also support setting ``PKG_CONFIG_PATH``,
15so you can put custom files in a folder containing new .pc files.
16This tool could also be implemented by taking advantage of this fact.
17
18Usage::
19
20   def options(opt):
21     opt.load('c_config_alt')
22     opt.add_package_option('package')
23
24   def configure(cfg):
25     conf.load('c_config_alt')
26     conf.check_cfg(...)
27
28Known issues:
29
30- Behavior with different build contexts...
31
32"""
33
34import os
35import functools
36from waflib import Configure, Options, Errors
37
38def name_to_dest(x):
39	return x.lower().replace('-', '_')
40
41
42def options(opt):
43	def x(opt, param):
44		dest = name_to_dest(param)
45		gr = opt.get_option_group("configure options")
46		gr.add_option('--%s-root' % dest,
47		 help="path containing include and lib subfolders for %s" \
48		  % param,
49		)
50
51	opt.add_package_option = functools.partial(x, opt)
52
53
54check_cfg_old = getattr(Configure.ConfigurationContext, 'check_cfg')
55
56@Configure.conf
57def check_cfg(conf, *k, **kw):
58	if k:
59		lst = k[0].split()
60		kw['package'] = lst[0]
61		kw['args'] = ' '.join(lst[1:])
62
63	if not 'package' in kw:
64		return check_cfg_old(conf, **kw)
65
66	package = kw['package']
67
68	package_lo = name_to_dest(package)
69	package_hi = package.upper().replace('-', '_') # TODO FIXME
70	package_hi = kw.get('uselib_store', package_hi)
71
72	def check_folder(path, name):
73		try:
74			assert os.path.isdir(path)
75		except AssertionError:
76			raise Errors.ConfigurationError(
77				"%s_%s (%s) is not a folder!" \
78				% (package_lo, name, path))
79		return path
80
81	root = getattr(Options.options, '%s_root' % package_lo, None)
82
83	if root is None:
84		return check_cfg_old(conf, **kw)
85	else:
86		def add_manual_var(k, v):
87			conf.start_msg('Adding for %s a manual var' % (package))
88			conf.env["%s_%s" % (k, package_hi)] = v
89			conf.end_msg("%s = %s" % (k, v))
90
91
92		check_folder(root, 'root')
93
94		pkg_inc = check_folder(os.path.join(root, "include"), 'inc')
95		add_manual_var('INCLUDES', [pkg_inc])
96		pkg_lib = check_folder(os.path.join(root, "lib"), 'libpath')
97		add_manual_var('LIBPATH', [pkg_lib])
98		add_manual_var('LIB', [package])
99
100		for x in kw.get('manual_deps', []):
101			for k, v in sorted(conf.env.get_merged_dict().items()):
102				if k.endswith('_%s' % x):
103					k = k.replace('_%s' % x, '')
104					conf.start_msg('Adding for %s a manual dep' \
105					 %(package))
106					conf.env["%s_%s" % (k, package_hi)] += v
107					conf.end_msg('%s += %s' % (k, v))
108
109		return True
110
111