@@ -15,40 +15,44 @@ defmodule Kernel.ParallelCompiler do
15
15
is set to `true` and there is a warning, this function will fail
16
16
with an exception.
17
17
18
- This function receives a set of callbacks as options:
18
+ This function accepts the following options:
19
19
20
20
* `:each_file` - for each file compiled, invokes the callback passing the
21
21
file
22
22
23
23
* `:each_module` - for each module compiled, invokes the callback passing
24
24
the file, module and the module bytecode
25
25
26
- The compiler doesn't care about the return values of the callbacks.
26
+ * `:dest` - the destination directory for the beam files. When using `files/2`,
27
+ this information is only used to properly annotate the beam files before
28
+ they are loaded into memory. If you want a file to actually be writen to
29
+ `dest`, use `files_to_path/3` instead.
30
+
27
31
Returns the modules generated by each compiled file.
28
32
"""
29
- def files ( files , callbacks \\ [ ] )
33
+ def files ( files , options \\ [ ] )
30
34
31
- def files ( files , callbacks ) when is_list ( callbacks ) do
32
- spawn_compilers ( files , nil , callbacks )
35
+ def files ( files , options ) when is_list ( options ) do
36
+ spawn_compilers ( files , nil , options )
33
37
end
34
38
35
39
@ doc """
36
40
Compiles the given files to the given path.
37
41
Read `files/2` for more information.
38
42
"""
39
- def files_to_path ( files , path , callbacks \\ [ ] )
43
+ def files_to_path ( files , path , options \\ [ ] )
40
44
41
- def files_to_path ( files , path , callbacks ) when is_binary ( path ) and is_list ( callbacks ) do
42
- spawn_compilers ( files , path , callbacks )
45
+ def files_to_path ( files , path , options ) when is_binary ( path ) and is_list ( options ) do
46
+ spawn_compilers ( files , path , options )
43
47
end
44
48
45
- defp spawn_compilers ( files , path , callbacks ) do
49
+ defp spawn_compilers ( files , path , options ) do
46
50
true = Code . ensure_loaded? ( Kernel.ErrorHandler )
47
51
compiler_pid = self ( )
48
52
:elixir_code_server . cast ( { :reset_warnings , compiler_pid } )
49
53
schedulers = max ( :erlang . system_info ( :schedulers_online ) , 2 )
50
54
51
- result = spawn_compilers ( files , files , path , callbacks , [ ] , [ ] , schedulers , [ ] )
55
+ result = spawn_compilers ( files , files , path , options , [ ] , [ ] , schedulers , [ ] )
52
56
53
57
# In case --warning-as-errors is enabled and there was a warning,
54
58
# compilation status will be set to error and we fail with CompileError
@@ -59,21 +63,21 @@ defmodule Kernel.ParallelCompiler do
59
63
end
60
64
61
65
# We already have 4 currently running, don't spawn new ones
62
- defp spawn_compilers ( entries , original , output , callbacks , waiting , queued , schedulers , result ) when
66
+ defp spawn_compilers ( entries , original , output , options , waiting , queued , schedulers , result ) when
63
67
length ( queued ) - length ( waiting ) >= schedulers do
64
- wait_for_messages ( entries , original , output , callbacks , waiting , queued , schedulers , result )
68
+ wait_for_messages ( entries , original , output , options , waiting , queued , schedulers , result )
65
69
end
66
70
67
71
# Release waiting processes
68
- defp spawn_compilers ( [ h | t ] , original , output , callbacks , waiting , queued , schedulers , result ) when is_pid ( h ) do
72
+ defp spawn_compilers ( [ h | t ] , original , output , options , waiting , queued , schedulers , result ) when is_pid ( h ) do
69
73
{ _kind , ^ h , ref , _module } = List . keyfind ( waiting , h , 1 )
70
74
send h , { ref , :ready }
71
75
waiting = List . keydelete ( waiting , h , 1 )
72
- spawn_compilers ( t , original , output , callbacks , waiting , queued , schedulers , result )
76
+ spawn_compilers ( t , original , output , options , waiting , queued , schedulers , result )
73
77
end
74
78
75
79
# Spawn a compiler for each file in the list until we reach the limit
76
- defp spawn_compilers ( [ h | t ] , original , output , callbacks , waiting , queued , schedulers , result ) do
80
+ defp spawn_compilers ( [ h | t ] , original , output , options , waiting , queued , schedulers , result ) do
77
81
parent = self ( )
78
82
79
83
{ pid , ref } =
@@ -90,7 +94,7 @@ defmodule Kernel.ParallelCompiler do
90
94
_ = if output do
91
95
:elixir_compiler . file_to_path ( h , output )
92
96
else
93
- :elixir_compiler . file ( h )
97
+ :elixir_compiler . file ( h , Keyword . get ( options , :dest ) )
94
98
end
95
99
{ :compiled , h }
96
100
catch
@@ -99,43 +103,43 @@ defmodule Kernel.ParallelCompiler do
99
103
end )
100
104
end
101
105
102
- spawn_compilers ( t , original , output , callbacks , waiting ,
106
+ spawn_compilers ( t , original , output , options , waiting ,
103
107
[ { pid , ref , h } | queued ] , schedulers , result )
104
108
end
105
109
106
110
# No more files, nothing waiting, queue is empty, we are done
107
- defp spawn_compilers ( [ ] , _original , _output , _callbacks , [ ] , [ ] , _schedulers , result ) do
111
+ defp spawn_compilers ( [ ] , _original , _output , _options , [ ] , [ ] , _schedulers , result ) do
108
112
for { :module , mod } <- result , do: mod
109
113
end
110
114
111
115
# Queued x, waiting for x: POSSIBLE ERROR! Release processes so we get the failures
112
- defp spawn_compilers ( [ ] , original , output , callbacks , waiting , queued , schedulers , result ) when length ( waiting ) == length ( queued ) do
116
+ defp spawn_compilers ( [ ] , original , output , options , waiting , queued , schedulers , result ) when length ( waiting ) == length ( queued ) do
113
117
Enum . each queued , fn { child , _ , _ } ->
114
118
{ _kind , ^ child , ref , _module } = List . keyfind ( waiting , child , 1 )
115
119
send child , { ref , :release }
116
120
end
117
- wait_for_messages ( [ ] , original , output , callbacks , waiting , queued , schedulers , result )
121
+ wait_for_messages ( [ ] , original , output , options , waiting , queued , schedulers , result )
118
122
end
119
123
120
124
# No more files, but queue and waiting are not full or do not match
121
- defp spawn_compilers ( [ ] , original , output , callbacks , waiting , queued , schedulers , result ) do
122
- wait_for_messages ( [ ] , original , output , callbacks , waiting , queued , schedulers , result )
125
+ defp spawn_compilers ( [ ] , original , output , options , waiting , queued , schedulers , result ) do
126
+ wait_for_messages ( [ ] , original , output , options , waiting , queued , schedulers , result )
123
127
end
124
128
125
129
# Wait for messages from child processes
126
- defp wait_for_messages ( entries , original , output , callbacks , waiting , queued , schedulers , result ) do
130
+ defp wait_for_messages ( entries , original , output , options , waiting , queued , schedulers , result ) do
127
131
receive do
128
132
{ :struct_available , module } ->
129
133
available = for { :struct , pid , _ , waiting_module } <- waiting ,
130
134
module == waiting_module ,
131
135
not pid in entries ,
132
136
do: pid
133
137
134
- spawn_compilers ( available ++ entries , original , output , callbacks ,
138
+ spawn_compilers ( available ++ entries , original , output , options ,
135
139
waiting , queued , schedulers , [ { :struct , module } | result ] )
136
140
137
141
{ :module_available , child , ref , file , module , binary } ->
138
- if callback = Keyword . get ( callbacks , :each_module ) do
142
+ if callback = Keyword . get ( options , :each_module ) do
139
143
callback . ( file , module , binary )
140
144
end
141
145
@@ -147,7 +151,7 @@ defmodule Kernel.ParallelCompiler do
147
151
not pid in entries ,
148
152
do: pid
149
153
150
- spawn_compilers ( available ++ entries , original , output , callbacks ,
154
+ spawn_compilers ( available ++ entries , original , output , options ,
151
155
waiting , queued , schedulers , [ { :module , module } | result ] )
152
156
153
157
{ :waiting , kind , child , ref , on } ->
@@ -160,10 +164,10 @@ defmodule Kernel.ParallelCompiler do
160
164
waiting = [ { kind , child , ref , on } | waiting ]
161
165
end
162
166
163
- spawn_compilers ( entries , original , output , callbacks , waiting , queued , schedulers , result )
167
+ spawn_compilers ( entries , original , output , options , waiting , queued , schedulers , result )
164
168
165
169
{ :DOWN , _down_ref , :process , down_pid , { :compiled , file } } ->
166
- if callback = Keyword . get ( callbacks , :each_file ) do
170
+ if callback = Keyword . get ( options , :each_file ) do
167
171
callback . ( file )
168
172
end
169
173
@@ -172,11 +176,11 @@ defmodule Kernel.ParallelCompiler do
172
176
new_entries = List . delete ( entries , down_pid )
173
177
new_queued = List . keydelete ( queued , down_pid , 0 )
174
178
new_waiting = List . keydelete ( waiting , down_pid , 1 )
175
- spawn_compilers ( new_entries , original , output , callbacks , new_waiting , new_queued , schedulers , result )
179
+ spawn_compilers ( new_entries , original , output , options , new_waiting , new_queued , schedulers , result )
176
180
177
181
{ :DOWN , down_ref , :process , _down_pid , reason } ->
178
182
handle_failure ( down_ref , reason , entries , waiting , queued )
179
- wait_for_messages ( entries , original , output , callbacks , waiting , queued , schedulers , result )
183
+ wait_for_messages ( entries , original , output , options , waiting , queued , schedulers , result )
180
184
end
181
185
end
182
186
0 commit comments