generate_deps
author Simon MacMullen <simon@rabbitmq.com>
Fri Feb 03 15:59:12 2012 +0000 (3 months ago)
changeset 8922 4f87837a40be
parent 5410 3bf92286211a
child 7032 f432f4406050
permissions -rw-r--r--
Merge bug24702
     1 #!/usr/bin/env escript
     2 %% -*- erlang -*-
     3 -mode(compile).
     4 
     5 %% We expect the list of Erlang source and header files to arrive on
     6 %% stdin, with the entries colon-separated.
     7 main([TargetFile, EbinDir]) ->
     8     ErlsAndHrls = [ string:strip(S,left) ||
     9                       S <- string:tokens(io:get_line(""), ":\n")],
    10     ErlFiles = [F || F <- ErlsAndHrls, lists:suffix(".erl", F)],
    11     Modules = sets:from_list(
    12                 [list_to_atom(filename:basename(FileName, ".erl")) ||
    13                     FileName <- ErlFiles]),
    14     HrlFiles = [F || F <- ErlsAndHrls, lists:suffix(".hrl", F)],
    15     IncludeDirs = lists:usort([filename:dirname(Path) || Path <- HrlFiles]),
    16     Headers = sets:from_list(HrlFiles),
    17     Deps = lists:foldl(
    18              fun (Path, Deps1) ->
    19                      dict:store(Path, detect_deps(IncludeDirs, EbinDir,
    20                                                   Modules, Headers, Path),
    21                                 Deps1)
    22              end, dict:new(), ErlFiles),
    23     {ok, Hdl} = file:open(TargetFile, [write, delayed_write]),
    24     dict:fold(
    25       fun (_Path, [], ok) ->
    26               ok;
    27           (Path, Dep, ok) ->
    28               Module = filename:basename(Path, ".erl"),
    29               ok = file:write(Hdl, [EbinDir, "/", Module, ".beam: ",
    30                                    Path]),
    31               ok = sets:fold(fun (E, ok) -> file:write(Hdl, [" ", E]) end,
    32                              ok, Dep),
    33               file:write(Hdl, ["\n"])
    34       end, ok, Deps),
    35     ok = file:write(Hdl, [TargetFile, ": ", escript:script_name(), "\n"]),
    36     ok = file:sync(Hdl),
    37     ok = file:close(Hdl).
    38 
    39 detect_deps(IncludeDirs, EbinDir, Modules, Headers, Path) ->
    40     {ok, Forms} = epp:parse_file(Path, IncludeDirs, [{use_specs, true}]),
    41     lists:foldl(
    42       fun ({attribute, _LineNumber, Attribute, Behaviour}, Deps)
    43           when Attribute =:= behaviour orelse Attribute =:= behavior ->
    44               case sets:is_element(Behaviour, Modules) of
    45                   true  -> sets:add_element(
    46                              [EbinDir, "/", atom_to_list(Behaviour), ".beam"],
    47                              Deps);
    48                   false -> Deps
    49               end;
    50           ({attribute, _LineNumber, file, {FileName, _LineNumber1}}, Deps) ->
    51               case sets:is_element(FileName, Headers) of
    52                   true  -> sets:add_element(FileName, Deps);
    53                   false -> Deps
    54               end;
    55           (_Form, Deps) ->
    56               Deps
    57       end, sets:new(), Forms).