@@ -14,14 +14,15 @@ defmodule Mix.Tasks.Compile.All do
14
14
Mix.Project . get! ( )
15
15
config = Mix.Project . config ( )
16
16
validate_compile_env? = "--no-validate-compile-env" not in args
17
+ lib_path = Path . join ( Mix.Project . build_path ( config ) , "lib" )
17
18
18
19
# Make sure Mix.Dep is cached to avoid loading dependencies
19
20
# during compilation. It is likely this will be invoked anyway,
20
21
# as both Elixir and app compilers rely on it.
21
22
Mix.Dep . cached ( )
22
23
23
24
unless "--no-app-loading" in args do
24
- load_apps ( config , validate_compile_env? )
25
+ load_apps ( config , lib_path , validate_compile_env? )
25
26
end
26
27
27
28
result =
@@ -39,8 +40,9 @@ defmodule Mix.Tasks.Compile.All do
39
40
end )
40
41
end
41
42
43
+ app = config [ :app ]
42
44
_ = Code . prepend_path ( Mix.Project . compile_path ( ) )
43
- load_app ( config [ : app] , validate_compile_env? )
45
+ load_app ( app , % { app => true } , lib_path , validate_compile_env? )
44
46
result
45
47
end
46
48
@@ -93,19 +95,20 @@ defmodule Mix.Tasks.Compile.All do
93
95
94
96
## App loading helpers
95
97
96
- defp load_apps ( config , validate_compile_env? ) do
98
+ defp load_apps ( config , lib_path , validate_compile_env? ) do
97
99
{ runtime , optional } = Mix.Tasks.Compile.App . project_apps ( config )
98
100
parent = self ( )
99
101
opts = [ ordered: false , timeout: :infinity ]
102
+ deps = for dep <- Mix.Dep . cached ( ) , into: % { } , do: { dep . app , true }
100
103
101
104
stream_apps ( runtime ++ optional )
102
- |> Task . async_stream ( & load_app ( & 1 , parent , validate_compile_env? ) , opts )
105
+ |> Task . async_stream ( & load_app ( & 1 , parent , deps , lib_path , validate_compile_env? ) , opts )
103
106
|> Stream . run ( )
104
107
end
105
108
106
- defp load_app ( app , parent , validate_compile_env? ) do
109
+ defp load_app ( app , parent , deps , lib_path , validate_compile_env? ) do
107
110
children =
108
- case load_app ( app , validate_compile_env? ) do
111
+ case load_app ( app , deps , lib_path , validate_compile_env? ) do
109
112
:ok ->
110
113
Application . spec ( app , :applications ) ++ Application . spec ( app , :included_applications )
111
114
@@ -143,14 +146,12 @@ defmodule Mix.Tasks.Compile.All do
143
146
end
144
147
end
145
148
146
- defp load_app ( app , validate_compile_env? ) do
149
+ defp load_app ( app , deps , lib_path , validate_compile_env? ) do
147
150
if Application . spec ( app , :vsn ) do
148
151
:ok
149
152
else
150
- name = Atom . to_charlist ( app ) ++ '.app'
151
-
152
- with [ _ | _ ] = path <- :code . where_is_file ( name ) ,
153
- { :ok , { :application , _ , properties } = application_data } <- consult_app_file ( path ) ,
153
+ with { :ok , bin } <- read_app ( app , deps , lib_path ) ,
154
+ { :ok , { :application , _ , properties } = application_data } <- consult_app_file ( bin ) ,
154
155
:ok <- :application . load ( application_data ) do
155
156
if compile_env = validate_compile_env? && properties [ :compile_env ] do
156
157
Config.Provider . validate_compile_env ( compile_env , false )
@@ -163,10 +164,22 @@ defmodule Mix.Tasks.Compile.All do
163
164
end
164
165
end
165
166
166
- defp consult_app_file ( path ) do
167
+ # Optimize the ones coming from deps by avoiding code/erl_prim_loader
168
+ defp read_app ( app , deps , lib_path ) when is_map_key ( deps , app ) do
169
+ File . read ( "#{ lib_path } /#{ app } /ebin/#{ app } .app" )
170
+ end
171
+
172
+ defp read_app ( app , _deps , _lib_path ) do
173
+ name = Atom . to_charlist ( app ) ++ '.app'
174
+
175
+ with [ _ | _ ] = path <- :code . where_is_file ( name ) ,
176
+ { :ok , bin , _full_name } <- :erl_prim_loader . get_file ( path ) ,
177
+ do: { :ok , bin }
178
+ end
179
+
180
+ defp consult_app_file ( bin ) do
167
181
# The path could be located in an .ez archive, so we use the prim loader.
168
- with { :ok , bin , _full_name } <- :erl_prim_loader . get_file ( path ) ,
169
- { :ok , tokens , _ } <- :erl_scan . string ( String . to_charlist ( bin ) ) do
182
+ with { :ok , tokens , _ } <- :erl_scan . string ( String . to_charlist ( bin ) ) do
170
183
:erl_parse . parse_term ( tokens )
171
184
end
172
185
end
0 commit comments