mirror of
https://github.com/correl/rebar.git
synced 2024-11-27 11:09:55 +00:00
Adding support for parallel compilation; use 3 workers by default
This commit is contained in:
parent
3765b86653
commit
a658e970db
1 changed files with 60 additions and 10 deletions
|
@ -60,18 +60,23 @@ do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn, FirstFiles) ->
|
||||||
ok;
|
ok;
|
||||||
FoundFiles when is_list(FoundFiles) ->
|
FoundFiles when is_list(FoundFiles) ->
|
||||||
%% Ensure that the FirstFiles are compiled first; drop them from the
|
%% Ensure that the FirstFiles are compiled first; drop them from the
|
||||||
%% FoundFiles and then build a final list of sources
|
%% FoundFiles and compile them in sequence
|
||||||
Srcs = FirstFiles ++ drop_each(FirstFiles, FoundFiles),
|
FirstTargets = [{Fs, target_file(Fs, OutDir, InExt, OutExt)} || Fs <- FirstFiles],
|
||||||
|
RestTargets = [{Fs, target_file(Fs, OutDir, InExt, OutExt)} ||
|
||||||
%% Build list of output files
|
Fs <- drop_each(FirstFiles, FoundFiles)],
|
||||||
Targets = [target_file(S, OutDir, InExt, OutExt) || S <- Srcs],
|
|
||||||
Files = lists:zip(Srcs, Targets),
|
|
||||||
|
|
||||||
%% Make sure target directory exists
|
%% Make sure target directory exists
|
||||||
ok = filelib:ensure_dir(hd(Targets)),
|
ok = filelib:ensure_dir(target_file(hd(FoundFiles), OutDir, InExt, OutExt)),
|
||||||
|
|
||||||
|
%% Compile first targets in sequence
|
||||||
|
compile_each(FirstTargets, Config, CompileFn),
|
||||||
|
|
||||||
%% Start compiling
|
%% Spin up workers
|
||||||
compile_each(Files, Config, CompileFn)
|
Self = self(),
|
||||||
|
Pids = [spawn_monitor(fun() -> compile_worker(Self) end) || _I <- lists:seq(1,3)],
|
||||||
|
|
||||||
|
%% Process rest of targets
|
||||||
|
compile_queue(Pids, RestTargets, Config, CompileFn)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
drop_each([], List) ->
|
drop_each([], List) ->
|
||||||
|
@ -119,3 +124,48 @@ compile_mib(Source, Config) ->
|
||||||
{error, compilation_failed} ->
|
{error, compilation_failed} ->
|
||||||
?FAIL
|
?FAIL
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
compile_queue([], [], _Config, _CompileFn) ->
|
||||||
|
ok;
|
||||||
|
compile_queue(Pids, Targets, Config, CompileFn) ->
|
||||||
|
receive
|
||||||
|
{next, Worker} ->
|
||||||
|
case Targets of
|
||||||
|
[] ->
|
||||||
|
Worker ! empty,
|
||||||
|
compile_queue(Pids, Targets, Config, CompileFn);
|
||||||
|
[{Src, Target} | Rest] ->
|
||||||
|
Worker ! {compile, Src, Target, Config, CompileFn},
|
||||||
|
compile_queue(Pids, Rest, Config, CompileFn)
|
||||||
|
end;
|
||||||
|
|
||||||
|
{compiled, Source} ->
|
||||||
|
?CONSOLE("Compiled ~s\n", [Source]),
|
||||||
|
compile_queue(Pids, Targets, Config, CompileFn);
|
||||||
|
|
||||||
|
{'DOWN', Mref, _, Pid, normal} ->
|
||||||
|
?DEBUG("Worker exited cleanly\n", []),
|
||||||
|
Pids2 = lists:delete({Pid, Mref}, Pids),
|
||||||
|
compile_queue(Pids2, Targets, Config, CompileFn);
|
||||||
|
|
||||||
|
{'DOWN', Mref, _, Pid, _} ->
|
||||||
|
?DEBUG("Worker failed: ~p\n", [Info]),
|
||||||
|
?FAIL
|
||||||
|
end.
|
||||||
|
|
||||||
|
compile_worker(QueuePid) ->
|
||||||
|
QueuePid ! {next, self()},
|
||||||
|
receive
|
||||||
|
{compile, Src, Target, Config, CompileFn} ->
|
||||||
|
case needs_compile(Src, Target) of
|
||||||
|
true ->
|
||||||
|
CompileFn(Src, Config),
|
||||||
|
QueuePid ! {compiled, Src};
|
||||||
|
false ->
|
||||||
|
?INFO("Skipping ~s\n", [Src]),
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
compile_worker(QueuePid);
|
||||||
|
empty ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in a new issue