mirror of
https://github.com/correl/rebar.git
synced 2024-11-23 19:19:54 +00:00
recompile files if their "includes" have changed
added parameter to do_compile for passing a function that can extra the list of includes from a file
This commit is contained in:
parent
a0b665360a
commit
1fa659b5b3
3 changed files with 64 additions and 24 deletions
|
@ -28,7 +28,7 @@
|
|||
clean/2]).
|
||||
|
||||
%% make available for rebar_eunit until there is a better option
|
||||
-export([do_compile/7, compile_opts/2]).
|
||||
-export([do_compile/8, compile_opts/2]).
|
||||
|
||||
-include("rebar.hrl").
|
||||
|
||||
|
@ -38,10 +38,10 @@
|
|||
|
||||
compile(Config, _AppFile) ->
|
||||
do_compile(Config, "src/*.erl", "ebin", ".erl", ".beam",
|
||||
fun compile_erl/2,
|
||||
fun list_hrls/2, fun compile_erl/2,
|
||||
rebar_config:get_list(Config, erl_first_files, [])),
|
||||
do_compile(Config, "mibs/*.mib", "priv/mibs", ".mib", ".bin",
|
||||
fun compile_mib/2,
|
||||
undefined, fun compile_mib/2,
|
||||
rebar_config:get_list(Config, mib_first_files, [])).
|
||||
|
||||
clean(_Config, _AppFile) ->
|
||||
|
@ -57,7 +57,8 @@ clean(_Config, _AppFile) ->
|
|||
%% Internal functions
|
||||
%% ===================================================================
|
||||
|
||||
do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn, FirstFiles) ->
|
||||
do_compile(Config, SrcWildcard, OutDir, InExt, OutExt,
|
||||
IncludeFn, CompileFn, FirstFiles) ->
|
||||
case filelib:wildcard(SrcWildcard) of
|
||||
[] ->
|
||||
ok;
|
||||
|
@ -72,14 +73,14 @@ do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn, FirstFiles) ->
|
|||
ok = filelib:ensure_dir(target_file(hd(FoundFiles), OutDir, InExt, OutExt)),
|
||||
|
||||
%% Compile first targets in sequence
|
||||
compile_each(FirstTargets, Config, CompileFn),
|
||||
compile_each(FirstTargets, Config, IncludeFn, CompileFn),
|
||||
|
||||
%% Spin up workers
|
||||
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)
|
||||
compile_queue(Pids, RestTargets, Config, IncludeFn, CompileFn)
|
||||
end.
|
||||
|
||||
drop_each([], List) ->
|
||||
|
@ -87,10 +88,10 @@ drop_each([], List) ->
|
|||
drop_each([Member | Rest], List) ->
|
||||
drop_each(Rest, lists:delete(Member, List)).
|
||||
|
||||
compile_each([], _Config, _CompileFn) ->
|
||||
compile_each([], _Config, _IncludeFn, _CompileFn) ->
|
||||
ok;
|
||||
compile_each([{Src, Target} | Rest], Config, CompileFn) ->
|
||||
case needs_compile(Src, Target) of
|
||||
compile_each([{Src, Target} | Rest], Config, IncludeFn, CompileFn) ->
|
||||
case needs_compile(Src, Target, IncludeFn, Config) of
|
||||
true ->
|
||||
?CONSOLE("Compiling ~s\n", [Src]),
|
||||
CompileFn(Src, Config);
|
||||
|
@ -98,11 +99,23 @@ compile_each([{Src, Target} | Rest], Config, CompileFn) ->
|
|||
?INFO("Skipping ~s\n", [Src]),
|
||||
ok
|
||||
end,
|
||||
compile_each(Rest, Config, CompileFn).
|
||||
compile_each(Rest, Config, IncludeFn, CompileFn).
|
||||
|
||||
needs_compile(Src, Target) ->
|
||||
filelib:last_modified(Target) < filelib:last_modified(Src).
|
||||
|
||||
needs_compile(Src, Target, IncludeFn, Config) ->
|
||||
TargetLM = filelib:last_modified(Target),
|
||||
case TargetLM < filelib:last_modified(Src) of
|
||||
true ->
|
||||
true;
|
||||
false ->
|
||||
if is_function(IncludeFn) ->
|
||||
lists:any(fun(I) ->
|
||||
TargetLM < filelib:last_modified(I)
|
||||
end,
|
||||
IncludeFn(Src, Config));
|
||||
true ->
|
||||
false
|
||||
end
|
||||
end.
|
||||
|
||||
target_file(F, TargetDir, InExt, OutExt) ->
|
||||
filename:join([TargetDir, filename:basename(F, InExt) ++ OutExt]).
|
||||
|
@ -110,6 +123,33 @@ target_file(F, TargetDir, InExt, OutExt) ->
|
|||
compile_opts(Config, Key) ->
|
||||
rebar_config:get_list(Config, Key, []).
|
||||
|
||||
list_hrls(Src, Config) ->
|
||||
case epp:open(Src, include_path(Src, Config)) of
|
||||
{ok, Epp} ->
|
||||
%% check include for erlang files
|
||||
extract_includes(Epp, Src);
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
include_path(Src, Config) ->
|
||||
[filename:dirname(Src)|compile_opts(Config, i)].
|
||||
|
||||
extract_includes(Epp, Src) ->
|
||||
case epp:parse_erl_form(Epp) of
|
||||
{ok, {attribute, 1, file, {Src, 1}}} ->
|
||||
extract_includes(Epp, Src);
|
||||
{ok, {attribute, 1, file, {IncFile, 1}}} ->
|
||||
[IncFile|extract_includes(Epp, Src)];
|
||||
{ok, _} ->
|
||||
extract_includes(Epp, Src);
|
||||
{eof, _} ->
|
||||
epp:close(Epp),
|
||||
[];
|
||||
{error, _Error} ->
|
||||
extract_includes(Epp, Src)
|
||||
end.
|
||||
|
||||
compile_erl(Source, Config) ->
|
||||
Opts = [{i, "include"}, {outdir, "ebin"}, report, return] ++ compile_opts(Config, erl_opts),
|
||||
case compile:file(Source, Opts) of
|
||||
|
@ -136,18 +176,18 @@ compile_mib(Source, Config) ->
|
|||
?FAIL
|
||||
end.
|
||||
|
||||
compile_queue([], [], _Config, _CompileFn) ->
|
||||
compile_queue([], [], _Config, _IncludeFn, _CompileFn) ->
|
||||
ok;
|
||||
compile_queue(Pids, Targets, Config, CompileFn) ->
|
||||
compile_queue(Pids, Targets, Config, IncludeFn, CompileFn) ->
|
||||
receive
|
||||
{next, Worker} ->
|
||||
case Targets of
|
||||
[] ->
|
||||
Worker ! empty,
|
||||
compile_queue(Pids, Targets, Config, CompileFn);
|
||||
compile_queue(Pids, Targets, Config, IncludeFn, CompileFn);
|
||||
[{Src, Target} | Rest] ->
|
||||
Worker ! {compile, Src, Target, Config, CompileFn},
|
||||
compile_queue(Pids, Rest, Config, CompileFn)
|
||||
Worker ! {compile, Src, Target, Config, IncludeFn, CompileFn},
|
||||
compile_queue(Pids, Rest, Config, IncludeFn, CompileFn)
|
||||
end;
|
||||
|
||||
{fail, Error} ->
|
||||
|
@ -156,12 +196,12 @@ compile_queue(Pids, Targets, Config, CompileFn) ->
|
|||
|
||||
{compiled, Source} ->
|
||||
?CONSOLE("Compiled ~s\n", [Source]),
|
||||
compile_queue(Pids, Targets, Config, CompileFn);
|
||||
compile_queue(Pids, Targets, Config, IncludeFn, CompileFn);
|
||||
|
||||
{'DOWN', Mref, _, Pid, normal} ->
|
||||
?DEBUG("Worker exited cleanly\n", []),
|
||||
Pids2 = lists:delete({Pid, Mref}, Pids),
|
||||
compile_queue(Pids2, Targets, Config, CompileFn);
|
||||
compile_queue(Pids2, Targets, Config, IncludeFn, CompileFn);
|
||||
|
||||
{'DOWN', _Mref, _, _Pid, Info} ->
|
||||
?DEBUG("Worker failed: ~p\n", [Info]),
|
||||
|
@ -171,8 +211,8 @@ compile_queue(Pids, Targets, Config, CompileFn) ->
|
|||
compile_worker(QueuePid) ->
|
||||
QueuePid ! {next, self()},
|
||||
receive
|
||||
{compile, Src, Target, Config, CompileFn} ->
|
||||
case needs_compile(Src, Target) of
|
||||
{compile, Src, Target, Config, IncludeFn, CompileFn} ->
|
||||
case needs_compile(Src, Target, IncludeFn, Config) of
|
||||
true ->
|
||||
case catch(CompileFn(Src, Config)) of
|
||||
ok ->
|
||||
|
|
|
@ -51,7 +51,7 @@ eunit(Config, _File) ->
|
|||
|
||||
%% Compile all erlang from src/ into ?EUNIT_DIR
|
||||
rebar_erlc_compiler:do_compile(Config, "src/*.erl", ?EUNIT_DIR, ".erl", ".beam",
|
||||
fun compile_erl/2,
|
||||
undefined, fun compile_erl/2,
|
||||
rebar_config:get_list(Config, erl_first_files, [])),
|
||||
|
||||
%% Build a list of all the .beams in ?EUNIT_DIR -- use this for cover
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
compile(Config, _AppFile) ->
|
||||
FirstFiles = rebar_config:get_list(Config, lfe_first_files, []),
|
||||
rebar_erlc_compiler:do_compile(Config, "src/*.lfe", "ebin", ".lfe", ".beam",
|
||||
fun compile_lfe/2, FirstFiles).
|
||||
undefined, fun compile_lfe/2, FirstFiles).
|
||||
|
||||
|
||||
%% ===================================================================
|
||||
|
|
Loading…
Reference in a new issue