From 4ce01860e9ebafee30e2d2f59bcc47f026cec6f9 Mon Sep 17 00:00:00 2001 From: Vagabond Date: Tue, 2 Mar 2010 17:13:58 -0500 Subject: [PATCH 1/4] Compile parse transform and custom behaviours first --- src/rebar_base_compiler.erl | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index 8ca0a7b..c405b3d 100644 --- a/src/rebar_base_compiler.erl +++ b/src/rebar_base_compiler.erl @@ -44,12 +44,15 @@ run(Config, FirstFiles, RestFiles, CompileFn) -> [] -> ok; _ -> + % Sort RestFiles so that parse_transforms and behaviours are first + SortedRestFiles = [K || {K, _V} <- lists:keysort(2, + [{F, compile_priority(F)} || F <- RestFiles ])], Self = self(), F = fun() -> compile_worker(Self, Config, CompileFn) end, Jobs = rebar_config:get_jobs(), ?DEBUG("Starting ~B compile worker(s)~n", [Jobs]), Pids = [spawn_monitor(F) || _I <- lists:seq(1,Jobs)], - compile_queue(Pids, RestFiles) + compile_queue(Pids, SortedRestFiles) end. run(Config, FirstFiles, SourceDir, SourceExt, TargetDir, TargetExt, Compile3Fn) -> @@ -186,3 +189,32 @@ compile_worker(QueuePid, Config, CompileFn) -> empty -> ok end. + +compile_priority(File) -> + case epp_dodger:parse_file(File) of + {error, _} -> + 10; % couldn't parse the file, default priority + {ok, Trees} -> + ?DEBUG("Computing priority of ~p\n", [File]), + F2 = fun({tree,arity_qualifier,_, + {arity_qualifier,{tree,atom,_,behaviour_info}, + {tree,integer,_,1}}}, _) -> + 2; + ({tree,arity_qualifier,_, + {arity_qualifier,{tree,atom,_,parse_transform}, + {tree,integer,_,2}}}, _) -> + 1; + (_, Acc) -> + Acc + end, + + F = fun({tree, attribute, _, {attribute, {tree, atom, _, export}, + [{tree, list, _, {list, List, none}}]}}, Acc) -> + lists:foldl(F2, Acc, List); + (_, Acc) -> + Acc + end, + + lists:foldl(F, 10, Trees) + end. + From c4d3f0ea6580197a608f6a3e07ce58acfb419ab5 Mon Sep 17 00:00:00 2001 From: Vagabond Date: Tue, 2 Mar 2010 17:34:12 -0500 Subject: [PATCH 2/4] Fix dependancy checking for headers by ensuring "include" is always in the eep IncludePath --- src/rebar_erlc_compiler.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 2065a60..6eb71e2 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -96,7 +96,7 @@ doterl_compile(Config, OutDir, MoreSources) -> -spec include_path(Source::string(), Config::#config{}) -> [string()]. include_path(Source, Config) -> ErlOpts = rebar_config:get(Config, erl_opts, []), - [filename:dirname(Source)] ++ proplists:get_all_values(i, ErlOpts). + ["include", filename:dirname(Source)] ++ proplists:get_all_values(i, ErlOpts). -spec inspect(Source::string(), IncludePath::[string()]) -> {string(), [string()]}. inspect(Source, IncludePath) -> From a3f8489340f3ee61719575624a25415b2863a5e4 Mon Sep 17 00:00:00 2001 From: Vagabond Date: Tue, 2 Mar 2010 17:58:05 -0500 Subject: [PATCH 3/4] Move the .erl sorting to the right place --- src/rebar_base_compiler.erl | 34 +--------------------------------- src/rebar_erlc_compiler.erl | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index c405b3d..8ca0a7b 100644 --- a/src/rebar_base_compiler.erl +++ b/src/rebar_base_compiler.erl @@ -44,15 +44,12 @@ run(Config, FirstFiles, RestFiles, CompileFn) -> [] -> ok; _ -> - % Sort RestFiles so that parse_transforms and behaviours are first - SortedRestFiles = [K || {K, _V} <- lists:keysort(2, - [{F, compile_priority(F)} || F <- RestFiles ])], Self = self(), F = fun() -> compile_worker(Self, Config, CompileFn) end, Jobs = rebar_config:get_jobs(), ?DEBUG("Starting ~B compile worker(s)~n", [Jobs]), Pids = [spawn_monitor(F) || _I <- lists:seq(1,Jobs)], - compile_queue(Pids, SortedRestFiles) + compile_queue(Pids, RestFiles) end. run(Config, FirstFiles, SourceDir, SourceExt, TargetDir, TargetExt, Compile3Fn) -> @@ -189,32 +186,3 @@ compile_worker(QueuePid, Config, CompileFn) -> empty -> ok end. - -compile_priority(File) -> - case epp_dodger:parse_file(File) of - {error, _} -> - 10; % couldn't parse the file, default priority - {ok, Trees} -> - ?DEBUG("Computing priority of ~p\n", [File]), - F2 = fun({tree,arity_qualifier,_, - {arity_qualifier,{tree,atom,_,behaviour_info}, - {tree,integer,_,1}}}, _) -> - 2; - ({tree,arity_qualifier,_, - {arity_qualifier,{tree,atom,_,parse_transform}, - {tree,integer,_,2}}}, _) -> - 1; - (_, Acc) -> - Acc - end, - - F = fun({tree, attribute, _, {attribute, {tree, atom, _, export}, - [{tree, list, _, {list, List, none}}]}}, Acc) -> - lists:foldl(F2, Acc, List); - (_, Acc) -> - Acc - end, - - lists:foldl(F, 10, Trees) - end. - diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 6eb71e2..33014cf 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -80,10 +80,16 @@ doterl_compile(Config, OutDir, MoreSources) -> RestErls = [Source || Source <- gather_src(SrcDirs, []) ++ MoreSources, lists:member(Source, FirstErls) == false], + % Sort RestErls so that parse_transforms and behaviours are first + % This should probably be somewhat combined with inspect_epp + SortedRestErls = [K || {K, _V} <- lists:keysort(2, + [{F, compile_priority(F)} || F <- RestErls ])], + + %% Make sure that ebin/ is on the path CurrPath = code:get_path(), code:add_path("ebin"), - rebar_base_compiler:run(Config, FirstErls, RestErls, + rebar_base_compiler:run(Config, FirstErls, SortedRestErls, fun(S, C) -> internal_erl_compile(S, C, OutDir) end), code:set_path(CurrPath), ok. @@ -211,3 +217,32 @@ delete_dir(Dir, []) -> delete_dir(Dir, Subdirs) -> lists:foreach(fun(D) -> delete_dir(D, dirs(D)) end, Subdirs), file:del_dir(Dir). + +-spec compile_priority(File::string()) -> pos_integer(). +compile_priority(File) -> + case epp_dodger:parse_file(File) of + {error, _} -> + 10; % couldn't parse the file, default priority + {ok, Trees} -> + ?DEBUG("Computing priority of ~p\n", [File]), + F2 = fun({tree,arity_qualifier,_, + {arity_qualifier,{tree,atom,_,behaviour_info}, + {tree,integer,_,1}}}, _) -> + 2; + ({tree,arity_qualifier,_, + {arity_qualifier,{tree,atom,_,parse_transform}, + {tree,integer,_,2}}}, _) -> + 1; + (_, Acc) -> + Acc + end, + + F = fun({tree, attribute, _, {attribute, {tree, atom, _, export}, + [{tree, list, _, {list, List, none}}]}}, Acc) -> + lists:foldl(F2, Acc, List); + (_, Acc) -> + Acc + end, + + lists:foldl(F, 10, Trees) + end. From 50832a1a14d52d183551e82d146dde7785434595 Mon Sep 17 00:00:00 2001 From: Vagabond Date: Tue, 2 Mar 2010 18:04:08 -0500 Subject: [PATCH 4/4] Don't detect the source file as an include of itself --- src/rebar_erlc_compiler.erl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 33014cf..473fa20 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -109,14 +109,14 @@ inspect(Source, IncludePath) -> ModuleDefault = filename:basename(Source, ".erl"), case epp:open(Source, IncludePath) of {ok, Epp} -> - inspect_epp(Epp, ModuleDefault, []); + inspect_epp(Epp, Source, ModuleDefault, []); {error, Reason} -> ?DEBUG("Failed to inspect ~s: ~p\n", [Source, Reason]), {ModuleDefault, []} end. --spec inspect_epp(Epp::pid(), Module::string(), Includes::[string()]) -> {string(), [string()]}. -inspect_epp(Epp, Module, Includes) -> +-spec inspect_epp(Epp::pid(), Source::string(), Module::string(), Includes::[string()]) -> {string(), [string()]}. +inspect_epp(Epp, Source, Module, Includes) -> case epp:parse_erl_form(Epp) of {ok, {attribute, _, module, ModInfo}} -> case ModInfo of @@ -133,16 +133,18 @@ inspect_epp(Epp, Module, Includes) -> {ActualModule, _} when is_list(ActualModule) -> ActualModuleStr = string:join([atom_to_list(P) || P <- ActualModule], ".") end, - inspect_epp(Epp, ActualModuleStr, Includes); + inspect_epp(Epp, Source, ActualModuleStr, Includes); {ok, {attribute, 1, file, {Module, 1}}} -> - inspect_epp(Epp, Module, Includes); + inspect_epp(Epp, Source, Module, Includes); + {ok, {attribute, 1, file, {Source, 1}}} -> + inspect_epp(Epp, Source, Module, Includes); {ok, {attribute, 1, file, {IncFile, 1}}} -> - inspect_epp(Epp, Module, [IncFile | Includes]); + inspect_epp(Epp, Source, Module, [IncFile | Includes]); {eof, _} -> epp:close(Epp), {Module, Includes}; _ -> - inspect_epp(Epp, Module, Includes) + inspect_epp(Epp, Source, Module, Includes) end. -spec needs_compile(Source::string(), Target::string(), Hrls::[string()]) -> boolean().