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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
{
stdenv,
erlang,
rebar3WithPlugins,
openssl,
lib,
}:
{
pname,
version,
src,
beamDeps ? [ ],
buildPlugins ? [ ],
checkouts ? null,
releaseType,
buildInputs ? [ ],
setupHook ? null,
profile ? "default",
installPhase ? null,
buildPhase ? null,
configurePhase ? null,
meta ? { },
...
}@attrs:
let
shell =
drv:
stdenv.mkDerivation {
name = "interactive-shell-${drv.pname}";
buildInputs = [ drv ];
};
customPhases = lib.filterAttrs (_: v: v != null) {
inherit
setupHook
configurePhase
buildPhase
installPhase
;
};
# When using the `beamDeps` argument, it is important that we use
# `rebar3WithPlugins` here even when there are no plugins. The vanilla
# `rebar3` package is an escript archive with bundled dependencies which can
# interfere with those in the app we are trying to build. `rebar3WithPlugins`
# doesn't have this issue since it puts its own deps last on the code path.
rebar3 = rebar3WithPlugins {
plugins = buildPlugins;
};
pkg =
assert beamDeps != [ ] -> checkouts == null;
self:
stdenv.mkDerivation (
attrs
// {
inherit version pname;
nativeBuildInputs = (attrs.nativeBuildInputs or [ ]) ++ [
erlang
rebar3
];
buildInputs = buildInputs ++ [ openssl ] ++ beamDeps;
__structuredAttrs = true;
strictDeps = true;
# ensure we strip any native binaries (eg. NIFs, ports)
stripDebugList = lib.optional (releaseType == "release") "rel";
inherit src;
env = (attrs.env or { }) // {
REBAR_IGNORE_DEPS = beamDeps != [ ];
};
configurePhase = ''
runHook preConfigure
${lib.optionalString (checkouts != null) "cp --no-preserve=all -R ${checkouts}/_checkouts ."}
runHook postConfigure
'';
buildPhase = ''
runHook preBuild
HOME=. DEBUG=1 rebar3 as ${profile} ${if releaseType == "escript" then "escriptize" else "release"}
runHook postBuild
'';
installPhase = ''
runHook preInstall
dir=${if releaseType == "escript" then "bin" else "rel"}
mkdir -p "$out/$dir" "$out/bin"
cp -R --preserve=mode "_build/${profile}/$dir" "$out"
${lib.optionalString (
releaseType == "release"
) "find $out/rel/*/bin -type f -executable -exec ln -s -t $out/bin {} \\;"}
runHook postInstall
'';
# Release will generate a binary which will cause a read null byte failure, see #261354
postInstall = lib.optionalString (releaseType == "escript") ''
for dir in $out/rel/*/erts-*; do
echo "ERTS found in $dir - removing references to erlang to reduce closure size"
for f in $dir/bin/{erl,start}; do
substituteInPlace "$f" --replace "${erlang}/lib/erlang" "''${dir/\/erts-*/}"
done
done
'';
meta = {
inherit (erlang.meta) platforms;
}
// meta;
passthru = (
{
packageName = pname;
env = shell self;
}
// (if attrs ? passthru then attrs.passthru else { })
);
}
// customPhases
);
in
lib.fix pkg
|