You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 rivejä
4.8 KiB

10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
  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. DepsPaths = rebar_state:code_paths(State, all_deps),
  27. code:add_pathsa(DepsPaths),
  28. ProjectApps = rebar_state:project_apps(State),
  29. Providers = rebar_state:providers(State),
  30. Deps = rebar_state:deps_to_build(State),
  31. Cwd = rebar_dir:get_cwd(),
  32. %% Need to allow global config vars used on deps
  33. %% Right now no way to differeniate and just give deps a new state
  34. EmptyState = rebar_state:new(),
  35. build_apps(EmptyState, Providers, Deps),
  36. {ok, ProjectApps1} = rebar_digraph:compile_order(ProjectApps),
  37. %% Run top level hooks *before* project apps compiled but *after* deps are
  38. rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State),
  39. ProjectApps2 = build_apps(State, Providers, ProjectApps1),
  40. State2 = rebar_state:project_apps(State, ProjectApps2),
  41. ProjAppsPaths = [filename:join(rebar_app_info:out_dir(X), "ebin") || X <- ProjectApps2],
  42. State3 = rebar_state:code_paths(State2, all_deps, DepsPaths ++ ProjAppsPaths),
  43. rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State2),
  44. rebar_utils:cleanup_code_path(rebar_state:code_paths(State3, default)),
  45. {ok, State3}.
  46. -spec format_error(any()) -> iolist().
  47. format_error(Reason) ->
  48. io_lib:format("~p", [Reason]).
  49. build_apps(State, Providers, Apps) ->
  50. [build_app(State, Providers, AppInfo) || AppInfo <- Apps].
  51. build_app(State, Providers, AppInfo) ->
  52. AppDir = rebar_app_info:dir(AppInfo),
  53. OutDir = rebar_app_info:out_dir(AppInfo),
  54. copy_app_dirs(State, AppDir, OutDir),
  55. S = case rebar_app_info:state(AppInfo) of
  56. undefined ->
  57. C = rebar_config:consult(AppDir),
  58. rebar_state:new(State, C, AppDir);
  59. AppState ->
  60. AppState
  61. end,
  62. %% Legacy hook support
  63. rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, S),
  64. AppInfo1 = compile(S, AppInfo),
  65. rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, S),
  66. AppInfo1.
  67. compile(State, AppInfo) ->
  68. ?INFO("Compiling ~s", [rebar_app_info:name(AppInfo)]),
  69. rebar_erlc_compiler:compile(State, ec_cnv:to_list(rebar_app_info:out_dir(AppInfo))),
  70. case rebar_otp_app:compile(State, AppInfo) of
  71. {ok, AppInfo1} ->
  72. AppInfo1;
  73. Error ->
  74. throw(Error)
  75. end.
  76. %% ===================================================================
  77. %% Internal functions
  78. %% ===================================================================
  79. copy_app_dirs(State, OldAppDir, AppDir) ->
  80. case ec_cnv:to_binary(filename:absname(OldAppDir)) =/=
  81. ec_cnv:to_binary(filename:absname(AppDir)) of
  82. true ->
  83. EbinDir = filename:join([OldAppDir, "ebin"]),
  84. %% copy all files from ebin if it exists
  85. case filelib:is_dir(EbinDir) of
  86. true ->
  87. OutEbin = filename:join(AppDir, "ebin"),
  88. filelib:ensure_dir(filename:join(OutEbin, "dummy.beam")),
  89. rebar_file_utils:cp_r(filelib:wildcard(filename:join(EbinDir, "*")), OutEbin);
  90. false ->
  91. ok
  92. end,
  93. filelib:ensure_dir(filename:join(AppDir, "dummy")),
  94. %% link to src_dirs to be adjacent to ebin is needed for R15 use of cover/xref
  95. SrcDirs = rebar_dir:all_src_dirs(State, ["src"], []),
  96. [symlink_or_copy(OldAppDir, AppDir, Dir) || Dir <- ["priv", "include"] ++ SrcDirs];
  97. false ->
  98. ok
  99. end.
  100. symlink_or_copy(OldAppDir, AppDir, Dir) ->
  101. Source = filename:join(OldAppDir, Dir),
  102. Target = filename:join(AppDir, Dir),
  103. rebar_file_utils:symlink_or_copy(Source, Target).