4
# Copyright 2011, 2012 Jiří Janoušek <janousek.jiri@gmail.com>
6
# Extra functions for wscript file
9
from waflib.Configure import conf
10
from waflib.Errors import ConfigurationError
13
"""Class that manage extra configure flags."""
16
self.flags_with_requires = []
19
def _requires_string(self, requires):
21
for key, value in requires.iteritems():
22
result.append(self._dep_key(key, value))
27
return "".join(result)
29
def add(self, id, name, default, requires=None, vala_def=None):
30
"""Adds a new flag."""
31
flag = (id, name, default, requires, vala_def)
32
self.flags.append(flag)
34
self.flags_with_requires.append(flag)
37
def _dep_key(self, name, version):
39
return "%s >= %s" % (name, version)
43
def _add_dep(self, flag):
44
id, name, default, requires, vala_def = flag
45
for key, value in requires.iteritems():
46
key = self._dep_key(key, value)
48
self.deps[key].append(flag)
50
self.deps[key] = [flag]
52
def add_options(self, ctx):
53
"""Adds flags to the options context."""
54
for id, name, default, requires, vala_def in self.flags:
56
help_true = "Build with %s (default)." % name
57
help_false = "Build without %s." % name
59
help_true = "Build with %s." % name
60
help_false = "Build without %s (default)." % name
62
help_true += " Requires %s." % self._requires_string(requires)
63
ctx.add_option("--" + id.replace("_", "-"), action='store_true', dest=id, help=help_true, default=default)
64
ctx.add_option("--no-" + id.replace("_", "-"), action='store_false', dest=id, help=help_false)
66
def store_result(self, ctx):
67
"""Stores status of a feature to ctx.env.feature_<id> and appends Vala definitions"""
68
for id, name, default, requires, vala_def in self.flags:
69
if getattr(ctx.options, id):
71
ctx.vala_def(id.upper())
73
ctx.vala_def(vala_def)
74
ctx.env["feature_" + id] = True
76
ctx.env["feature_" + id] = False
78
def print_restrictive(self, ctx, message):
79
"""Prints message and list of flags with non-empty 'requires' field"""
80
if self.flags_with_requires:
82
for id, name, default, requires, vala_def in self.flags_with_requires:
83
if getattr(ctx.options, id):
84
print " * Feature %s requires %s.\n You can disable it by a flag --no-%s." % (name, self._requires_string(requires), id.replace("_", "-"))
86
def get_feature_for_dep(self, ctx, dep_name, dep_version=None):
87
"""Returns information about features that require particular dependency."""
88
flags = self.deps.get(self._dep_key(dep_name, dep_version), None)
90
for id, name, default, requires, vala_def in flags:
91
if getattr(ctx.options, id):
92
yield "Feature %s requires %s.\n You can disable it by a flag --no-%s." % (name, self._requires_string(requires), id.replace("_", "-"))
95
"""Prints features and their flags"""
96
print "Use `./waf configure --feature` to turn the feature on."
97
print "Use `./waf configure --no-feature` to turn the feature off."
99
print "Available features: \n"
100
for id, name, default, requires, vala_def in self.flags:
102
help_true = "Build with %s (default)." % name
103
help_false = "Build without %s." % name
105
help_true = "Build with %s." % name
106
help_false = "Build without %s (default)." % name
108
help_true += " Requires %s." % self._requires_string(requires)
109
print "--" + id.replace("_", "-")
110
print "\t" + help_true
111
print "--no-" + id.replace("_", "-")
112
print "\t" + help_false
114
def print_summary(self, ctx):
115
"""Prints status of features"""
118
for id, name, default, requires, vala_def in self.flags:
119
if getattr(ctx.options, id):
120
ctx.msg(name, "ON", "GREEN")
122
ctx.msg(name, "OFF", "RED")
127
def vala_def(ctx, vala_definition):
128
"""Appends a Vala definition"""
129
if not hasattr(ctx.env, "VALA_DEFINES"):
130
ctx.env.VALA_DEFINES = []
131
if isinstance(vala_def, tuple) or isinstance(vala_def, list):
132
for d in vala_definition:
133
ctx.env.VALA_DEFINES.append(d)
135
ctx.env.VALA_DEFINES.append(vala_definition)
138
def check_dep(ctx, pkg, uselib, version, mandatory=True, store=None, vala_def=None, define=None):
139
"""Wrapper for ctx.check_cfg that stores errors instead of termination of the script."""
142
ctx.check_cfg(package=pkg, uselib_store=uselib, atleast_version=version, mandatory=True, args = '--cflags --libs')
144
ctx.vala_def(vala_def)
146
for key, value in define.iteritems():
147
ctx.define(key, value)
148
except ConfigurationError, e:
150
fail = "Unable to satisfy dependency %s >= %s" % (pkg, version)
151
ctx.append_error(fail)
152
for fail in flags.get_feature_for_dep(ctx, pkg, version):
153
ctx.append_error(fail)
155
if store is not None:
156
ctx.env[store] = result
160
def check_prog(ctx, name, mandatory=True):
161
"""Wrapper for ctx.find_program that stores errors instead of termination of the script."""
163
ctx.find_program(name, mandatory=True)
165
except ConfigurationError:
167
ctx.append_error("Unable to find program '%s'" % name)
168
for fail in flags.get_feature_for_dep(ctx, name):
169
ctx.append_error(fail)
173
def append_error(ctx, fail):
174
"""Appends error message"""
176
ctx.conf_errors.append(fail)
177
except AttributeError:
178
ctx.conf_errors = [fail]
181
def check_status(ctx,):
182
"""Checks status of configuration. Lists errors and terminates script if there are any errors."""
184
errors = ctx.conf_errors
185
except AttributeError, e:
188
ctx.msg("Configuration status", "FAIL", "RED")
193
ctx.fatal("Configuration failed. Please read file INSTALL for details about dependencies.")
195
ctx.msg("Configuration status", "OK", "GREEN")
200
def parse_version(version):
201
"""Parses version string and returns SERIES, MAJOR, MINOR, BUGFIX, SUFFIX, DEV_STAGE"""
203
m = re.match("^(\d+)\.(\d+)(?:\.(\d+))?(?:\~(unstable|beta\d+))?$", version)
205
raise ValueError("VERSION '%s' doesn't match regular expression" % version)
207
if "alpha" in version or "unstable" in version:
208
dev_stage = "unstable"
209
elif "beta" in version:
213
return (parts[0] + "." + parts[1], int(parts[0] or 0), int(parts[1] or 0),
214
int(parts[2] or 0), parts[3] or "", dev_stage)
217
"""Looks for Bazaar revision information, returns REVISION, REVISION_ID"""
222
num, id = open(".bzr/branch/last-revision").read().split(" ")
223
REVISION = str(int(num))
224
REVISION_ID = str(id).strip()
225
ctx.msg("Revision from .bzr", REVISION, "GREEN")
227
num, id = open("revision_info").read().split(" ")
228
REVISION = str(int(num))
229
REVISION_ID = str(id).strip()
230
ctx.msg("Revision from revision_info", REVISION, "GREEN")
232
for item in os.listdir(os.path.abspath("..")):
233
if not item.endswith(".dsc"):
235
for part in item.split("~"):
236
if not part.startswith("bzr"):
239
ctx.msg("Revision from deb build", REVISION, "GREEN")
243
return REVISION, REVISION_ID