mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-23 07:23:20 +00:00
Merge pull request #329828 from mattpolzin/mix-release-named
beamPackages.mixRelease: support named releases
This commit is contained in:
commit
88733d6c42
@ -1,56 +1,61 @@
|
|||||||
{ stdenv
|
{
|
||||||
, lib
|
stdenv,
|
||||||
, elixir
|
lib,
|
||||||
, erlang
|
elixir,
|
||||||
, hex
|
erlang,
|
||||||
, git
|
hex,
|
||||||
, rebar
|
git,
|
||||||
, rebar3
|
rebar,
|
||||||
, fetchMixDeps
|
rebar3,
|
||||||
, findutils
|
fetchMixDeps,
|
||||||
, ripgrep
|
findutils,
|
||||||
, bbe
|
ripgrep,
|
||||||
, makeWrapper
|
bbe,
|
||||||
, coreutils
|
makeWrapper,
|
||||||
, gnused
|
coreutils,
|
||||||
, gnugrep
|
gnused,
|
||||||
, gawk
|
gnugrep,
|
||||||
|
gawk,
|
||||||
}@inputs:
|
}@inputs:
|
||||||
|
|
||||||
{ pname
|
{
|
||||||
, version
|
pname,
|
||||||
, src
|
version,
|
||||||
, nativeBuildInputs ? [ ]
|
src,
|
||||||
, buildInputs ? [ ]
|
nativeBuildInputs ? [ ],
|
||||||
, meta ? { }
|
buildInputs ? [ ],
|
||||||
, enableDebugInfo ? false
|
meta ? { },
|
||||||
, mixEnv ? "prod"
|
enableDebugInfo ? false,
|
||||||
, compileFlags ? [ ]
|
mixEnv ? "prod",
|
||||||
|
compileFlags ? [ ],
|
||||||
|
# Build a particular named release.
|
||||||
|
# see https://hexdocs.pm/mix/1.12/Mix.Tasks.Release.html#content
|
||||||
|
mixReleaseName ? "",
|
||||||
|
|
||||||
# Options to be passed to the Erlang compiler. As documented in the reference
|
# Options to be passed to the Erlang compiler. As documented in the reference
|
||||||
# manual, these must be valid Erlang terms. They will be turned into an
|
# manual, these must be valid Erlang terms. They will be turned into an
|
||||||
# erlang list and set as the ERL_COMPILER_OPTIONS environment variable.
|
# erlang list and set as the ERL_COMPILER_OPTIONS environment variable.
|
||||||
# See https://www.erlang.org/doc/man/compile
|
# See https://www.erlang.org/doc/man/compile
|
||||||
, erlangCompilerOptions ? [ ]
|
erlangCompilerOptions ? [ ],
|
||||||
|
|
||||||
# Deterministic Erlang builds remove full system paths from debug information
|
# Deterministic Erlang builds remove full system paths from debug information
|
||||||
# among other things to keep builds more reproducible. See their docs for more:
|
# among other things to keep builds more reproducible. See their docs for more:
|
||||||
# https://www.erlang.org/doc/man/compile
|
# https://www.erlang.org/doc/man/compile
|
||||||
, erlangDeterministicBuilds ? true
|
erlangDeterministicBuilds ? true,
|
||||||
|
|
||||||
# Mix dependencies provided as a fixed output derivation
|
# Mix dependencies provided as a fixed output derivation
|
||||||
, mixFodDeps ? null
|
mixFodDeps ? null,
|
||||||
|
|
||||||
# Mix dependencies generated by mix2nix
|
# Mix dependencies generated by mix2nix
|
||||||
#
|
#
|
||||||
# This assumes each dependency is built by buildMix or buildRebar3. Each
|
# This assumes each dependency is built by buildMix or buildRebar3. Each
|
||||||
# dependency needs to have a setup hook to add the lib path to $ERL_LIBS.
|
# dependency needs to have a setup hook to add the lib path to $ERL_LIBS.
|
||||||
# This is how Mix finds dependencies.
|
# This is how Mix finds dependencies.
|
||||||
, mixNixDeps ? { }
|
mixNixDeps ? { },
|
||||||
|
|
||||||
, elixir ? inputs.elixir
|
elixir ? inputs.elixir,
|
||||||
, erlang ? inputs.erlang
|
erlang ? inputs.erlang,
|
||||||
, hex ? inputs.hex.override { inherit elixir; }
|
hex ? inputs.hex.override { inherit elixir; },
|
||||||
|
|
||||||
# Remove releases/COOKIE
|
# Remove releases/COOKIE
|
||||||
#
|
#
|
||||||
@ -65,172 +70,204 @@
|
|||||||
#
|
#
|
||||||
# You can always specify a custom cookie by using RELEASE_COOKIE environment
|
# You can always specify a custom cookie by using RELEASE_COOKIE environment
|
||||||
# variable, regardless of the value of this attr.
|
# variable, regardless of the value of this attr.
|
||||||
, removeCookie ? true
|
removeCookie ? true,
|
||||||
|
|
||||||
# This reduces closure size, but can lead to some hard to understand runtime
|
# This reduces closure size, but can lead to some hard to understand runtime
|
||||||
# errors, so use with caution. See e.g.
|
# errors, so use with caution. See e.g.
|
||||||
# https://github.com/whitfin/cachex/issues/205
|
# https://github.com/whitfin/cachex/issues/205
|
||||||
# https://framagit.org/framasoft/mobilizon/-/issues/1169
|
# https://framagit.org/framasoft/mobilizon/-/issues/1169
|
||||||
, stripDebug ? false
|
stripDebug ? false,
|
||||||
|
|
||||||
, ...
|
...
|
||||||
}@attrs:
|
}@attrs:
|
||||||
let
|
let
|
||||||
# Remove non standard attributes that cannot be coerced to strings
|
# Remove non standard attributes that cannot be coerced to strings
|
||||||
overridable = builtins.removeAttrs attrs [ "compileFlags" "erlangCompilerOptions" "mixNixDeps" ];
|
overridable = builtins.removeAttrs attrs [
|
||||||
|
"compileFlags"
|
||||||
|
"erlangCompilerOptions"
|
||||||
|
"mixNixDeps"
|
||||||
|
];
|
||||||
in
|
in
|
||||||
assert mixNixDeps != { } -> mixFodDeps == null;
|
assert mixNixDeps != { } -> mixFodDeps == null;
|
||||||
assert stripDebug -> !enableDebugInfo;
|
assert stripDebug -> !enableDebugInfo;
|
||||||
|
|
||||||
stdenv.mkDerivation (overridable // {
|
stdenv.mkDerivation (
|
||||||
nativeBuildInputs = nativeBuildInputs ++
|
overridable
|
||||||
# Erlang/Elixir deps
|
// {
|
||||||
[ erlang elixir hex git ] ++
|
nativeBuildInputs =
|
||||||
# Mix deps
|
nativeBuildInputs
|
||||||
(builtins.attrValues mixNixDeps) ++
|
++
|
||||||
# other compile-time deps
|
# Erlang/Elixir deps
|
||||||
[ findutils ripgrep bbe makeWrapper ];
|
[
|
||||||
|
erlang
|
||||||
|
elixir
|
||||||
|
hex
|
||||||
|
git
|
||||||
|
]
|
||||||
|
++
|
||||||
|
# Mix deps
|
||||||
|
(builtins.attrValues mixNixDeps)
|
||||||
|
++
|
||||||
|
# other compile-time deps
|
||||||
|
[
|
||||||
|
findutils
|
||||||
|
ripgrep
|
||||||
|
bbe
|
||||||
|
makeWrapper
|
||||||
|
];
|
||||||
|
|
||||||
buildInputs = buildInputs;
|
buildInputs = buildInputs;
|
||||||
|
|
||||||
MIX_ENV = mixEnv;
|
MIX_ENV = mixEnv;
|
||||||
MIX_DEBUG = if enableDebugInfo then 1 else 0;
|
MIX_DEBUG = if enableDebugInfo then 1 else 0;
|
||||||
HEX_OFFLINE = 1;
|
HEX_OFFLINE = 1;
|
||||||
|
|
||||||
DEBUG = if enableDebugInfo then 1 else 0; # for Rebar3 compilation
|
DEBUG = if enableDebugInfo then 1 else 0; # for Rebar3 compilation
|
||||||
# The API with `mix local.rebar rebar path` makes a copy of the binary
|
# The API with `mix local.rebar rebar path` makes a copy of the binary
|
||||||
# some older dependencies still use rebar.
|
# some older dependencies still use rebar.
|
||||||
MIX_REBAR = "${rebar}/bin/rebar";
|
MIX_REBAR = "${rebar}/bin/rebar";
|
||||||
MIX_REBAR3 = "${rebar3}/bin/rebar3";
|
MIX_REBAR3 = "${rebar3}/bin/rebar3";
|
||||||
|
|
||||||
ERL_COMPILER_OPTIONS =
|
ERL_COMPILER_OPTIONS =
|
||||||
let
|
let
|
||||||
options = erlangCompilerOptions ++ lib.optionals erlangDeterministicBuilds [ "deterministic" ];
|
options = erlangCompilerOptions ++ lib.optionals erlangDeterministicBuilds [ "deterministic" ];
|
||||||
in
|
in
|
||||||
"[${lib.concatStringsSep "," options}]";
|
"[${lib.concatStringsSep "," options}]";
|
||||||
|
|
||||||
LC_ALL = "C.UTF-8";
|
LC_ALL = "C.UTF-8";
|
||||||
|
|
||||||
postUnpack = ''
|
postUnpack =
|
||||||
# Mix and Hex
|
''
|
||||||
export MIX_HOME="$TEMPDIR/mix"
|
# Mix and Hex
|
||||||
export HEX_HOME="$TEMPDIR/hex"
|
export MIX_HOME="$TEMPDIR/mix"
|
||||||
|
export HEX_HOME="$TEMPDIR/hex"
|
||||||
|
|
||||||
# Rebar
|
# Rebar
|
||||||
export REBAR_GLOBAL_CONFIG_DIR="$TEMPDIR/rebar3"
|
export REBAR_GLOBAL_CONFIG_DIR="$TEMPDIR/rebar3"
|
||||||
export REBAR_CACHE_DIR="$TEMPDIR/rebar3.cache"
|
export REBAR_CACHE_DIR="$TEMPDIR/rebar3.cache"
|
||||||
|
|
||||||
${lib.optionalString (mixFodDeps != null) ''
|
${lib.optionalString (mixFodDeps != null) ''
|
||||||
# Compilation of the dependencies will require that the dependency path is
|
# Compilation of the dependencies will require that the dependency path is
|
||||||
# writable, thus a copy to the $TEMPDIR is inevitable here.
|
# writable, thus a copy to the $TEMPDIR is inevitable here.
|
||||||
export MIX_DEPS_PATH="$TEMPDIR/deps"
|
export MIX_DEPS_PATH="$TEMPDIR/deps"
|
||||||
cp --no-preserve=mode -R "${mixFodDeps}" "$MIX_DEPS_PATH"
|
cp --no-preserve=mode -R "${mixFodDeps}" "$MIX_DEPS_PATH"
|
||||||
''}
|
''}
|
||||||
'' + (attrs.postUnpack or "");
|
''
|
||||||
|
+ (attrs.postUnpack or "");
|
||||||
|
|
||||||
configurePhase = attrs.configurePhase or ''
|
configurePhase =
|
||||||
runHook preConfigure
|
attrs.configurePhase or ''
|
||||||
|
runHook preConfigure
|
||||||
|
|
||||||
${./mix-configure-hook.sh}
|
${./mix-configure-hook.sh}
|
||||||
|
|
||||||
# This is needed for projects that have a specific compile step
|
# This is needed for projects that have a specific compile step
|
||||||
# the dependency needs to be compiled in order for the task
|
# the dependency needs to be compiled in order for the task
|
||||||
# to be available.
|
# to be available.
|
||||||
#
|
#
|
||||||
# Phoenix projects for example will need compile.phoenix.
|
# Phoenix projects for example will need compile.phoenix.
|
||||||
mix deps.compile --no-deps-check --skip-umbrella-children
|
mix deps.compile --no-deps-check --skip-umbrella-children
|
||||||
|
|
||||||
# Symlink dependency sources. This is needed for projects that require
|
# Symlink dependency sources. This is needed for projects that require
|
||||||
# access to the source of their dependencies. For example, Phoenix
|
# access to the source of their dependencies. For example, Phoenix
|
||||||
# projects need javascript assets to build asset bundles.
|
# projects need javascript assets to build asset bundles.
|
||||||
${lib.optionalString (mixNixDeps != { }) ''
|
${lib.optionalString (mixNixDeps != { }) ''
|
||||||
mkdir -p deps
|
mkdir -p deps
|
||||||
|
|
||||||
${lib.concatMapStringsSep "\n" (dep: ''
|
${lib.concatMapStringsSep "\n" (dep: ''
|
||||||
dep_name=$(basename ${dep} | cut -d '-' -f2)
|
dep_name=$(basename ${dep} | cut -d '-' -f2)
|
||||||
dep_path="deps/$dep_name"
|
dep_path="deps/$dep_name"
|
||||||
if [ -d "${dep}/src" ]; then
|
if [ -d "${dep}/src" ]; then
|
||||||
ln -s ${dep}/src $dep_path
|
ln -s ${dep}/src $dep_path
|
||||||
|
fi
|
||||||
|
'') (builtins.attrValues mixNixDeps)}
|
||||||
|
''}
|
||||||
|
|
||||||
|
# Symlink deps to build root. Similar to above, but allows for mixFodDeps
|
||||||
|
# Phoenix projects to find javascript assets.
|
||||||
|
${lib.optionalString (mixFodDeps != null) ''
|
||||||
|
ln -s ../deps ./
|
||||||
|
''}
|
||||||
|
|
||||||
|
runHook postConfigure
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildPhase =
|
||||||
|
attrs.buildPhase or ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
mix compile --no-deps-check ${lib.concatStringsSep " " compileFlags}
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase =
|
||||||
|
attrs.installPhase or ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mix release ${mixReleaseName} --no-deps-check --path "$out"
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
postFixup =
|
||||||
|
''
|
||||||
|
echo "removing files for Microsoft Windows"
|
||||||
|
rm -f "$out"/bin/*.bat
|
||||||
|
|
||||||
|
echo "wrapping programs in $out/bin with their runtime deps"
|
||||||
|
for f in $(find $out/bin/ -type f -executable); do
|
||||||
|
wrapProgram "$f" \
|
||||||
|
--prefix PATH : ${
|
||||||
|
lib.makeBinPath [
|
||||||
|
coreutils
|
||||||
|
gnused
|
||||||
|
gnugrep
|
||||||
|
gawk
|
||||||
|
]
|
||||||
|
}
|
||||||
|
done
|
||||||
|
''
|
||||||
|
+ lib.optionalString removeCookie ''
|
||||||
|
if [ -e $out/releases/COOKIE ]; then
|
||||||
|
echo "removing $out/releases/COOKIE"
|
||||||
|
rm $out/releases/COOKIE
|
||||||
fi
|
fi
|
||||||
'') (builtins.attrValues mixNixDeps)}
|
''
|
||||||
''}
|
+ ''
|
||||||
|
if [ -e $out/erts-* ]; then
|
||||||
|
# ERTS is included in the release, then erlang is not required as a runtime dependency.
|
||||||
|
# But, erlang is still referenced in some places. To removed references to erlang,
|
||||||
|
# following steps are required.
|
||||||
|
|
||||||
# Symlink deps to build root. Similar to above, but allows for mixFodDeps
|
# 1. remove references to erlang from plain text files
|
||||||
# Phoenix projects to find javascript assets.
|
for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches); do
|
||||||
${lib.optionalString (mixFodDeps != null) ''
|
echo "removing references to erlang in $file"
|
||||||
ln -s ../deps ./
|
substituteInPlace "$file" --replace "${erlang}/lib/erlang" "$out"
|
||||||
''}
|
done
|
||||||
|
|
||||||
runHook postConfigure
|
# 2. remove references to erlang from .beam files
|
||||||
'';
|
#
|
||||||
|
# No need to do anything, because it has been handled by "deterministic" option specified
|
||||||
|
# by ERL_COMPILER_OPTIONS.
|
||||||
|
|
||||||
buildPhase = attrs.buildPhase or ''
|
# 3. remove references to erlang from normal binary files
|
||||||
runHook preBuild
|
for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches --binary --iglob '!*.beam'); do
|
||||||
|
echo "removing references to erlang in $file"
|
||||||
|
# use bbe to substitute strings in binary files, because using substituteInPlace
|
||||||
|
# on binaries will raise errors
|
||||||
|
bbe -e "s|${erlang}/lib/erlang|$out|" -o "$file".tmp "$file"
|
||||||
|
rm -f "$file"
|
||||||
|
mv "$file".tmp "$file"
|
||||||
|
done
|
||||||
|
|
||||||
mix compile --no-deps-check ${lib.concatStringsSep " " compileFlags}
|
# References to erlang should be removed from output after above processing.
|
||||||
|
fi
|
||||||
runHook postBuild
|
''
|
||||||
'';
|
+ lib.optionalString stripDebug ''
|
||||||
|
# Strip debug symbols to avoid hardreferences to "foreign" closures actually
|
||||||
installPhase = attrs.installPhase or ''
|
# not needed at runtime, while at the same time reduce size of BEAM files.
|
||||||
runHook preInstall
|
erl -noinput -eval 'lists:foreach(fun(F) -> io:format("Stripping ~p.~n", [F]), beam_lib:strip(F) end, filelib:wildcard("'"$out"'/**/*.beam"))' -s init stop
|
||||||
|
'';
|
||||||
mix release --no-deps-check --path "$out"
|
}
|
||||||
|
)
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
postFixup = ''
|
|
||||||
echo "removing files for Microsoft Windows"
|
|
||||||
rm -f "$out"/bin/*.bat
|
|
||||||
|
|
||||||
echo "wrapping programs in $out/bin with their runtime deps"
|
|
||||||
for f in $(find $out/bin/ -type f -executable); do
|
|
||||||
wrapProgram "$f" \
|
|
||||||
--prefix PATH : ${lib.makeBinPath [
|
|
||||||
coreutils
|
|
||||||
gnused
|
|
||||||
gnugrep
|
|
||||||
gawk
|
|
||||||
]}
|
|
||||||
done
|
|
||||||
'' + lib.optionalString removeCookie ''
|
|
||||||
if [ -e $out/releases/COOKIE ]; then
|
|
||||||
echo "removing $out/releases/COOKIE"
|
|
||||||
rm $out/releases/COOKIE
|
|
||||||
fi
|
|
||||||
'' + ''
|
|
||||||
if [ -e $out/erts-* ]; then
|
|
||||||
# ERTS is included in the release, then erlang is not required as a runtime dependency.
|
|
||||||
# But, erlang is still referenced in some places. To removed references to erlang,
|
|
||||||
# following steps are required.
|
|
||||||
|
|
||||||
# 1. remove references to erlang from plain text files
|
|
||||||
for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches); do
|
|
||||||
echo "removing references to erlang in $file"
|
|
||||||
substituteInPlace "$file" --replace "${erlang}/lib/erlang" "$out"
|
|
||||||
done
|
|
||||||
|
|
||||||
# 2. remove references to erlang from .beam files
|
|
||||||
#
|
|
||||||
# No need to do anything, because it has been handled by "deterministic" option specified
|
|
||||||
# by ERL_COMPILER_OPTIONS.
|
|
||||||
|
|
||||||
# 3. remove references to erlang from normal binary files
|
|
||||||
for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches --binary --iglob '!*.beam'); do
|
|
||||||
echo "removing references to erlang in $file"
|
|
||||||
# use bbe to substitute strings in binary files, because using substituteInPlace
|
|
||||||
# on binaries will raise errors
|
|
||||||
bbe -e "s|${erlang}/lib/erlang|$out|" -o "$file".tmp "$file"
|
|
||||||
rm -f "$file"
|
|
||||||
mv "$file".tmp "$file"
|
|
||||||
done
|
|
||||||
|
|
||||||
# References to erlang should be removed from output after above processing.
|
|
||||||
fi
|
|
||||||
'' + lib.optionalString stripDebug ''
|
|
||||||
# Strip debug symbols to avoid hardreferences to "foreign" closures actually
|
|
||||||
# not needed at runtime, while at the same time reduce size of BEAM files.
|
|
||||||
erl -noinput -eval 'lists:foreach(fun(F) -> io:format("Stripping ~p.~n", [F]), beam_lib:strip(F) end, filelib:wildcard("'"$out"'/**/*.beam"))' -s init stop
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
|
Loading…
Reference in New Issue
Block a user