Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
70 lines (67 sloc) 2.93 KB
#!/usr/bin/env escript
%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (the "License"); you may not use this file except in
%% compliance with the License. You may obtain a copy of the License
%% at
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and
%% limitations under the License.
%% The Original Code is RabbitMQ.
%% The Initial Developer of the Original Code is VMware, Inc.
%% Copyright (c) 2007-2011 VMware, Inc. All rights reserved.
%% -*- erlang -*-
main([IncludeDir, ErlDir, EbinDir, 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]),
Headers = sets:from_list(
[filename:join(IncludeDir, FileName) ||
FileName <- filelib:wildcard("*.hrl", IncludeDir)]),
Deps = lists:foldl(
fun (Path, Deps1) ->
dict:store(Path, detect_deps(IncludeDir, EbinDir,
Modules, Headers, Path),
end, dict:new(), ErlFiles),
{ok, Hdl} = file:open(TargetFile, [write, delayed_write]),
fun (_Path, [], ok) ->
(Path, Dep, ok) ->
Module = filename:basename(Path, ".erl"),
ok = file:write(Hdl, [EbinDir, "/", Module, ".beam: ",
ok = sets:fold(fun (E, ok) -> file:write(Hdl, [" ", E]) end,
ok, Dep),
file:write(Hdl, ["\n"])
end, ok, Deps),
ok = file:write(Hdl, [TargetFile, ": ", escript:script_name(), "\n"]),
ok = file:sync(Hdl),
ok = file:close(Hdl).
detect_deps(IncludeDir, EbinDir, Modules, Headers, Path) ->
{ok, Forms} = epp:parse_file(Path, [IncludeDir], [{use_specs, true}]),
fun ({attribute, _LineNumber, Attribute, Behaviour}, Deps)
when Attribute =:= behaviour orelse Attribute =:= behavior ->
case sets:is_element(Behaviour, Modules) of
true -> sets:add_element(
[EbinDir, "/", atom_to_list(Behaviour), ".beam"],
false -> Deps
({attribute, _LineNumber, file, {FileName, _LineNumber1}}, Deps) ->
case sets:is_element(FileName, Headers) of
true -> sets:add_element(FileName, Deps);
false -> Deps
(_Form, Deps) ->
end, sets:new(), Forms).