summaryrefslogtreecommitdiff
path: root/src/rebar_erlc_compiler.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_erlc_compiler.erl')
-rw-r--r--src/rebar_erlc_compiler.erl64
1 files changed, 42 insertions, 22 deletions
diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl
index 624fe0b..90193da 100644
--- a/src/rebar_erlc_compiler.erl
+++ b/src/rebar_erlc_compiler.erl
@@ -152,31 +152,31 @@ doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) ->
OutDir1 = proplists:get_value(outdir, ErlOpts, OutDir),
- G = init_erlcinfo(proplists:get_all_values(i, ErlOpts), AllErlFiles, Dir),
-
- %% A source file may have been renamed or deleted. Remove it from the graph
- %% and remove any beam file for that source if it exists.
- Vertices = digraph:vertices(G),
- [maybe_rm_beam_and_edge(G, OutDir, File) || File <- lists:sort(Vertices) -- lists:sort(AllErlFiles),
- filename:extension(File) =:= ".erl"],
+ G = init_erlcinfo(proplists:get_all_values(i, ErlOpts), AllErlFiles, Dir, OutDir),
NeededErlFiles = needed_files(G, ErlOpts, Dir, OutDir1, AllErlFiles),
{ErlFirstFiles, ErlOptsFirst} = erl_first_files(Config, ErlOpts, Dir, NeededErlFiles),
{DepErls, OtherErls} = lists:partition(
fun(Source) -> digraph:in_degree(G, Source) > 0 end,
[File || File <- NeededErlFiles, not lists:member(File, ErlFirstFiles)]),
- DepErlsOrdered = digraph_utils:topsort(digraph_utils:subgraph(G, DepErls)),
+ SubGraph = digraph_utils:subgraph(G, DepErls),
+ DepErlsOrdered = digraph_utils:topsort(SubGraph),
FirstErls = ErlFirstFiles ++ lists:reverse(DepErlsOrdered),
?DEBUG("Files to compile first: ~p", [FirstErls]),
- rebar_base_compiler:run(
- Config, FirstErls, OtherErls,
- fun(S, C) ->
- ErlOpts1 = case lists:member(S, ErlFirstFiles) of
- true -> ErlOptsFirst;
- false -> ErlOpts
- end,
- internal_erl_compile(C, Dir, S, OutDir1, ErlOpts1)
- end),
+ try
+ rebar_base_compiler:run(
+ Config, FirstErls, OtherErls,
+ fun(S, C) ->
+ ErlOpts1 = case lists:member(S, ErlFirstFiles) of
+ true -> ErlOptsFirst;
+ false -> ErlOpts
+ end,
+ internal_erl_compile(C, Dir, S, OutDir1, ErlOpts1)
+ end)
+ after
+ true = digraph:delete(SubGraph),
+ true = digraph:delete(G)
+ end,
ok.
%% Get files which need to be compiled first, i.e. those specified in erl_first_files
@@ -219,12 +219,13 @@ maybe_rm_beam_and_edge(G, OutDir, Source) ->
case filelib:is_regular(Source) of
true ->
%% Actually exists, don't delete
- ok;
+ false;
false ->
Target = target_base(OutDir, Source) ++ ".beam",
?DEBUG("Source ~s is gone, deleting previous beam file if it exists ~s", [Source, Target]),
file:delete(Target),
- digraph:del_vertex(G, Source)
+ digraph:del_vertex(G, Source),
+ true
end.
opts_changed(NewOpts, Target) ->
@@ -250,7 +251,7 @@ erlcinfo_file(Dir) ->
%% parse transforms, behaviours etc.) located in their directories or given
%% InclDirs. Note that last modification times stored in vertices already respect
%% dependencies induced by given graph G.
-init_erlcinfo(InclDirs, Erls, Dir) ->
+init_erlcinfo(InclDirs, Erls, Dir, OutDir) ->
G = digraph:new([acyclic]),
try restore_erlcinfo(G, InclDirs, Dir)
catch
@@ -259,10 +260,29 @@ init_erlcinfo(InclDirs, Erls, Dir) ->
file:delete(erlcinfo_file(Dir))
end,
Dirs = source_and_include_dirs(InclDirs, Erls),
- Modified = lists:foldl(update_erlcinfo_fun(G, Dirs), false, Erls),
- if Modified -> store_erlcinfo(G, InclDirs, Dir); not Modified -> ok end,
+ %% A source file may have been renamed or deleted. Remove it from the graph
+ %% and remove any beam file for that source if it exists.
+ Modified = maybe_rm_beams_and_edges(G, OutDir, Erls),
+ Modified1 = lists:foldl(update_erlcinfo_fun(G, Dirs), Modified, Erls),
+ if Modified1 -> store_erlcinfo(G, InclDirs, Dir); not Modified1 -> ok end,
G.
+maybe_rm_beams_and_edges(G, Dir, Files) ->
+ Vertices = digraph:vertices(G),
+ case lists:filter(fun(File) ->
+ case filename:extension(File) =:= ".erl" of
+ true ->
+ maybe_rm_beam_and_edge(G, Dir, File);
+ false ->
+ false
+ end
+ end, lists:sort(Vertices) -- lists:sort(Files)) of
+ [] ->
+ false;
+ _ ->
+ true
+ end.
+
source_and_include_dirs(InclDirs, Erls) ->
SourceDirs = lists:map(fun filename:dirname/1, Erls),
lists:usort(["include" | InclDirs ++ SourceDirs]).