Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

125 строки
4.7 KiB

10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
  1. -module(rebar_prv_compile).
  2. -behaviour(provider).
  3. -export([init/1,
  4. do/1,
  5. format_error/1]).
  6. -export([compile/2]).
  7. -include("rebar.hrl").
  8. -define(PROVIDER, compile).
  9. -define(DEPS, [lock]).
  10. %% ===================================================================
  11. %% Public API
  12. %% ===================================================================
  13. -spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
  14. init(State) ->
  15. State1 = rebar_state:add_provider(State, providers:create([{name, ?PROVIDER},
  16. {module, ?MODULE},
  17. {bare, false},
  18. {deps, ?DEPS},
  19. {example, "rebar3 compile"},
  20. {short_desc, "Compile apps .app.src and .erl files."},
  21. {desc, "Compile apps .app.src and .erl files."},
  22. {opts, []}])),
  23. {ok, State1}.
  24. -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
  25. do(State) ->
  26. ProjectApps = rebar_state:project_apps(State),
  27. Providers = rebar_state:providers(State),
  28. Deps = rebar_state:deps_to_build(State),
  29. Cwd = rebar_dir:get_cwd(),
  30. rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State),
  31. %% Need to allow global config vars used on deps
  32. %% Right now no way to differeniate and just give deps a new state
  33. EmptyState = rebar_state:new(),
  34. build_apps(EmptyState, Providers, Deps),
  35. %% Use the project State for building project apps
  36. %% Set hooks to empty so top-level hooks aren't run for each project app
  37. State2 = rebar_state:set(rebar_state:set(State, post_hooks, []), pre_hooks, []),
  38. ProjectApps1 = build_apps(State2, Providers, ProjectApps),
  39. rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State),
  40. {ok, rebar_state:project_apps(State, ProjectApps1)}.
  41. -spec format_error(any()) -> iolist().
  42. format_error(Reason) ->
  43. io_lib:format("~p", [Reason]).
  44. build_apps(State, Providers, Apps) ->
  45. [build_app(State, Providers, AppInfo) || AppInfo <- Apps].
  46. build_app(State, Providers, AppInfo) ->
  47. AppDir = rebar_app_info:dir(AppInfo),
  48. OutDir = rebar_app_info:out_dir(AppInfo),
  49. copy_app_dirs(State, AppDir, OutDir),
  50. S = case rebar_app_info:state(AppInfo) of
  51. undefined ->
  52. C = rebar_config:consult(AppDir),
  53. rebar_state:new(State, C, AppDir);
  54. AppState ->
  55. AppState
  56. end,
  57. %% Legacy hook support
  58. rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, S),
  59. AppInfo1 = compile(S, AppInfo),
  60. rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, S),
  61. true = code:add_patha(rebar_app_info:ebin_dir(AppInfo1)),
  62. AppInfo1.
  63. compile(State, AppInfo) ->
  64. ?INFO("Compiling ~s", [rebar_app_info:name(AppInfo)]),
  65. rebar_erlc_compiler:compile(State, ec_cnv:to_list(rebar_app_info:out_dir(AppInfo))),
  66. case rebar_otp_app:compile(State, AppInfo) of
  67. {ok, AppInfo1} ->
  68. AppInfo1;
  69. Error ->
  70. throw(Error)
  71. end.
  72. %% ===================================================================
  73. %% Internal functions
  74. %% ===================================================================
  75. copy_app_dirs(State, OldAppDir, AppDir) ->
  76. case ec_cnv:to_binary(filename:absname(OldAppDir)) =/=
  77. ec_cnv:to_binary(filename:absname(AppDir)) of
  78. true ->
  79. EbinDir = filename:join([OldAppDir, "ebin"]),
  80. %% copy all files from ebin if it exists
  81. case filelib:is_dir(EbinDir) of
  82. true ->
  83. OutEbin = filename:join(AppDir, "ebin"),
  84. filelib:ensure_dir(filename:join(OutEbin, "dummy.beam")),
  85. rebar_file_utils:cp_r(filelib:wildcard(filename:join(EbinDir, "*")), OutEbin);
  86. false ->
  87. ok
  88. end,
  89. filelib:ensure_dir(filename:join(AppDir, "dummy")),
  90. %% link to src_dirs to be adjacent to ebin is needed for R15 use of cover/xref
  91. ErlOpts = rebar_utils:erl_opts(State),
  92. SrcDirs = proplists:get_value(src_dirs, ErlOpts, ["src"]),
  93. [symlink_or_copy(OldAppDir, AppDir, Dir) || Dir <- ["priv", "include", "test"] ++ SrcDirs];
  94. false ->
  95. ok
  96. end.
  97. symlink_or_copy(OldAppDir, AppDir, Dir) ->
  98. Source = filename:join(OldAppDir, Dir),
  99. Target = filename:join(AppDir, Dir),
  100. rebar_file_utils:symlink_or_copy(Source, Target).