Skip to content

Commit 26fed3a

Browse files
committed
Add libs and extra_args attributes to the plt rule
libs are placed on the code path for erlang when the dialyzer command is run This turns out to be useful with elixir, which needs to be on the code path to generate a plt from beam built with elixir extra_args are just extra args to be passed to the `dialyzer` command
1 parent 75b7a68 commit 26fed3a

File tree

4 files changed

+96
-49
lines changed

4 files changed

+96
-49
lines changed

dialyze.bzl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,24 @@ load(
44
)
55
load(
66
"//private:plt.bzl",
7-
_DEFAULT_PLT_APPS = "DEFAULT_PLT_APPS",
87
_plt = "plt",
98
)
109

11-
DEFAULT_PLT_APPS = _DEFAULT_PLT_APPS
10+
DEFAULT_PLT_APPS = ["erts", "kernel", "stdlib"]
1211

1312
DIALYZE_TAG = "dialyze"
1413

15-
def plt(**kwargs):
16-
_plt(**kwargs)
14+
def plt(
15+
for_target = None,
16+
apps = None,
17+
**kwargs):
18+
if for_target == None and apps == None:
19+
apps = DEFAULT_PLT_APPS
20+
_plt(
21+
for_target = for_target,
22+
apps = apps,
23+
**kwargs
24+
)
1725

1826
def dialyze(
1927
name = "dialyze",

private/erlang_bytecode2.bzl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,14 @@ def _impl(ctx):
4141
dir = erl_libs_dir,
4242
)
4343

44-
# it would be nice to properly compute the path, but ctx.bin_dir.path
45-
# does not appear to be the whole prefix
44+
erl_libs_path = ""
4645
if len(erl_libs_files) > 0:
47-
(output_dir, _, path) = erl_libs_files[0].path.partition(erl_libs_dir)
48-
if output_dir == "":
49-
fail("Could not compute the ERL_LIBS relative path from {}".format(
50-
erl_libs_files[0].path,
51-
))
52-
erl_libs_path = path_join(output_dir.rstrip("/"), erl_libs_dir)
53-
else:
54-
erl_libs_path = ""
46+
erl_libs_path = path_join(
47+
ctx.bin_dir.path,
48+
ctx.label.workspace_root,
49+
ctx.label.package,
50+
erl_libs_dir,
51+
)
5552

5653
out_dirs = unique_dirnames(outputs)
5754
if len(out_dirs) > 1:

private/plt.bzl

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,82 @@
11
load("//:erlang_app_info.bzl", "ErlangAppInfo", "flat_deps")
2-
load(":erlang_bytecode.bzl", "unique_dirnames")
2+
load("//:util.bzl", "path_join")
3+
load(":util.bzl", "erl_libs_contents2")
34
load(
45
"//tools:erlang_toolchain.bzl",
56
"erlang_dirs",
67
"maybe_install_erlang",
78
)
89

9-
DEFAULT_PLT_APPS = ["erts", "kernel", "stdlib"]
10-
1110
def _impl(ctx):
1211
logfile = ctx.actions.declare_file(ctx.outputs.plt.basename + ".log")
1312
home_dir = ctx.actions.declare_directory(ctx.label.name + "_home")
1413

14+
erl_libs_dir = ctx.label.name + "_deps"
15+
16+
erl_libs_files = erl_libs_contents2(
17+
ctx,
18+
deps = ctx.attr.libs,
19+
dir = erl_libs_dir,
20+
)
21+
22+
erl_libs_path = ""
23+
if len(erl_libs_files) > 0:
24+
erl_libs_path = path_join(
25+
ctx.bin_dir.path,
26+
ctx.label.workspace_root,
27+
ctx.label.package,
28+
erl_libs_dir,
29+
)
30+
31+
target_files_dir = ctx.label.name + "_files"
32+
33+
deps = []
34+
if ctx.attr.for_target != None:
35+
deps.extend(flat_deps(ctx.attr.for_target[ErlangAppInfo].deps + ctx.attr.deps))
36+
else:
37+
deps.extend(flat_deps(ctx.attr.deps))
38+
39+
target_files = erl_libs_contents2(
40+
ctx,
41+
deps = deps,
42+
dir = target_files_dir,
43+
)
44+
45+
target_files_path = ""
46+
if len(target_files) > 0:
47+
target_files_path = path_join(
48+
ctx.bin_dir.path,
49+
ctx.label.workspace_root,
50+
ctx.label.package,
51+
target_files_dir,
52+
)
53+
54+
args = ctx.actions.args()
55+
1556
if ctx.file.plt == None:
16-
source_plt_arg = "--build_plt"
57+
args.add("--build_plt")
1758
else:
18-
source_plt_arg = "--plt " + ctx.file.plt.path + " --no_check_plt --add_to_plt"
59+
args.add("--plt")
60+
args.add(ctx.file.plt)
61+
args.add("--no_check_plt")
62+
args.add("--add_to_plt")
1963

