summaryrefslogtreecommitdiff
path: root/generate_deps
diff options
context:
space:
mode:
authorMatthew Sackman <matthew@lshift.net>2010-01-25 00:57:09 +0000
committerMatthew Sackman <matthew@lshift.net>2010-01-25 00:57:09 +0000
commit3b1a4ba372ae31a1c6dacd86557f8380d06e9243 (patch)
treed447b06e013a57cbb5ea64c963fe7d34950a9ebd /generate_deps
parent4c6b3ba492eb171d37d800e708f65f0543e89073 (diff)
downloadrabbitmq-server-git-3b1a4ba372ae31a1c6dacd86557f8380d06e9243.tar.gz
Added dependency analysis so that we know to compile behaviours first, and we track deps on includes (+transitive) correctly
Diffstat (limited to 'generate_deps')
-rw-r--r--generate_deps71
1 files changed, 71 insertions, 0 deletions
diff --git a/generate_deps b/generate_deps
new file mode 100644
index 0000000000..8b17f499c7
--- /dev/null
+++ b/generate_deps
@@ -0,0 +1,71 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+
+main([IncludeDir, ErlDir, TargetFile]) ->
+ ErlDirContents = filelib:wildcard("*.erl", ErlDir),
+ ErlFiles = [filename:join(ErlDir, FileName) || FileName <- ErlDirContents],
+ Modules = sets:from_list(
+ [list_to_atom(filename:basename(FileName, ".erl")) ||
+ FileName <- ErlDirContents]),
+ IncludeDirContents = filelib:wildcard("*.hrl", IncludeDir),
+ HrlFiles = [filename:join(IncludeDir, FileName) ||
+ FileName <- IncludeDirContents],
+ Headers = sets:from_list(IncludeDirContents),
+ Deps = lists:foldl(fun (Path, Acc) -> make_deps(Path, Acc) end,
+ dict:new(), ErlFiles),
+ Deps1 = lists:foldl(fun (Path, Acc) -> make_deps(Path, Acc) end,
+ Deps, HrlFiles),
+ Deps2 = dict:map(
+ fun (_Module, Dep) ->
+ lists:filter(
+ fun ({module, Behaviour}) ->
+ sets:is_element(Behaviour, Modules);
+ ({include, Include}) ->
+ sets:is_element(Include, Headers)
+ end, Dep)
+ end, Deps1),
+ {ok, Hdl} = file:open(TargetFile, [write, delayed_write]),
+ dict:fold(
+ fun (_Module, [], ok) ->
+ ok;
+ (Module, Dep, ok) ->
+ case lists:suffix(".hrl", Module) of
+ false ->
+ ok = file:write(Hdl, ["$(EBIN_DIR)/", Module, ".beam:"]),
+ lists:foreach(
+ fun (E) ->
+ write_deps(Hdl, IncludeDir, E)
+ end, Dep),
+ file:write(Hdl, [" ", ErlDir, "/", Module, ".erl\n"]);
+ true ->
+ ok = file:write(Hdl, [IncludeDir, "/", Module, ":"]),
+ lists:foreach(
+ fun (E) ->
+ write_deps(Hdl, IncludeDir, E)
+ end, Dep),
+ file:write(Hdl, "\n")
+ end
+ end, ok, Deps2),
+ ok = file:write(Hdl, [TargetFile, ": ", escript:script_name(), "\n"]),
+ ok = file:sync(Hdl),
+ ok = file:close(Hdl).
+
+write_deps(Hdl, _IncludeDir, {module, Behaviour}) ->
+ ok = file:write(Hdl, [" $(EBIN_DIR)/", atom_to_list(Behaviour), ".beam"]);
+write_deps(Hdl, IncludeDir, {include, Include}) ->
+ ok = file:write(Hdl, [" ", IncludeDir, "/", Include]).
+
+
+make_deps(Path, Deps) ->
+ {ok, Forms} = epp:parse_file(Path, [], []),
+ Behaviours =
+ lists:foldl(fun (Form, Acc) -> detect_deps(Form, Acc) end,
+ [], Forms),
+ dict:store(filename:basename(Path, ".erl"), Behaviours, Deps).
+
+detect_deps({attribute, _LineNumber, behaviour, Behaviour}, Deps) ->
+ [{module, Behaviour} | Deps];
+detect_deps({error, {_LineNumber, epp, {include, file, Include}}}, Deps) ->
+ [{include, Include} | Deps];
+detect_deps(_Form, Deps) ->
+ Deps.