Advertisement
joshualim

Untitled

Jan 15th, 2014
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.66 KB | None | 0 0
  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.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement