beamPackages.mixRelease: remove erlang references from output

This commit is contained in:
c4710n 2023-12-03 14:21:39 +08:00 committed by Yt
parent 4600a9d607
commit e924d0f542

View file

@ -8,6 +8,8 @@
, rebar3 , rebar3
, fetchMixDeps , fetchMixDeps
, findutils , findutils
, ripgrep
, bbe
, makeWrapper , makeWrapper
, coreutils , coreutils
, gnused , gnused
@ -42,6 +44,7 @@
, mixNixDeps ? { } , mixNixDeps ? { }
, elixir ? inputs.elixir , elixir ? inputs.elixir
, erlang ? inputs.erlang
, hex ? inputs.hex.override { inherit elixir; } , hex ? inputs.hex.override { inherit elixir; }
# Remove releases/COOKIE # Remove releases/COOKIE
@ -81,7 +84,7 @@ stdenv.mkDerivation (overridable // {
# Mix deps # Mix deps
(builtins.attrValues mixNixDeps) ++ (builtins.attrValues mixNixDeps) ++
# other compile-time deps # other compile-time deps
[ findutils makeWrapper ]; [ findutils ripgrep bbe makeWrapper ];
buildInputs = buildInputs; buildInputs = buildInputs;
@ -95,7 +98,11 @@ stdenv.mkDerivation (overridable // {
MIX_REBAR = "${rebar}/bin/rebar"; MIX_REBAR = "${rebar}/bin/rebar";
MIX_REBAR3 = "${rebar3}/bin/rebar3"; MIX_REBAR3 = "${rebar3}/bin/rebar3";
ERL_COMPILER_OPTIONS = "[${lib.strings.concatStringsSep "," ([ "deterministic" ] ++ erlangCompilerOptions)}]"; ERL_COMPILER_OPTIONS =
let
options = [ "deterministic" ] ++ erlangCompilerOptions;
in
"[${lib.concatStringsSep "," options}]";
LC_ALL = "C.UTF-8"; LC_ALL = "C.UTF-8";
@ -169,10 +176,10 @@ stdenv.mkDerivation (overridable // {
''; '';
postFixup = '' postFixup = ''
# Remove files for Microsoft Windows echo "removing files for Microsoft Windows"
rm -f "$out"/bin/*.bat rm -f "$out"/bin/*.bat
# Wrap programs in $out/bin with their runtime deps echo "wrapping programs in $out/bin with their runtime deps"
for f in $(find $out/bin/ -type f -executable); do for f in $(find $out/bin/ -type f -executable); do
wrapProgram "$f" \ wrapProgram "$f" \
--prefix PATH : ${lib.makeBinPath [ --prefix PATH : ${lib.makeBinPath [
@ -184,34 +191,41 @@ stdenv.mkDerivation (overridable // {
done done
'' + lib.optionalString removeCookie '' '' + lib.optionalString removeCookie ''
if [ -e $out/releases/COOKIE ]; then if [ -e $out/releases/COOKIE ]; then
echo "removing $out/releases/COOKIE"
rm $out/releases/COOKIE rm $out/releases/COOKIE
fi 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 '' '' + lib.optionalString stripDebug ''
# Strip debug symbols to avoid hardreferences to "foreign" closures actually # Strip debug symbols to avoid hardreferences to "foreign" closures actually
# not needed at runtime, while at the same time reduce size of BEAM files. # 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 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
''; '';
# TODO: remove erlang references in resulting derivation
#
# # Step 1 - investigate why the resulting derivation still has references to erlang.
#
# The reason is that the generated binaries contains erlang reference. Here's a repo to
# demonstrate the problem - <https://github.com/plastic-gun/nix-mix-release-unwanted-references>.
#
#
# # Step 2 - remove erlang references from the binaries
#
# As said in above repo, it's hard to remove erlang references from `.beam` binaries.
#
# We need more experienced developers to resolve this issue.
#
#
# # Tips
#
# When resolving this issue, it is convenient to fail the build when erlang is referenced,
# which can be achieved by using:
#
# disallowedReferences = [ erlang ];
#
}) })