aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2015-12-16 15:18:27 +0100
committerLoïc Hoguin <[email protected]>2015-12-16 15:18:27 +0100
commit649505cd5f14601e3abeabab9016b999a93e1dae (patch)
treeb31aae9f93b2ef8ab19b9978db34038efe524767 /core
parent3ede3d9ae27930c7a9bc09dd3219948e602476d5 (diff)
downloaderlang.mk-649505cd5f14601e3abeabab9016b999a93e1dae.tar.gz
erlang.mk-649505cd5f14601e3abeabab9016b999a93e1dae.tar.bz2
erlang.mk-649505cd5f14601e3abeabab9016b999a93e1dae.zip
Improve file dependency detection
One case was added, where a -compile attribute specified a list that included a parse_transform. This affected alog, for example. The COMPILE_FIRST variable is now filled from a digraph. This allows us to keep track of the dependency tree properly, rather than rely on luck. This affected erlando. With both of these changes in, a large chunk of the rebar autopatch code can be removed, the part that concerned the auto detection of file dependencies. On the other hand, we still need to honor the erl_first_files configuration value, otherwise the parse_trans project fails to build. While it would be possible to detect these dependencies automatically too, it's probably too complex to bother, at least for now.
Diffstat (limited to 'core')
-rw-r--r--core/deps.mk51
-rw-r--r--core/erlc.mk40
2 files changed, 21 insertions, 70 deletions
diff --git a/core/deps.mk b/core/deps.mk
index a74b29b..8815f61 100644
--- a/core/deps.mk
+++ b/core/deps.mk
@@ -247,57 +247,6 @@ define dep_autopatch_rebar.erl
Write(io_lib:format("COMPILE_FIRST +=~s\n", [Names]))
end
end(),
- FindFirst = fun(F, Fd) ->
- case io:parse_erl_form(Fd, undefined) of
- {ok, {attribute, _, compile, {parse_transform, PT}}, _} ->
- [PT, F(F, Fd)];
- {ok, {attribute, _, compile, CompileOpts}, _} when is_list(CompileOpts) ->
- case proplists:get_value(parse_transform, CompileOpts) of
- undefined -> [F(F, Fd)];
- PT -> [PT, F(F, Fd)]
- end;
- {ok, {attribute, _, include, Hrl}, _} ->
- case file:open("$(call core_native_path,$(DEPS_DIR)/$1/include/)" ++ Hrl, [read]) of
- {ok, HrlFd} -> [F(F, HrlFd), F(F, Fd)];
- _ ->
- case file:open("$(call core_native_path,$(DEPS_DIR)/$1/src/)" ++ Hrl, [read]) of
- {ok, HrlFd} -> [F(F, HrlFd), F(F, Fd)];
- _ -> [F(F, Fd)]
- end
- end;
- {ok, {attribute, _, include_lib, "$(1)/include/" ++ Hrl}, _} ->
- {ok, HrlFd} = file:open("$(call core_native_path,$(DEPS_DIR)/$1/include/)" ++ Hrl, [read]),
- [F(F, HrlFd), F(F, Fd)];
- {ok, {attribute, _, include_lib, Hrl}, _} ->
- case file:open("$(call core_native_path,$(DEPS_DIR)/$1/include/)" ++ Hrl, [read]) of
- {ok, HrlFd} -> [F(F, HrlFd), F(F, Fd)];
- _ -> [F(F, Fd)]
- end;
- {ok, {attribute, _, import, {Imp, _}}, _} ->
- case file:open("$(call core_native_path,$(DEPS_DIR)/$1/src/)" ++ atom_to_list(Imp) ++ ".erl", [read]) of
- {ok, ImpFd} -> [Imp, F(F, ImpFd), F(F, Fd)];
- _ -> [F(F, Fd)]
- end;
- {eof, _} ->
- file:close(Fd),
- [];
- _ ->
- F(F, Fd)
- end
- end,
- fun() ->
- ErlFiles = filelib:wildcard("$(call core_native_path,$(DEPS_DIR)/$1/src/)*.erl"),
- First0 = lists:usort(lists:flatten([begin
- {ok, Fd} = file:open(F, [read]),
- FindFirst(FindFirst, Fd)
- end || F <- ErlFiles])),
- First = lists:flatten([begin
- {ok, Fd} = file:open("$(call core_native_path,$(DEPS_DIR)/$1/src/)" ++ atom_to_list(M) ++ ".erl", [read]),
- FindFirst(FindFirst, Fd)
- end || M <- First0, lists:member("$(call core_native_path,$(DEPS_DIR)/$1/src/)" ++ atom_to_list(M) ++ ".erl", ErlFiles)]) ++ First0,
- Write(["COMPILE_FIRST +=", [[" ", atom_to_list(M)] || M <- First,
- lists:member("$(call core_native_path,$(DEPS_DIR)/$1/src/)" ++ atom_to_list(M) ++ ".erl", ErlFiles)], "\n"])
- end(),
Write("\n\nrebar_dep: preprocess pre-deps deps pre-app app\n"),
Write("\npreprocess::\n"),
Write("\npre-deps::\n"),
diff --git a/core/erlc.mk b/core/erlc.mk
index 1b94644..e430ced 100644
--- a/core/erlc.mk
+++ b/core/erlc.mk
@@ -137,12 +137,17 @@ $(PROJECT).d:: $(XRL_FILES) $(YRL_FILES)
# Erlang and Core Erlang files.
define makedep.erl
+ G = digraph:new([acyclic]),
ErlFiles = lists:usort(string:tokens("$(ERL_FILES)", " ")),
Modules = [{filename:basename(F, ".erl"), F} || F <- ErlFiles],
- Add = fun (Dep, Acc) ->
+ Add = fun (Mod, Dep, Acc) ->
case lists:keyfind(atom_to_list(Dep), 1, Modules) of
- {_, DepFile} -> [DepFile|Acc];
- false -> Acc
+ false -> Acc;
+ {_, DepFile} ->
+ digraph:add_vertex(G, Mod),
+ digraph:add_vertex(G, Dep),
+ digraph:add_edge(G, Mod, Dep),
+ [DepFile|Acc]
end
end,
AddHd = fun (Dep, Acc) ->
@@ -152,36 +157,33 @@ define makedep.erl
_ -> Acc
end
end,
- CompileFirst = fun (Deps) ->
- First0 = [case filename:extension(D) of
- ".erl" -> filename:basename(D, ".erl");
- _ -> []
- end || D <- Deps],
- case lists:usort(First0) of
- [] -> [];
- [[]] -> [];
- First -> ["COMPILE_FIRST +=", [[" ", F] || F <- First], "\n"]
- end
- end,
Depend = [begin
+ Mod = list_to_atom(filename:basename(F, ".erl")),
case epp:parse_file(F, ["include/"], []) of
{ok, Forms} ->
Deps = lists:usort(lists:foldl(fun
- ({attribute, _, behavior, Dep}, Acc) -> Add(Dep, Acc);
- ({attribute, _, behaviour, Dep}, Acc) -> Add(Dep, Acc);
- ({attribute, _, compile, {parse_transform, Dep}}, Acc) -> Add(Dep, Acc);
+ ({attribute, _, behavior, Dep}, Acc) -> Add(Mod, Dep, Acc);
+ ({attribute, _, behaviour, Dep}, Acc) -> Add(Mod, Dep, Acc);
+ ({attribute, _, compile, {parse_transform, Dep}}, Acc) -> Add(Mod, Dep, Acc);
+ ({attribute, _, compile, CompileOpts}, Acc) when is_list(CompileOpts) ->
+ case proplists:get_value(parse_transform, CompileOpts) of
+ undefined -> Acc;
+ Dep -> Add(Mod, Dep, Acc)
+ end;
({attribute, _, file, {Dep, _}}, Acc) -> AddHd(Dep, Acc);
(_, Acc) -> Acc
end, [], Forms)),
case Deps of
[] -> "";
- _ -> [F, "::", [[" ", D] || D <- Deps], "; @touch \$$@\n", CompileFirst(Deps)]
+ _ -> [F, "::", [[" ", D] || D <- Deps], "; @touch \$$@\n"]
end;
{error, enoent} ->
[]
end
end || F <- ErlFiles],
- ok = file:write_file("$(1)", Depend),
+ CompileFirst = [X || X <- lists:reverse(digraph_utils:topsort(G)), [] =/= digraph:in_neighbours(G, X)],
+ ok = file:write_file("$(1)", [Depend, "\nCOMPILE_FIRST +=",
+ [[" ", atom_to_list(CF)] || CF <- CompileFirst], "\n"]),
halt()
endef