diff options
Diffstat (limited to 'pkgs/development/beam-modules')
-rw-r--r-- | pkgs/development/beam-modules/default.nix | 2 | ||||
-rw-r--r-- | pkgs/development/beam-modules/elixir-ls/default.nix | 12 | ||||
-rw-r--r-- | pkgs/development/beam-modules/mix-release.nix | 162 | ||||
-rw-r--r-- | pkgs/development/beam-modules/rebar3-release.nix | 3 |
4 files changed, 115 insertions, 64 deletions
diff --git a/pkgs/development/beam-modules/default.nix b/pkgs/development/beam-modules/default.nix index 421d5f7ffbc..b7b2cc9c7dc 100644 --- a/pkgs/development/beam-modules/default.nix +++ b/pkgs/development/beam-modules/default.nix @@ -43,7 +43,7 @@ let elvis-erlang = callPackage ./elvis-erlang { }; # BEAM-based languages. - elixir = elixir_1_14; + elixir = elixir_1_15; elixir_1_15 = lib'.callElixir ../interpreters/elixir/1.15.nix { inherit erlang; diff --git a/pkgs/development/beam-modules/elixir-ls/default.nix b/pkgs/development/beam-modules/elixir-ls/default.nix index 949331f2fe4..9475ed35f88 100644 --- a/pkgs/development/beam-modules/elixir-ls/default.nix +++ b/pkgs/development/beam-modules/elixir-ls/default.nix @@ -4,16 +4,16 @@ let pname = "elixir-ls"; - version = "0.16.0"; + version = "0.17.3"; src = fetchFromGitHub { owner = "elixir-lsp"; repo = "elixir-ls"; rev = "v${version}"; - hash = "sha256-tEKwM5o3uXJ0cLY5USnQJ+HOGTSv6NDJvq+F/iqFEWs="; + hash = "sha256-E+tlnkwJiyG8x29um/G7OqIDCJ/laDMTm3z7VvdWy6s="; fetchSubmodules = true; }; in -mixRelease { +mixRelease { inherit pname version src elixir; stripDebug = true; @@ -21,7 +21,7 @@ mixRelease { mixFodDeps = fetchMixDeps { pname = "mix-deps-${pname}"; inherit src version elixir; - hash = "sha256-jpjqMIQ9fS4nkkKWZ80Mx5vULm5bvnNHy52ZQcR0y8c="; + hash = "sha256-ltSYZYsXWiq5ASvRmR7ETgK9e8bj4f9bhZAZEIceLkw="; }; # elixir-ls is an umbrella app @@ -49,6 +49,10 @@ mixRelease { substitute release/language_server.sh $out/bin/elixir-ls \ --replace 'exec "''${dir}/launch.sh"' "exec $out/lib/launch.sh" chmod +x $out/bin/elixir-ls + + substitute release/debugger.sh $out/bin/elixir-debugger \ + --replace 'exec "''${dir}/launch.sh"' "exec $out/lib/launch.sh" + chmod +x $out/bin/elixir-debugger # prepare the launcher substituteInPlace $out/lib/launch.sh \ --replace "ERL_LIBS=\"\$SCRIPTPATH:\$ERL_LIBS\"" \ diff --git a/pkgs/development/beam-modules/mix-release.nix b/pkgs/development/beam-modules/mix-release.nix index d48dc38a4b8..e5b44bc5dcd 100644 --- a/pkgs/development/beam-modules/mix-release.nix +++ b/pkgs/development/beam-modules/mix-release.nix @@ -1,4 +1,19 @@ -{ stdenv, lib, elixir, erlang, findutils, hex, rebar, rebar3, fetchMixDeps, makeWrapper, git, ripgrep }@inputs: +{ stdenv +, lib +, elixir +, erlang +, hex +, git +, rebar +, rebar3 +, fetchMixDeps +, findutils +, makeWrapper +, coreutils +, gnused +, gnugrep +, gawk +}@inputs: { pname , version @@ -10,80 +25,104 @@ , mixEnv ? "prod" , compileFlags ? [ ] - # mix fixed output derivation dependencies + # Mix dependencies provided as a fixed output derivation , mixFodDeps ? null - # mix dependencies generated by mix2nix - # 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 - # this is how mix will find dependencies + # Mix dependencies generated by mix2nix + # + # 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. + # This is how Mix finds dependencies. , mixNixDeps ? { } , elixir ? inputs.elixir , hex ? inputs.hex.override { inherit elixir; } -# This reduces closure size, but can lead to some hard to understand runtime -# errors, so use with caution. See e.g. -# https://github.com/whitfin/cachex/issues/205 -# https://framagit.org/framasoft/mobilizon/-/issues/1169 + # Remove releases/COOKIE + # + # People have different views on the nature of cookies. Some believe that they are + # secrets, while others believe they are just ids for clustering nodes instead of + # secrets. + # + # If you think cookie is secret, you can set this attr to true, then it will be + # removed from nix store. If not, you can set it to false. + # + # For backward compatibility, it is set to true by default. + # + # You can always specify a custom cookie by using RELEASE_COOKIE environment + # variable, regardless of the value of this attr. +, removeCookie ? true + + # This reduces closure size, but can lead to some hard to understand runtime + # errors, so use with caution. See e.g. + # https://github.com/whitfin/cachex/issues/205 + # https://framagit.org/framasoft/mobilizon/-/issues/1169 , stripDebug ? false , ... }@attrs: 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" "mixNixDeps" ]; in assert mixNixDeps != { } -> mixFodDeps == null; assert stripDebug -> !enableDebugInfo; stdenv.mkDerivation (overridable // { - # rg is used as a better grep to search for erlang references in the final release - nativeBuildInputs = nativeBuildInputs ++ [ erlang hex elixir makeWrapper git ripgrep ]; - buildInputs = buildInputs ++ builtins.attrValues mixNixDeps; + nativeBuildInputs = nativeBuildInputs ++ + # Erlang/Elixir deps + [ erlang elixir hex git ] ++ + # Mix deps + (builtins.attrValues mixNixDeps) ++ + # other compile-time deps + [ findutils makeWrapper ]; + + buildInputs = buildInputs; MIX_ENV = mixEnv; MIX_DEBUG = if enableDebugInfo then 1 else 0; HEX_OFFLINE = 1; + DEBUG = if enableDebugInfo then 1 else 0; # for Rebar3 compilation - # the api with `mix local.rebar rebar path` makes a copy of the binary - # some older dependencies still use rebar + # The API with `mix local.rebar rebar path` makes a copy of the binary + # some older dependencies still use rebar. MIX_REBAR = "${rebar}/bin/rebar"; MIX_REBAR3 = "${rebar3}/bin/rebar3"; + LC_ALL = "C.UTF-8"; postUnpack = '' - export HEX_HOME="$TEMPDIR/hex" + # Mix and Hex export MIX_HOME="$TEMPDIR/mix" + export HEX_HOME="$TEMPDIR/hex" # Rebar export REBAR_GLOBAL_CONFIG_DIR="$TEMPDIR/rebar3" export REBAR_CACHE_DIR="$TEMPDIR/rebar3.cache" ${lib.optionalString (mixFodDeps != null) '' - # compilation of the dependencies will require - # that the dependency path is writable - # thus a copy to the TEMPDIR is inevitable here + # Compilation of the dependencies will require that the dependency path is + # writable, thus a copy to the $TEMPDIR is inevitable here. export MIX_DEPS_PATH="$TEMPDIR/deps" cp --no-preserve=mode -R "${mixFodDeps}" "$MIX_DEPS_PATH" - '' - } - + ''} '' + (attrs.postUnpack or ""); configurePhase = attrs.configurePhase or '' runHook preConfigure ${./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 - # to be available - # Phoenix projects for example will need compile.phoenix + # to be available. + # + # Phoenix projects for example will need compile.phoenix. mix deps.compile --no-deps-check --skip-umbrella-children # Symlink dependency sources. This is needed for projects that require # access to the source of their dependencies. For example, Phoenix - # applications need javascript assets to build asset bundles. + # projects need javascript assets to build asset bundles. ${lib.optionalString (mixNixDeps != { }) '' mkdir -p deps @@ -113,7 +152,6 @@ stdenv.mkDerivation (overridable // { runHook postBuild ''; - installPhase = attrs.installPhase or '' runHook preInstall @@ -122,42 +160,50 @@ stdenv.mkDerivation (overridable // { runHook postInstall ''; - # Stripping of the binary is intentional - # even though it does not affect beam files - # it is necessary for NIFs binaries postFixup = '' - if [ -e "$out/bin/${pname}.bat" ]; then # absent in special cases, i.e. elixir-ls - rm "$out/bin/${pname}.bat" # windows file - fi - # contains secrets and should not be in the nix store - # TODO document how to handle RELEASE_COOKIE - # secrets should not be in the nix store. - # This is only used for connecting multiple nodes - if [ -e $out/releases/COOKIE ]; then # absent in special cases, i.e. elixir-ls + # Remove files for Microsoft Windows + rm -f "$out"/bin/*.bat + + # Wrap 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 rm $out/releases/COOKIE fi - # removing unused erlang reference from resulting derivation to reduce - # closure size - if [ -e $out/erts-* ]; then - echo "ERTS found in $out - removing references to erlang to reduce closure size" - # there is a link in $out/erts-*/bin/start always - # TODO: - # sometimes there are links in dependencies like bcrypt compiled binaries - # at the moment those are not removed since substituteInPlace will - # error on binaries - for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches); do - echo "removing reference to erlang in $file" - substituteInPlace "$file" --replace "${erlang}/lib/erlang" "$out" - done - fi '' + 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. 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 investigate why the resulting closure still has - # a reference to erlang. - # uncommenting the following will fail the build - # disallowedReferences = [ erlang ]; + # 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 ]; + # }) diff --git a/pkgs/development/beam-modules/rebar3-release.nix b/pkgs/development/beam-modules/rebar3-release.nix index b884809505f..621887d6cd1 100644 --- a/pkgs/development/beam-modules/rebar3-release.nix +++ b/pkgs/development/beam-modules/rebar3-release.nix @@ -84,7 +84,8 @@ let runHook postInstall ''; - 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 |