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