Adding support for basic compilation ordering

This commit is contained in:
Dave Smith 2009-11-25 21:55:47 -07:00
parent fd8794dae7
commit e4a9310a97
3 changed files with 55 additions and 10 deletions

View file

@ -2,5 +2,7 @@
-record(global_state, { working_dir }). -record(global_state, { working_dir }).
-define(CONSOLE(Str, Args), io:format(Str, Args)). -define(CONSOLE(Str, Args), io:format(Str, Args)).
-define(WARN(Str, Args), io:format("WARN: " ++ Str, Args)).
-define(FAIL, throw({error, failed})). -define(FAIL, throw({error, failed})).

View file

@ -28,13 +28,34 @@
get_modules/2, get_modules/2,
get_list/3]). get_list/3]).
-include("rebar.hrl").
-record(config, { dir, -record(config, { dir,
opts }). opts }).
%% ===================================================================
%% Public API
%% ===================================================================
new(Dir) -> new(Dir) ->
{ok, DefaultConfig} = application:get_env(rebar, default_config), {ok, DefaultConfig} = application:get_env(rebar, default_config),
#config { dir = Dir, BaseDict = orddict:from_list(DefaultConfig),
opts = orddict:from_list(DefaultConfig)}.
%% Load terms from rebar.config, if it exists
ConfigFile = filename:join([Dir, "rebar.config"]),
case file:consult(ConfigFile) of
{ok, Terms} ->
Dict = merge_terms(Terms, BaseDict);
{error, enoent} ->
Dict = BaseDict;
Other ->
?WARN("Failed to load ~s: ~p\n", [ConfigFile, Other]),
?FAIL,
Dict = BaseDict
end,
#config { dir = Dir, opts = Dict }.
get_modules(Config, app) -> get_modules(Config, app) ->
case orddict:find(app_modules, Config#config.opts) of case orddict:find(app_modules, Config#config.opts) of
@ -52,3 +73,15 @@ get_list(Config, Key, Default) ->
List List
end. end.
%% ===================================================================
%% Internal functions
%% ===================================================================
merge_terms([], Dict) ->
Dict;
merge_terms([{Key, Value} | Rest], Dict) ->
merge_terms(Rest, orddict:append(Key, Value, Dict));
merge_terms([_ | Rest], Dict) ->
merge_terms(Rest, Dict).

View file

@ -35,9 +35,11 @@
compile(Config, Dir) -> compile(Config, Dir) ->
do_compile(Config, "src/*.erl", "ebin", ".erl", ".beam", do_compile(Config, "src/*.erl", "ebin", ".erl", ".beam",
fun compile_erl/2), fun compile_erl/2,
rebar_config:get_list(Config, erl_first_files, [])),
do_compile(Config, "mibs/*.mib", "priv/mibs", ".mib", ".bin", do_compile(Config, "mibs/*.mib", "priv/mibs", ".mib", ".bin",
fun compile_mib/2). fun compile_mib/2,
rebar_config:get_list(Config, mib_first_files, [])).
clean(Config, Dir) -> clean(Config, Dir) ->
%% TODO: This would be more portable if it used Erlang to traverse %% TODO: This would be more portable if it used Erlang to traverse
@ -52,14 +54,18 @@ clean(Config, Dir) ->
%% Internal functions %% Internal functions
%% =================================================================== %% ===================================================================
do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn) -> do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn, FirstFiles) ->
case filelib:wildcard(SrcWildcard) of case filelib:wildcard(SrcWildcard) of
[] -> [] ->
ok; ok;
Srcs when is_list(Srcs) -> FoundFiles when is_list(FoundFiles) ->
%% Ensure that the FirstFiles are compiled first; drop them from the
%% FoundFiles and then build a final list of sources
Srcs = FirstFiles ++ drop_each(FirstFiles, FoundFiles),
%% Build list of output files %% Build list of output files
Targets = [target_file(S, OutDir, InExt, OutExt) || S <- Srcs], Targets = [target_file(S, OutDir, InExt, OutExt) || S <- Srcs],
Files = lists:zip(Targets, 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(hd(Targets)),
@ -68,11 +74,15 @@ do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn) ->
compile_each(Files, Config, CompileFn) compile_each(Files, Config, CompileFn)
end. end.
drop_each([], List) ->
List;
drop_each([Member | Rest], List) ->
drop_each(Rest, lists:delete(Member, List)).
compile_each([], _Config, _CompileFn) -> compile_each([], _Config, _CompileFn) ->
ok; ok;
compile_each([{Target, Src} | Rest], Config, CompileFn) -> compile_each([{Src, Target} | Rest], Config, CompileFn) ->
case needs_compile(Target, Src) of case needs_compile(Src, Target) of
true -> true ->
?CONSOLE("Compiling ~s\n", [Src]), ?CONSOLE("Compiling ~s\n", [Src]),
CompileFn(Src, Config); CompileFn(Src, Config);
@ -81,7 +91,7 @@ compile_each([{Target, Src} | Rest], Config, CompileFn) ->
end, end,
compile_each(Rest, Config, CompileFn). compile_each(Rest, Config, CompileFn).
needs_compile(Target, Src) -> needs_compile(Src, Target) ->
filelib:last_modified(Target) < filelib:last_modified(Src). filelib:last_modified(Target) < filelib:last_modified(Src).