-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathelixir_make.precompile.ex
More file actions
102 lines (78 loc) · 2.83 KB
/
elixir_make.precompile.ex
File metadata and controls
102 lines (78 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
defmodule Mix.Tasks.ElixirMake.Precompile do
@shortdoc "Precompiles the given project for all targets"
@moduledoc """
Precompiles the given project for all targets.
This task must only be used by package creators who want to ship the
precompiled NIFs. This task is often used on CI to precompile
for different targets.
This is only supported if `:make_precompiler` is specified
in your project configuration.
"""
alias ElixirMake.Artefact
use Mix.Task
@recursive true
@impl true
def run(args) do
if function_exported?(Mix, :ensure_application!, 1) do
Mix.ensure_application!(:inets)
Mix.ensure_application!(:ssl)
Mix.ensure_application!(:crypto)
end
config = Mix.Project.config()
paths = config[:make_precompiler_priv_paths] || ["."]
{_, precompiler} =
config[:make_precompiler] ||
Mix.raise(
":make_precompiler project configuration is required when using elixir_make.precompile"
)
targets = precompiler.all_supported_targets(:compile)
try do
precompiled_artefacts =
Enum.map(targets, fn target ->
case precompiler.precompile(args, target) do
:ok ->
precompiled_artefacts = create_precompiled_archive(config, target, paths)
if function_exported?(precompiler, :post_precompile_target, 1) do
precompiler.post_precompile_target(target)
end
Artefact.write_checksum_for_target!(precompiled_artefacts)
precompiled_artefacts
{:error, msg} ->
Mix.raise(msg)
end
end)
Artefact.write_checksums!(precompiled_artefacts)
if function_exported?(precompiler, :post_precompile, 0) do
precompiler.post_precompile()
else
:ok
end
after
app_priv = Path.join(Mix.Project.app_path(config), "priv")
for include <- paths,
file <- Path.wildcard(Path.join(app_priv, include)) do
File.rm_rf(file)
end
end
end
defp create_precompiled_archive(config, target, paths) do
archive_path = Artefact.archive_path(config, target, :erlang.system_info(:nif_version))
Mix.shell().info("Creating precompiled archive: #{archive_path}")
Mix.shell().info("Paths to archive from priv directory: #{inspect(paths)}")
app_priv = Path.join(Mix.Project.app_path(config), "priv")
File.mkdir_p!(app_priv)
File.mkdir_p!(Path.dirname(archive_path))
artefact =
File.cd!(app_priv, fn ->
filepaths =
for path <- paths,
entry <- Path.wildcard(path),
do: String.to_charlist(entry)
Artefact.compress(archive_path, filepaths)
end)
Mix.shell().info(
"NIF cached at #{archive_path} with checksum #{artefact.checksum} (#{artefact.checksum_algo})"
)
artefact
end
end