2064
apps = []
65+
apps.extend(ctx.attr.apps)
2166
if ctx.attr.for_target != None:
2267
apps.extend(ctx.attr.for_target[ErlangAppInfo].extra_apps)
23-
if ctx.attr.for_target == None or ctx.attr.apps != DEFAULT_PLT_APPS:
24-
apps.extend(ctx.attr.apps)
25-
apps_args = ""
2668
if len(apps) > 0:
27-
apps_args = "--apps " + " ".join(apps)
69+
args.add("--apps")
70+
args.add_all(apps)
2871

29-
deps = []
30-
if ctx.attr.for_target != None:
31-
deps.extend(flat_deps(ctx.attr.for_target[ErlangAppInfo].deps + ctx.attr.deps))
32-
else:
33-
deps.extend(flat_deps(ctx.attr.deps))
72+
if target_files_path != "":
73+
args.add("-r")
74+
args.add(target_files_path)
3475

35-
files = []
36-
for dep in deps:
37-
lib_info = dep[ErlangAppInfo]
38-
files.extend(lib_info.beam)
76+
args.add_all(ctx.attr.extra_args)
3977

40-
dirs = unique_dirnames(files)
41-
dirs_args = "".join([
42-
"\n {} \\".format(d)
43-
for d in dirs
44-
])
78+
args.add("--output_plt")
79+
args.add(ctx.outputs.plt)
4580

4681
(erlang_home, _, runfiles) = erlang_dirs(ctx)
4782

@@ -52,38 +87,38 @@ def _impl(ctx):
5287
# without HOME being set, dialyzer will error regarding a default plt
5388
export HOME={home}
5489
90+
if [ -n "{erl_libs_path}" ]; then
91+
export ERL_LIBS={erl_libs_path}
92+
fi
93+
5594
set +e
5695
set -x
57-
"{erlang_home}"/bin/dialyzer {apps_args} \\
58-
{source_plt_arg} \\{dirs_args}
59-
--output_plt {output} > {logfile}
96+
"{erlang_home}"/bin/dialyzer $@ > {logfile}
6097
R=$?
6198
set +x
6299
set -e
63100
if [ ! $R -eq 0 ]; then
64-
cat {logfile}
101+
head {logfile}
65102
fi
66103
exit $R
67104
""".format(
68105
maybe_install_erlang = maybe_install_erlang(ctx),
69106
erlang_home = erlang_home,
70107
home = home_dir.path,
71-
apps_args = apps_args,
72-
source_plt_arg = source_plt_arg,
73-
dirs_args = dirs_args,
74-
output = ctx.outputs.plt.path,
108+
erl_libs_path = erl_libs_path,
75109
logfile = logfile.path,
76110
)
77111

78112
inputs = depset(
79-
direct = ctx.files.plt + files,
113+
direct = ctx.files.plt + erl_libs_files + target_files,
80114
transitive = [runfiles.files],
81115
)
82116

83117
ctx.actions.run_shell(
84118
inputs = inputs,
85119
outputs = [ctx.outputs.plt, logfile, home_dir],
86120
command = script,
121+
arguments = [args],
87122
mnemonic = "DIALYZER",
88123
)
89124

@@ -93,8 +128,10 @@ plt = rule(
93128
"plt": attr.label(
94129
allow_single_file = [".plt"],
95130
),
96-
"apps": attr.string_list(
97-
default = DEFAULT_PLT_APPS,
131+
"apps": attr.string_list(),
132+
"extra_args": attr.string_list(),
133+
"libs": attr.label_list(
134+
providers = [ErlangAppInfo],
98135
),
99136
"deps": attr.label_list(
100137
providers = [ErlangAppInfo],

private/util.bzl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ def additional_file_dest_relative_path(dep_label, f):
2121
else:
2222
return f.short_path
2323

24-
def erl_libs_contents2(ctx, target_info = None, deps = [], headers = False, dir = _DEFAULT_ERL_LIBS_DIR):
24+
def erl_libs_contents2(
25+
ctx,
26+
target_info = None,
27+
deps = [],
28+
headers = False,
29+
dir = _DEFAULT_ERL_LIBS_DIR):
2530
erl_libs_files = []
2631
if headers and target_info != None:
2732
dep_path = path_join(dir, target_info.app_name)

0 commit comments

Comments
 (0)