diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2017-10-23 10:11:06 -0400 |
---|---|---|
committer | Fred Hebert <mononcqc@ferd.ca> | 2017-10-23 10:16:55 -0400 |
commit | 65e07082018dec2a47f309258761db760100f5f2 (patch) | |
tree | 515f45fe857aa9d07f4f121b65aab744ca02e248 /src | |
parent | 0e15a4cf22b50e4df2100052a332205aeba98972 (diff) |
Fix include paths in profile multiapp edge case
The compiling of OTP applications is done by first topographically
sorting them according to their dependencies, deps-first. This allows
all compilation to take place in order. In the current code, the same
logic extends to top-level applications in an umbrella project.
Unfortunately, there are cases where this is not going to be true: when
an application has extra_src_dirs entries (or additional directories or
files) to conditionally compile under some profiles, it may start
depending on another top-level application dedicated to that profile for
include files.
However, such an app will never make it to production and neither will
the compilation artifacts that create the dependency. Under that
scenario, current rebar3 is unusable.
This patch makes it so that the compilation provider instead changes the
logic for top-level apps: rather than copying their directories one by
one and compiling them in order, it:
1. copies all top-level apps to the build directory so the files are in
their proper locations
2. adds the top-level apps to the path (after the global hooks have run,
so the existing scope and env has not changed)
3. runs the compilation as usual.
Fixes #1651
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar_prv_compile.erl | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 959ecb0..c9a77a5 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -45,13 +45,13 @@ do(State) -> Deps = rebar_state:deps_to_build(State), Cwd = rebar_state:dir(State), - build_apps(State, Providers, Deps), + copy_and_build_apps(State, Providers, Deps), {ok, ProjectApps1} = rebar_digraph:compile_order(ProjectApps), %% Run top level hooks *before* project apps compiled but *after* deps are rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), - ProjectApps2 = build_apps(State, Providers, ProjectApps1), + ProjectApps2 = copy_and_build_project_apps(State, Providers, ProjectApps1), State2 = rebar_state:project_apps(State, ProjectApps2), %% projects with structures like /apps/foo,/apps/bar,/test @@ -77,7 +77,7 @@ format_error({missing_artifact, File}) -> format_error(Reason) -> io_lib:format("~p", [Reason]). -build_apps(State, Providers, Apps) -> +copy_and_build_apps(State, Providers, Apps) -> [build_app(State, Providers, AppInfo) || AppInfo <- Apps]. build_app(State, Providers, AppInfo) -> @@ -86,6 +86,19 @@ build_app(State, Providers, AppInfo) -> copy_app_dirs(AppInfo, AppDir, OutDir), compile(State, Providers, AppInfo). +copy_and_build_project_apps(State, Providers, Apps) -> + %% Top-level apps, because of profile usage and specific orderings (i.e. + %% may require an include file from a profile-specific app for an extra_dirs + %% entry that only exists in a test context), need to be + %% copied and added to the path at once, and not just in compile order. + [copy_app_dirs(AppInfo, + rebar_app_info:dir(AppInfo), + rebar_app_info:out_dir(AppInfo)) + || AppInfo <- Apps], + code:add_pathsa([rebar_app_info:out_dir(AppInfo) || AppInfo <- Apps]), + [compile(State, Providers, AppInfo) || AppInfo <- Apps]. + + build_extra_dirs(State, Apps) -> BaseDir = rebar_state:dir(State), F = fun(App) -> rebar_app_info:dir(App) == BaseDir end, |