Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: joshualim on Jan 15th, 2014  |  syntax: None  |  size: 2.66 KB  |  views: 54  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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, _Line, Attribute, Behaviour}, Deps)
  43.           when Attribute =:= behaviour orelse Attribute =:= behavior ->
  44.               maybe_add_to_deps(EbinDir, Modules, Behaviour, Deps);
  45.           ({attribute, _Line, compile, {parse_transform, Transform}}, Deps) ->
  46.               maybe_add_to_deps(EbinDir, Modules, Transform, Deps);
  47.           ({attribute, _Line, file, {FileName, _LineNumber1}}, Deps) ->
  48.               case sets:is_element(FileName, Headers) of
  49.                   true  -> sets:add_element(FileName, Deps);
  50.                   false -> Deps
  51.               end;
  52.           (_Form, Deps) ->
  53.               Deps
  54.       end, sets:new(), Forms).
  55.  
  56. maybe_add_to_deps(EbinDir, Modules, Module, Deps) ->
  57.     case sets:is_element(Module, Modules) of
  58.         true  -> sets:add_element(
  59.                    [EbinDir, "/", atom_to_list(Module), ".beam"], Deps);
  60.         false -> Deps
  61.     end.
clone this paste RAW Paste Data