about summary refs log tree commit diff
path: root/pkgs/development/beam-modules
diff options
context:
space:
mode:
authorc4710n <c4710n@users.noreply.github.com>2023-12-03 14:21:39 +0800
committerYt <happysalada@tuta.io>2023-12-08 07:23:35 +0000
commite924d0f542496ea026ad8292dd412722aeeec3a2 (patch)
treef1a2ee1c7b7ae3724dd3a7e3bfd1d11488d2055d /pkgs/development/beam-modules
parent4600a9d60782a8832449fead0606f720e40169a1 (diff)
beamPackages.mixRelease: remove erlang references from output
Diffstat (limited to 'pkgs/development/beam-modules')
-rw-r--r--pkgs/development/beam-modules/mix-release.nix68
1 files changed, 41 insertions, 27 deletions
diff --git a/pkgs/development/beam-modules/mix-release.nix b/pkgs/development/beam-modules/mix-release.nix
index 2248dce7a76b7..b25c609bd3bc3 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 - <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 ];
-  #
 })