diff --git a/doc/languages-frameworks/beam.section.md b/doc/languages-frameworks/beam.section.md index 947968db15e..2a4753a1199 100644 --- a/doc/languages-frameworks/beam.section.md +++ b/doc/languages-frameworks/beam.section.md @@ -34,6 +34,8 @@ Erlang.mk works exactly as expected. There is a bootstrap process that needs to For Elixir applications use `mixRelease` to make a release. See examples for more details. +There is also a `buildMix` helper, whose behavior is closer to that of `buildErlangMk` and `buildRebar3`. The primary difference is that mixRelease makes a release, while buildMix only builds the package, making it useful for libraries and other dependencies. + ## How to Install BEAM Packages {#how-to-install-beam-packages} BEAM builders are not registered at the top level, simply because they are not relevant to the vast majority of Nix users. To install any of those builders into your profile, refer to them by their attribute path `beamPackages.rebar3`: diff --git a/pkgs/development/beam-modules/build-mix.nix b/pkgs/development/beam-modules/build-mix.nix new file mode 100644 index 00000000000..7e19f19a093 --- /dev/null +++ b/pkgs/development/beam-modules/build-mix.nix @@ -0,0 +1,85 @@ +{ stdenv, writeText, elixir, erlang, hex, lib }: + +{ name +, version +, src +, buildInputs ? [ ] +, beamDeps ? [ ] +, propagatedBuildInputs ? [ ] +, postPatch ? "" +, compilePorts ? false +, meta ? { } +, enableDebugInfo ? false +, mixEnv ? "prod" +, ... +}@attrs: + +with lib; +let + shell = drv: stdenv.mkDerivation { + name = "interactive-shell-${drv.name}"; + buildInputs = [ drv ]; + }; + + pkg = self: stdenv.mkDerivation (attrs // { + name = "${name}-${version}"; + inherit version; + inherit src; + + MIX_ENV = mixEnv; + MIX_DEBUG = if enableDebugInfo then 1 else 0; + HEX_OFFLINE = 1; + + # stripping does not have any effect on beam files + dontStrip = true; + + # add to ERL_LIBS so other modules can find at runtime. + # http://erlang.org/doc/man/code.html#code-path + # Mix also searches the code path when compiling with the --no-deps-check + # flag, which is why there is no complicated booterstrapper like the one + # used by buildRebar3. + setupHook = attrs.setupHook or + writeText "setupHook.sh" '' + addToSearchPath ERL_LIBS "$1/lib/erlang/lib" + ''; + + buildInputs = buildInputs ++ [ elixir hex ]; + propagatedBuildInputs = propagatedBuildInputs ++ beamDeps; + + buildPhase = attrs.buildPhase or '' + runHook preBuild + export HEX_HOME="$TEMPDIR/hex" + export MIX_HOME="$TEMPDIR/mix" + mix compile --no-deps-check + runHook postBuild + ''; + + installPhase = attrs.installPhase or '' + runHook preInstall + + # This uses the install path convention established by nixpkgs maintainers + # for all beam packages. Changing this will break compatibility with other + # builder functions like buildRebar3 and buildErlangMk. + mkdir -p "$out/lib/erlang/lib/${name}-${version}" + + # Some packages like db_connection will use _build/shared instead of + # honoring the $MIX_ENV variable. + for reldir in _build/{$MIX_ENV,shared}/lib/${name}/{src,ebin,priv,include} ; do + if test -d $reldir ; then + # Some builds produce symlinks (eg: phoenix priv dircetory). They must + # be followed with -H flag. + cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$reldir" + fi + done + + runHook postInstall + ''; + + passthru = { + packageName = name; + env = shell self; + inherit beamDeps; + }; + }); +in +fix pkg diff --git a/pkgs/development/beam-modules/default.nix b/pkgs/development/beam-modules/default.nix index f63ecd95083..3375fd61260 100644 --- a/pkgs/development/beam-modules/default.nix +++ b/pkgs/development/beam-modules/default.nix @@ -32,6 +32,7 @@ let buildRebar3 = callPackage ./build-rebar3.nix { }; buildHex = callPackage ./build-hex.nix { }; buildErlangMk = callPackage ./build-erlang-mk.nix { }; + buildMix = callPackage ./build-mix.nix { }; fetchMixDeps = callPackage ./fetch-mix-deps.nix { }; mixRelease = callPackage ./mix-release.nix { };