diff --git a/pkgs/development/beam-modules/mix-release.nix b/pkgs/development/beam-modules/mix-release.nix index 2248dce7a76b..b25c609bd3bc 100644 --- a/pkgs/development/beam-modules/mix-release.nix +++ b/pkgs/development/beam-modules/mix-release.nix @@ -8,6 +8,8 @@ , rebar3 , fetchMixDeps , findutils +, ripgrep +, bbe , makeWrapper , coreutils , gnused @@ -42,6 +44,7 @@ , mixNixDeps ? { } , elixir ? inputs.elixir +, erlang ? inputs.erlang , hex ? inputs.hex.override { inherit elixir; } # Remove releases/COOKIE @@ -81,7 +84,7 @@ stdenv.mkDerivation (overridable // { # Mix deps (builtins.attrValues mixNixDeps) ++ # other compile-time deps - [ findutils makeWrapper ]; + [ findutils ripgrep bbe makeWrapper ]; buildInputs = buildInputs; @@ -95,7 +98,11 @@ stdenv.mkDerivation (overridable // { MIX_REBAR = "${rebar}/bin/rebar"; 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"; @@ -169,10 +176,10 @@ stdenv.mkDerivation (overridable // { ''; postFixup = '' - # Remove files for Microsoft Windows + echo "removing files for Microsoft Windows" 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 wrapProgram "$f" \ --prefix PATH : ${lib.makeBinPath [ @@ -184,34 +191,41 @@ stdenv.mkDerivation (overridable // { 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 ''; - - # 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 - . - # - # - # # 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 ]; - # })