1 # compatibility layer for building with more recent waf versions
4 from waflib import Build, Configure, Node, Utils, Options, Logs
5 from waflib import ConfigSet
6 from waflib.TaskGen import feature, after
7 from waflib.Configure import conf, ConfigurationContext
9 from waflib.Tools import bison, flex
10 sys.modules['bison'] = bison
11 sys.modules['flex'] = flex
13 for y in (Build.BuildContext, Build.CleanContext, Build.InstallContext, Build.UninstallContext, Build.ListContext):
18 self.cwdx = self.bldnode.parent
19 self.cwd = self.cwdx.abspath()
20 self.bdir = self.bldnode.abspath()
21 return Build.BuildContext.old_pre_build(self)
22 Build.BuildContext.old_pre_build = Build.BuildContext.pre_build
23 Build.BuildContext.pre_build = pre_build
25 def abspath(self, env=None):
26 if env and hasattr(self, 'children'):
27 return self.get_bld().abspath()
28 return self.old_abspath()
29 Node.Node.old_abspath = Node.Node.abspath
30 Node.Node.abspath = abspath
32 def bldpath(self, env=None):
34 #return self.path_from(self.ctx.bldnode.parent)
35 Node.Node.bldpath = bldpath
37 def srcpath(self, env=None):
39 #return self.path_from(self.ctx.bldnode.parent)
40 Node.Node.srcpath = srcpath
42 def store_fast(self, filename):
43 file = open(filename, 'wb')
44 data = self.get_merged_dict()
46 Build.cPickle.dump(data, file, -1)
49 ConfigSet.ConfigSet.store_fast = store_fast
51 def load_fast(self, filename):
52 file = open(filename, 'rb')
54 data = Build.cPickle.load(file)
57 self.table.update(data)
58 ConfigSet.ConfigSet.load_fast = load_fast
60 @feature('c', 'cxx', 'd', 'asm', 'fc', 'includes')
61 @after('propagate_uselib_vars', 'process_source')
62 def apply_incpaths(self):
63 lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES'])
64 self.includes_nodes = lst
65 cwdx = getattr(self.bld, 'cwdx', self.bld.bldnode)
66 self.env['INCPATHS'] = [x.path_from(cwdx) for x in lst]
69 def define(self, key, val, quote=True, comment=None):
70 assert key and isinstance(key, str)
74 elif val in (False, None):
80 if isinstance(val, int) or isinstance(val, float):
83 s = quote and '%s="%s"' or '%s=%s'
84 app = s % (key, str(val))
87 lst = self.env.DEFINES
90 lst[lst.index(x)] = app
93 self.env.append_value('DEFINES', app)
95 self.env.append_unique('define_key', key)
97 # compat15 removes this but we want to keep it
99 def undefine(self, key, from_env=True, comment=None):
100 assert key and isinstance(key, str)
103 self.env.DEFINES = [x for x in self.env.DEFINES if not x.startswith(ban)]
104 self.env.append_unique('define_key', key)
109 class ConfigurationContext(Configure.ConfigurationContext):
111 self.setenv('default')
112 self.env.merge_config_header = True
113 return super(ConfigurationContext, self).init_dirs()
115 def find_program_samba(self, *k, **kw):
116 kw['mandatory'] = False
117 ret = self.find_program_old(*k, **kw)
119 Configure.ConfigurationContext.find_program_old = Configure.ConfigurationContext.find_program
120 Configure.ConfigurationContext.find_program = find_program_samba
122 Build.BuildContext.ENFORCE_GROUP_ORDERING = Utils.nada
123 Build.BuildContext.AUTOCLEANUP_STALE_FILES = Utils.nada
126 def check(self, *k, **kw):
127 '''Override the waf defaults to inject --with-directory options'''
129 # match the configuration test with speficic options, for example:
130 # --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv"
136 for x in Options.OptionsContext.parser.parser.option_list:
137 if getattr(x, 'match', None) and msg in x.match:
138 d = getattr(Options.options, x.dest, '')
140 additional_dirs.append(d)
142 # we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below
143 def add_options_dir(dirs, env):
145 if not x in env.CPPPATH:
146 env.CPPPATH = [os.path.join(x, 'include')] + env.CPPPATH
147 if not x in env.LIBPATH:
148 env.LIBPATH = [os.path.join(x, 'lib')] + env.LIBPATH
150 add_options_dir(additional_dirs, kw['env'])
152 self.start_msg(kw['msg'], **kw)
155 ret = self.run_build(*k, **kw)
156 except self.errors.ConfigurationError:
157 self.end_msg(kw['errmsg'], 'YELLOW', **kw)
161 self.fatal('The configuration failed')
164 # success! time for brandy
165 add_options_dir(additional_dirs, self.env)
167 ret = self.post_check(*k, **kw)
169 self.end_msg(kw['errmsg'], 'YELLOW', **kw)
170 self.fatal('The configuration failed %r' % ret)
172 self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw)
176 def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None):
177 '''see if the platform supports building libraries'''
181 msg = "rpath library support"
183 msg = "building library support"
186 lib_node = bld.srcnode.make_node('libdir/liblc1.c')
187 lib_node.parent.mkdir()
188 lib_node.write('int lib_func(void) { return 42; }\n', 'w')
189 main_node = bld.srcnode.make_node('main.c')
190 main_node.write('int main(void) {return !(lib_func() == 42);}', 'w')
193 script = bld.srcnode.make_node('ldscript')
194 script.write('TEST_1.0A2 { global: *; };\n', 'w')
195 linkflags.append('-Wl,--version-script=%s' % script.abspath())
196 bld(features='c cshlib', source=lib_node, target='lib1', linkflags=linkflags, name='lib1')
197 o = bld(features='c cprogram', source=main_node, target='prog1', uselib_local='lib1')
199 o.rpath = [lib_node.parent.abspath()]
201 args = conf.SAMBA_CROSS_ARGS(msg=msg)
202 env = dict(os.environ)
203 env['LD_LIBRARY_PATH'] = self.inputs[0].parent.abspath() + os.pathsep + env.get('LD_LIBRARY_PATH', '')
204 self.generator.bld.cmd_and_log([self.inputs[0].abspath()] + args, env=env)
206 bld(rule=run_app, source=o.link_task.outputs[0])
210 conf.check(build_fun=build, msg='Checking for %s' % msg)
211 except conf.errors.ConfigurationError:
216 def CHECK_NEED_LC(conf, msg):
217 '''check if we need -lc'''
219 lib_node = bld.srcnode.make_node('libdir/liblc1.c')
220 lib_node.parent.mkdir()
221 lib_node.write('#include <stdio.h>\nint lib_func(void) { FILE *f = fopen("foo", "r");}\n', 'w')
222 bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc')
224 conf.check(build_fun=build, msg=msg, okmsg='-lc is unnecessary', errmsg='-lc is necessary')
225 except conf.errors.ConfigurationError:
229 # already implemented on "waf -v"
230 def order(bld, tgt_list):
232 Build.BuildContext.check_group_ordering = order
235 def CHECK_CFG(self, *k, **kw):
237 kw['args'] = shlex.split(kw['args'])
238 if not 'mandatory' in kw:
239 kw['mandatory'] = False
240 kw['global_define'] = True
241 return self.check_cfg(*k, **kw)
243 def cmd_output(cmd, **kw):
247 silent = kw['silent']
255 kw['shell'] = isinstance(cmd, str)
256 kw['stdout'] = Utils.subprocess.PIPE
258 kw['stderr'] = Utils.subprocess.PIPE
261 p = Utils.subprocess.Popen(cmd, **kw)
262 output = p.communicate()[0]
264 raise ValueError(str(e))
268 msg = "command execution failed: %s -> %r" % (cmd, str(output))
269 raise ValueError(msg)
272 Utils.cmd_output = cmd_output