mirror of
https://gitlab.com/ita1024/waf.git
synced 2024-11-22 18:07:12 +01:00
Udated Erlang support.
This adds a scaner method to track Erlang heders dependencies. Support for EUnit tests Support for EDocs Support for ERL, ERLC, ERLC_FLAGS environment settings.
This commit is contained in:
parent
fdf22b24c8
commit
69157c7b68
@ -1,5 +1,36 @@
|
|||||||
% what a weird language ... :-)
|
% what a weird language ... :-)
|
||||||
|
%%% @author Przemyslaw Rzepecki
|
||||||
|
%%% @version 0.01
|
||||||
|
|
||||||
|
%%% @doc == Hello World, Example Module ==
|
||||||
|
%%% This module contains some Erlang code for WAF build system support for
|
||||||
|
%%% Erlang language.
|
||||||
|
%%% @end
|
||||||
|
|
||||||
-module(hello).
|
-module(hello).
|
||||||
-export([hello_world/0]).
|
-export([say_hello/1, hello_world/0]).
|
||||||
hello_world() -> io:fwrite("hello, world\n").
|
-include("hello.hrl").
|
||||||
|
|
||||||
|
%%% ###########################################################################
|
||||||
|
%% @doc Returns a greetings string
|
||||||
|
%%
|
||||||
|
%% Some more specific description of the function should be written here...
|
||||||
|
%%
|
||||||
|
%% See http://erlang.org/doc/apps/edoc/users_guide.html for the complete Edoc
|
||||||
|
%% guide.
|
||||||
|
%%
|
||||||
|
%% @end
|
||||||
|
%%% ----------------------------------------------------------
|
||||||
|
say_hello(waf) -> "Hello WAF, cool to see you!";
|
||||||
|
say_hello(make) -> "Oh Make, you again...";
|
||||||
|
say_hello(Other) -> "Hi " ++ Other.
|
||||||
|
|
||||||
|
|
||||||
|
%%% ###########################################################################
|
||||||
|
%% @doc Print a 'Hello World' string to stdout of the program..
|
||||||
|
%%
|
||||||
|
%% This is an Erlang Version of the famous hello_world function.
|
||||||
|
%%
|
||||||
|
%% @end
|
||||||
|
%%% ----------------------------------------------------------
|
||||||
|
hello_world() -> io:fwrite("~p~n", [?HELLO_WORLD]).
|
||||||
|
10
playground/erlang/hello_eunit.erl
Normal file
10
playground/erlang/hello_eunit.erl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
-module(hello_eunit).
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include("hello.hrl").
|
||||||
|
|
||||||
|
example_test_() ->
|
||||||
|
[
|
||||||
|
?_assert(hello:say_hello(waf) =:= "Hello WAF, cool to see you!"),
|
||||||
|
?_assert(hello:say_hello(make) =:= "Oh Make, you again..."),
|
||||||
|
?_assert(hello:say_hello("Mike") =:= "Hi Mike")
|
||||||
|
].
|
1
playground/erlang/inc/hello.hrl
Normal file
1
playground/erlang/inc/hello.hrl
Normal file
@ -0,0 +1 @@
|
|||||||
|
-define(HELLO_WORLD, "hello, world").
|
@ -4,5 +4,8 @@ def configure(conf):
|
|||||||
conf.load('erlang')
|
conf.load('erlang')
|
||||||
|
|
||||||
def build(bld):
|
def build(bld):
|
||||||
bld(source='hello.erl')
|
bld(source='hello.erl', includes=['inc'])
|
||||||
|
|
||||||
|
# This requires EUnit. The Erlangs EUnit header files are available erlang-dev package.
|
||||||
|
bld(source=['hello_eunit.erl', 'hello.beam'], includes=['inc'], features="eunit")
|
||||||
|
bld(source=['hello.erl'], includes=['inc'], features="edoc")
|
||||||
|
@ -1,19 +1,139 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
# Thomas Nagy, 2010 (ita)
|
#Thomas Nagy, 2010 (ita), Przemyslaw Rzepecki, 2016
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Erlang support
|
Erlang support
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from waflib import TaskGen
|
from waflib import Task, TaskGen
|
||||||
|
from waflib.TaskGen import extension, feature, after_method, before_method
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
TaskGen.declare_chain(name = 'erlc',
|
# Those flags are required by the Erlang VM to execute/evaluate code in
|
||||||
rule = '${ERLC} ${ERLC_FLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}',
|
# non-interactive mode. It is used in this tool to create Erlang modules
|
||||||
ext_in = '.erl',
|
# documentation and run unit tests. The user can pass additional arguments to the
|
||||||
ext_out = '.beam')
|
# '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):
|
def configure(conf):
|
||||||
conf.find_program('erlc', var='ERLC')
|
conf.find_program('erlc', var='ERLC')
|
||||||
conf.env.ERLC_FLAGS = []
|
conf.find_program('erl', var='ERL')
|
||||||
|
conf.add_os_flags('ERLC_FLAGS')
|
||||||
|
conf.add_os_flags('ERL_FLAGS')
|
||||||
|
|
||||||
|
@TaskGen.extension('.erl')
|
||||||
|
def process(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']
|
||||||
|
|
||||||
|
class erl(Task.Task):
|
||||||
|
scan=scan_meth
|
||||||
|
color='GREEN'
|
||||||
|
vars = ['ERLC_FLAGS', 'ERLC', 'ERL', 'INCLUDES', 'DEFINES']
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
@TaskGen.extension('.beam')
|
||||||
|
def process(self, node):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
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())
|
||||||
|
|
||||||
|
@feature('eunit')
|
||||||
|
@after_method('process_source')
|
||||||
|
def addtestrun(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', []))
|
||||||
|
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
|
||||||
|
@feature('edoc')
|
||||||
|
@before_method('process_source')
|
||||||
|
def add_edoc_task(self):
|
||||||
|
# do not process source, it would create double erl->beam task
|
||||||
|
self.meths.remove('process_source')
|
||||||
|
e = self.path.find_resource(self.source)
|
||||||
|
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])
|
||||||
|
Loading…
Reference in New Issue
Block a user