File 3341-diffable-Allow-input-from-external-runtime.patch of Package erlang
From f47e7d5a2464c54e5d86389dce7b1845ea606c71 Mon Sep 17 00:00:00 2001
From: Frej Drejhammar <frej.drejhammar@gmail.com>
Date: Fri, 1 Apr 2022 08:40:45 +0200
Subject: [PATCH] diffable: Allow input from external runtime
When `diffable` is used to evaluate the impact of a compiler
optimization or checking that a compiler refactoring doesn't change
the result in any significant way, the changes to the compiler source
code produce many differences in the output from `diffable`. The sheer
number of changes in line number directives in the output from, for
example, a reformatting which inserts a line early in a module makes
it hard to notice significant changes in the output.
Prior to this patch `diffable` finds the source code to the
applications it compiles by using `code:root_dir/0` and
`code:lib_dir/1`, that is, it assumes that the source code to compile
is the source for the running system. This patch adds a new command
line flag to `diffable`. The flag, `--erltop <path>`, makes diffable
look for the source code for the applications to compile in a
different tree.
The intended use case is as follows, you have a baseline and a
development tree, located in directories $BASE and $DEV
respectively:
```
$ PATH=$BASE/bin:$PATH $BASE/scripts/diffable --asm \
--deterministic /tmp/baseline
```
Now run `diffable` using the development compiler, but compile the
source code from the baseline:
```
$ PATH=$DEV/bin:$PATH $DEV/scripts/diffable --erltop $BASE --asm \
--deterministic /tmp/dev
```
---
scripts/diffable | 88 +++++++++++++++++++++++++++++++-----------------
1 file changed, 57 insertions(+), 31 deletions(-)
diff --git a/scripts/diffable b/scripts/diffable
index fa3f79454f..c127480242 100755
--- a/scripts/diffable
+++ b/scripts/diffable
@@ -7,7 +7,8 @@
-define(LONG_COMPILE_THRESHOLD, 10000).
main(Args0) ->
- DefOpts = #{format=>asm,no_compile=>false,legacy=>false,copts=>[]},
+ DefOpts = #{erltop=>false,format=>asm,no_compile=>false,
+ legacy=>false,copts=>[]},
{Args,Opts} = opts(Args0, DefOpts),
case Args of
[OutDir] ->
@@ -28,6 +29,10 @@ usage() ->
" --asm)\n"
" --co <option> Add <option> to the list of options given to the\n"
" compiler. See compile:file/2 for valid options.\n"
+ " --erltop <path> By default diffable looks for the applications to\n"
+ " compile by looking up the source for the current\n"
+ " runtime. This option allows the user to compile\n"
+ " the source in a different source tree.\n"
"\n"
"DESCRIPTION\n"
"\n"
@@ -85,6 +90,8 @@ opts(["--deterministic"|Args], #{copts:=Copts}=Opts) ->
opts(Args, Opts#{copts:=Copts++[deterministic]});
opts(["--co",Opt|Args], #{copts:=Copts}=Opts) ->
opts(Args, Opts#{copts:=Copts++[list_to_atom(Opt)]});
+opts(["--erltop", Path|Args], Opts) ->
+ opts(Args, Opts#{erltop:=Path});
opts(["--"++Opt|_], _Opts) ->
io:format("Unknown option: --~ts\n\n", [Opt]),
usage();
@@ -156,16 +163,16 @@ elixir_root() ->
%%%
get_specs(Apps, #{format:=dis,no_compile:=true}=Opts) ->
- Files = get_elixir_beams() ++ get_beams(Apps),
+ Files = get_elixir_beams() ++ get_beams(Apps, Opts),
{Files,Opts};
get_specs(Apps, #{}=Opts) ->
- Inc = make_includes(),
+ Inc = make_includes(Opts),
CompilerOpts = [{d,epmd_dist_high,42},
{d,epmd_dist_low,37},
{d,'VSN',1},
{d,'COMPILER_VSN',1},
{d,erlang_daemon_port,1337}|Inc],
- Files = get_src(Apps),
+ Files = get_src(Apps, Opts),
Specs1 = add_opts(Files, CompilerOpts),
Specs = [{Beam,elixir} || Beam <- get_elixir_beams()] ++ Specs1,
{Specs,Opts}.
@@ -200,31 +207,50 @@ vsn_is_harmful(F) ->
App =:= "ssl"
end.
-get_src(["preloaded"|Apps]) ->
- WC = filename:join(code:root_dir(), "erts/preloaded/src/*.erl"),
- filelib:wildcard(WC) ++ get_src(Apps);
-get_src(["inets"|Apps]) ->
- LibDir = code:lib_dir(inets),
+get_src([A="preloaded"|Apps], Opts) ->
+ WC = filename:join(get_lib_dir(A, Opts), "erts/preloaded/src/*.erl"),
+ filelib:wildcard(WC) ++ get_src(Apps, Opts);
+get_src(["inets"|Apps], Opts) ->
+ LibDir = get_lib_dir(inets, Opts),
WC = filename:join(LibDir, "src/*/*.erl"),
- filelib:wildcard(WC) ++ get_src(Apps);
-get_src(["syntax_tools"|Apps]) ->
- LibDir = code:lib_dir(syntax_tools),
+ filelib:wildcard(WC) ++ get_src(Apps, Opts);
+get_src(["syntax_tools"|Apps], Opts) ->
+ LibDir = get_lib_dir(syntax_tools, Opts),
WC = filename:join(LibDir, "src/*.erl"),
Files0 = filelib:wildcard(WC),
Files = [F || F <- Files0,
filename:basename(F) =/= "merl_tests.erl"],
- Files ++ get_src(Apps);
-get_src(["wx"|Apps]) ->
- LibDir = code:lib_dir(wx),
+ Files ++ get_src(Apps, Opts);
+get_src(["wx"|Apps], Opts) ->
+ LibDir = get_lib_dir(wx, Opts),
WC1 = filename:join(LibDir, "src/gen/*.erl"),
WC2 = filename:join(LibDir, "src/*.erl"),
- filelib:wildcard(WC1) ++ filelib:wildcard(WC2) ++ get_src(Apps);
-get_src([App|Apps]) ->
- WC = filename:join(code:lib_dir(App), "src/*.erl"),
- filelib:wildcard(WC) ++ get_src(Apps);
-get_src([]) -> [].
-
-make_includes() ->
+ filelib:wildcard(WC1) ++ filelib:wildcard(WC2) ++ get_src(Apps, Opts);
+get_src([App|Apps], Opts) ->
+ WC = filename:join(get_lib_dir(App, Opts), "src/*.erl"),
+ filelib:wildcard(WC) ++ get_src(Apps, Opts);
+get_src([], _) -> [].
+
+get_root_dir(#{ erltop := false }) ->
+ code:root_dir();
+get_root_dir(#{ erltop := Root }) ->
+ Root.
+
+get_lib_dir("preloaded", Opts) ->
+ get_root_dir(Opts);
+get_lib_dir(App, #{ erltop := false }) ->
+ code:lib_dir(App);
+get_lib_dir(App, #{ erltop := AltRoot }) ->
+ %% The assumption made here is that we intend to compare either
+ %% two installed runtimes or two source trees, that is, the
+ %% application directory names either both contain the same
+ %% version or have no version at all.
+ RuntimeRoot = code:root_dir(),
+ RuntimeLibDir = code:lib_dir(App),
+ AppWithVersion = lists:nthtail(length(RuntimeRoot) + 1, RuntimeLibDir),
+ AltRoot ++ AppWithVersion.
+
+make_includes(Opts) ->
Is = [{common_test,"include"},
{inets,"include"},
{inets,"src/http_client"},
@@ -242,15 +268,15 @@ make_includes() ->
{wx,"src"},
{wx,"include"},
{xmerl,"include"}],
- [{i,filename:join(code:lib_dir(App), Path)} || {App,Path} <- Is].
-
-get_beams(["preloaded"|Apps]) ->
- WC = filename:join(code:root_dir(), "erts/preloaded/ebin/*.beam"),
- filelib:wildcard(WC) ++ get_beams(Apps);
-get_beams([App|Apps]) ->
- WC = filename:join(code:lib_dir(App), "ebin/*.beam"),
- filelib:wildcard(WC) ++ get_beams(Apps);
-get_beams([]) -> [].
+ [{i,filename:join(get_lib_dir(App, Opts), Path)} || {App,Path} <- Is].
+
+get_beams(["preloaded"|Apps], Opts) ->
+ WC = filename:join(get_root_dir(Opts), "erts/preloaded/ebin/*.beam"),
+ filelib:wildcard(WC) ++ get_beams(Apps, Opts);
+get_beams([App|Apps], Opts) ->
+ WC = filename:join(get_lib_dir(App, Opts), "ebin/*.beam"),
+ filelib:wildcard(WC) ++ get_beams(Apps, Opts);
+get_beams([], _) -> [].
%%%
--
2.34.1