115 lines
3.5 KiB
Nix
115 lines
3.5 KiB
Nix
{ stdenv, lib, elixir, erlang, findutils, hex, rebar, rebar3, fetchMixDeps, makeWrapper, git }:
|
|
|
|
{ pname
|
|
, version
|
|
, src
|
|
, nativeBuildInputs ? [ ]
|
|
, meta ? { }
|
|
, enableDebugInfo ? false
|
|
, mixEnv ? "prod"
|
|
, compileFlags ? [ ]
|
|
# mix fixed output derivation dependencies
|
|
, 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
|
|
, mixNixDeps ? { }
|
|
, ...
|
|
}@attrs:
|
|
let
|
|
# remove non standard attributes that cannot be coerced to strings
|
|
overridable = builtins.removeAttrs attrs [ "compileFlags" "mixNixDeps" ];
|
|
in
|
|
assert mixNixDeps != { } -> mixFodDeps == null;
|
|
stdenv.mkDerivation (overridable // {
|
|
nativeBuildInputs = nativeBuildInputs ++ [ erlang hex elixir makeWrapper git ];
|
|
buildInputs = builtins.attrValues mixNixDeps;
|
|
|
|
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
|
|
MIX_REBAR = "${rebar}/bin/rebar";
|
|
MIX_REBAR3 = "${rebar3}/bin/rebar3";
|
|
|
|
postUnpack = ''
|
|
export HEX_HOME="$TEMPDIR/hex"
|
|
export MIX_HOME="$TEMPDIR/mix"
|
|
|
|
# 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
|
|
export MIX_DEPS_PATH="$TEMPDIR/deps"
|
|
cp --no-preserve=mode -R "${mixFodDeps}" "$MIX_DEPS_PATH"
|
|
''
|
|
}
|
|
|
|
'' + (attrs.postUnpack or "");
|
|
|
|
configurePhase = attrs.configurePhase or ''
|
|
runHook preConfigure
|
|
|
|
# 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
|
|
mix deps.compile --no-deps-check --skip-umbrella-children
|
|
|
|
runHook postConfigure
|
|
'';
|
|
|
|
buildPhase = attrs.buildPhase or ''
|
|
runHook preBuild
|
|
|
|
mix compile --no-deps-check ${lib.concatStringsSep " " compileFlags}
|
|
|
|
runHook postBuild
|
|
'';
|
|
|
|
|
|
installPhase = attrs.installPhase or ''
|
|
runHook preInstall
|
|
|
|
mix release --no-deps-check --path "$out"
|
|
|
|
runHook postInstall
|
|
'';
|
|
|
|
fixupPhase = ''
|
|
runHook preFixup
|
|
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
|
|
rm $out/releases/COOKIE
|
|
fi
|
|
# TODO remove the uneeded reference too erlang
|
|
# one possible way would be
|
|
# for f in $(${findutils}/bin/find $out -name start); do
|
|
# substituteInPlace $f \
|
|
# --replace 'ROOTDIR=${erlang}/lib/erlang' 'ROOTDIR=""'
|
|
# done
|
|
# What is left to do is to check that erlang is not required on
|
|
# the host
|
|
|
|
patchShebangs $out
|
|
runHook postFixup
|
|
'';
|
|
# TODO figure out how to do a Fixed Output Derivation and add the output hash
|
|
# This doesn't play well at the moment with Phoenix projects
|
|
# for example that have frontend dependencies
|
|
|
|
# disallowedReferences = [ erlang ];
|
|
})
|