From e4a9310a9769d432ea8d1fa32710ebb02eda2c60 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 25 Nov 2009 21:55:47 -0700 Subject: Adding support for basic compilation ordering --- include/rebar.hrl | 2 ++ src/rebar_config.erl | 37 +++++++++++++++++++++++++++++++++++-- src/rebar_erlc_compiler.erl | 26 ++++++++++++++++++-------- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/include/rebar.hrl b/include/rebar.hrl index 4b75577..fba5885 100644 --- a/include/rebar.hrl +++ b/include/rebar.hrl @@ -2,5 +2,7 @@ -record(global_state, { working_dir }). -define(CONSOLE(Str, Args), io:format(Str, Args)). +-define(WARN(Str, Args), io:format("WARN: " ++ Str, Args)). -define(FAIL, throw({error, failed})). + diff --git a/src/rebar_config.erl b/src/rebar_config.erl index 077de75..0b3ffee 100644 --- a/src/rebar_config.erl +++ b/src/rebar_config.erl @@ -28,13 +28,34 @@ get_modules/2, get_list/3]). +-include("rebar.hrl"). + -record(config, { dir, opts }). + +%% =================================================================== +%% Public API +%% =================================================================== + new(Dir) -> {ok, DefaultConfig} = application:get_env(rebar, default_config), - #config { dir = Dir, - opts = orddict:from_list(DefaultConfig)}. + BaseDict = 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) -> case orddict:find(app_modules, Config#config.opts) of @@ -52,3 +73,15 @@ get_list(Config, Key, Default) -> List 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). diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 1c157f6..518c446 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -35,9 +35,11 @@ compile(Config, Dir) -> 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", - fun compile_mib/2). + fun compile_mib/2, + rebar_config:get_list(Config, mib_first_files, [])). clean(Config, Dir) -> %% TODO: This would be more portable if it used Erlang to traverse @@ -52,14 +54,18 @@ clean(Config, Dir) -> %% Internal functions %% =================================================================== -do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn) -> +do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn, FirstFiles) -> case filelib:wildcard(SrcWildcard) of [] -> 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 Targets = [target_file(S, OutDir, InExt, OutExt) || S <- Srcs], - Files = lists:zip(Targets, Srcs), + Files = lists:zip(Srcs, Targets), %% Make sure target directory exists ok = filelib:ensure_dir(hd(Targets)), @@ -68,11 +74,15 @@ do_compile(Config, SrcWildcard, OutDir, InExt, OutExt, CompileFn) -> compile_each(Files, Config, CompileFn) end. +drop_each([], List) -> + List; +drop_each([Member | Rest], List) -> + drop_each(Rest, lists:delete(Member, List)). compile_each([], _Config, _CompileFn) -> ok; -compile_each([{Target, Src} | Rest], Config, CompileFn) -> - case needs_compile(Target, Src) of +compile_each([{Src, Target} | Rest], Config, CompileFn) -> + case needs_compile(Src, Target) of true -> ?CONSOLE("Compiling ~s\n", [Src]), CompileFn(Src, Config); @@ -81,7 +91,7 @@ compile_each([{Target, Src} | Rest], Config, CompileFn) -> end, compile_each(Rest, Config, CompileFn). -needs_compile(Target, Src) -> +needs_compile(Src, Target) -> filelib:last_modified(Target) < filelib:last_modified(Src). -- cgit v1.2.1