Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env escript
- %% -*- erlang -*-
- -mode(compile).
- %% We expect the list of Erlang source and header files to arrive on
- %% stdin, with the entries colon-separated.
- main([TargetFile, EbinDir]) ->
- ErlsAndHrls = [ string:strip(S,left) ||
- S <- string:tokens(io:get_line(""), ":\n")],
- ErlFiles = [F || F <- ErlsAndHrls, lists:suffix(".erl", F)],
- Modules = sets:from_list(
- [list_to_atom(filename:basename(FileName, ".erl")) ||
- FileName <- ErlFiles]),
- HrlFiles = [F || F <- ErlsAndHrls, lists:suffix(".hrl", F)],
- IncludeDirs = lists:usort([filename:dirname(Path) || Path <- HrlFiles]),
- Headers = sets:from_list(HrlFiles),
- Deps = lists:foldl(
- fun (Path, Deps1) ->
- dict:store(Path, detect_deps(IncludeDirs, EbinDir,
- Modules, Headers, Path),
- Deps1)
- end, dict:new(), ErlFiles),
- {ok, Hdl} = file:open(TargetFile, [write, delayed_write]),
- dict:fold(
- fun (_Path, [], ok) ->
- ok;
- (Path, Dep, ok) ->
- Module = filename:basename(Path, ".erl"),
- ok = file:write(Hdl, [EbinDir, "/", Module, ".beam: ",
- Path]),
- 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(IncludeDirs, EbinDir, Modules, Headers, Path) ->
- {ok, Forms} = epp:parse_file(Path, IncludeDirs, [{use_specs, true}]),
- lists:foldl(
- fun ({attribute, _Line, Attribute, Behaviour}, Deps)
- when Attribute =:= behaviour orelse Attribute =:= behavior ->
- maybe_add_to_deps(EbinDir, Modules, Behaviour, Deps);
- ({attribute, _Line, compile, {parse_transform, Transform}}, Deps) ->
- maybe_add_to_deps(EbinDir, Modules, Transform, Deps);
- ({attribute, _Line, file, {FileName, _LineNumber1}}, Deps) ->
- case sets:is_element(FileName, Headers) of
- true -> sets:add_element(FileName, Deps);
- false -> Deps
- end;
- (_Form, Deps) ->
- Deps
- end, sets:new(), Forms).
- maybe_add_to_deps(EbinDir, Modules, Module, Deps) ->
- case sets:is_element(Module, Modules) of
- true -> sets:add_element(
- [EbinDir, "/", atom_to_list(Module), ".beam"], Deps);
- false -> Deps
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement