From d35cd0cf121b41181b48e87e31bdcf5d262bba29 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Wed, 20 Dec 2017 00:13:47 +0100 Subject: [PATCH] Improve the Erlang module #2095 --- waflib/extras/erlang.py | 145 ++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 87 deletions(-) diff --git a/waflib/extras/erlang.py b/waflib/extras/erlang.py index f9c15afe..49f6d5b4 100644 --- a/waflib/extras/erlang.py +++ b/waflib/extras/erlang.py @@ -1,15 +1,17 @@ #!/usr/bin/env python # encoding: utf-8 -#Thomas Nagy, 2010 (ita), Przemyslaw Rzepecki, 2016 +# Thomas Nagy, 2010 (ita) +# Przemyslaw Rzepecki, 2016 """ Erlang support """ -from waflib import Task, TaskGen -from waflib.TaskGen import extension, feature, after_method, before_method -import os import re +from waflib import Task, TaskGen +from waflib.TaskGen import feature, after_method, before_method +# to load the method "to_incnodes" below +from waflib.Tools import ccroot # Those flags are required by the Erlang VM to execute/evaluate code in # non-interactive mode. It is used in this tool to create Erlang modules @@ -17,73 +19,48 @@ import re # 'erl' command with ERL_FLAGS environment variable. EXEC_NON_INTERACTIVE = ['-noshell', '-noinput', '-eval'] -def scan_meth(task): - node = task.inputs[0] - parent = node.parent - - deps = [] - scanned = set([]) - nodes_to_scan = [node] - - for n in nodes_to_scan: - if n.abspath() in scanned: - continue - - for i in re.findall('-include\("(.*)"\)\.', n.read()): - found = False - for d in task.includes_nodes: - r = task.generator.path.find_resource(os.path.join(d,i)) - if r: - deps.append(r) - nodes_to_scan.append(r) - found = True - break - r = task.generator.bld.root.find_resource(os.path.join(d,i)) - if r: - deps.append(r) - nodes_to_scan.append(r) - found = True - break - if not found: - pass - scanned.add(n.abspath()) - - return (deps, []) - def configure(conf): conf.find_program('erlc', var='ERLC') conf.find_program('erl', var='ERL') conf.add_os_flags('ERLC_FLAGS') conf.add_os_flags('ERL_FLAGS') + conf.env.ERLC_DEF_PATTERN = '-D%s' + conf.env.ERLC_INC_PATTERN = '-I%s' @TaskGen.extension('.erl') -def process(self, node): +def process_erl_node(self, node): tsk = self.create_task('erl', node, node.change_ext('.beam')) - tsk.includes_nodes = self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES'] + [node.parent.abspath()] - tsk.defines = self.to_list(getattr(self, 'defines', [])) + self.env['DEFINES'] - tsk.flags = self.to_list(getattr(self, 'flags', [])) + self.env['ERLC_FLAGS'] + tsk.erlc_incnodes = [tsk.outputs[0].parent] + self.to_incnodes(self.includes) + tsk.env.append_value('ERLC_INCPATHS', [x.abspath() for x in tsk.erlc_incnodes]) + tsk.env.append_value('ERLC_DEFINES', self.to_list(getattr(self, 'defines', []))) + tsk.env.append_value('ERLC_FLAGS', self.to_list(getattr(self, 'flags', []))) + tsk.cwd = tsk.outputs[0].parent -class erl(Task.Task): - scan=scan_meth - color='GREEN' - vars = ['ERLC_FLAGS', 'ERLC', 'ERL', 'INCLUDES', 'DEFINES'] +class erl(Task.Task): + color = 'GREEN' + run_str = '${ERLC} ${ERL_FLAGS} ${ERLC_INC_PATTERN:ERLC_INCPATHS} ${ERLC_DEF_PATTERN:ERLC_DEFINES} ${SRC}' - def run(self): - output=self.inputs[0].change_ext('.beam') - erlc = self.generator.env["ERLC"] - inca = [i for i in self.includes_nodes if os.path.isabs(i)] - incr = [self.generator.path.find_dir(i) for i in self.includes_nodes if not os.path.isabs(i)] - incr = filter(lambda x:x, incr) - incb = [i.get_bld() for i in incr] - inc = inca + [i.abspath() for i in incr+incb] - r = self.exec_command( - erlc + self.flags - + ["-I"+i for i in inc] - + ["-D"+d for d in self.defines] - + [self.inputs[0].path_from(output.parent)], - cwd=output.parent.abspath(), - shell=False) - return r + def scan(task): + node = task.inputs[0] + + deps = [] + scanned = set([]) + nodes_to_scan = [node] + + for n in nodes_to_scan: + if n.abspath() in scanned: + continue + + for i in re.findall('-include\("(.*)"\)\.', n.read()): + for d in task.erlc_incnodes: + r = d.find_node(i) + if r: + deps.append(r) + nodes_to_scan.append(r) + break + scanned.add(n.abspath()) + + return (deps, []) @TaskGen.extension('.beam') def process(self, node): @@ -92,40 +69,29 @@ def process(self, node): class erl_test(Task.Task): color = 'BLUE' - vars = ['ERL', 'ERL_FLAGS'] - - def run(self): - test_list = ", ".join([m.change_ext("").path_from(m.parent)+":test()" for m in self.modules]) - flags = " ".join(self.flags) - return self.exec_command( - self.generator.env.ERL - + self.generator.env.ERL_FLAGS - + self.flags - + EXEC_NON_INTERACTIVE - + ['halt(case lists:all(fun(Elem) -> Elem == ok end, [%s]) of true -> 0; false -> 1 end).' % test_list], - cwd = self.modules[0].parent.abspath()) + run_str = '${ERL} ${ERL_FLAGS} ${ERL_TEST_FLAGS}' @feature('eunit') @after_method('process_source') -def addtestrun(self): +def add_erl_test_run(self): test_modules = [t.outputs[0] for t in self.tasks] test_task = self.create_task('erl_test') test_task.set_inputs(self.source + test_modules) - test_task.modules = test_modules - test_task.flags = self.to_list(getattr(self, 'flags', [])) + test_task.cwd = test_modules[0].parent + + test_task.env.append_value('ERL_FLAGS', self.to_list(getattr(self, 'flags', []))) + + test_list = ", ".join([m.change_ext("").path_from(test_task.cwd)+":test()" for m in test_modules]) + test_flag = 'halt(case lists:all(fun(Elem) -> Elem == ok end, [%s]) of true -> 0; false -> 1 end).' % test_list + test_task.env.append_value('ERL_TEST_FLAGS', EXEC_NON_INTERACTIVE) + test_task.env.append_value('ERL_TEST_FLAGS', test_flag) + class edoc(Task.Task): color = 'BLUE' - vars = ['ERL_FLAGS', 'ERL'] - - def run(self): - self.exec_command( - self.generator.env.ERL - + self.generator.env.ERL_FLAGS - + EXEC_NON_INTERACTIVE - + ['edoc:files([\"'+self.inputs[0].abspath()+'\"]), halt(0).'], - cwd = self.outputs[0].parent.abspath() - ) + run_str = "${ERL} ${ERL_FLAGS} ${ERL_DOC_FLAGS}" + def keyword(self): + return 'Generating edoc' @feature('edoc') @before_method('process_source') @@ -136,4 +102,9 @@ def add_edoc_task(self): t = e.change_ext('.html') png = t.parent.make_node('erlang.png') css = t.parent.make_node('stylesheet.css') - self.create_task('edoc', e, [t, png, css]) + tsk = self.create_task('edoc', e, [t, png, css]) + tsk.cwd = tsk.outputs[0].parent + tsk.env.append_value('ERL_DOC_FLAGS', EXEC_NON_INTERACTIVE) + tsk.env.append_value('ERL_DOC_FLAGS', 'edoc:files(["%s"]), halt(0).' % tsk.inputs[0].abspath()) + # TODO the above can break if a file path contains '"' +