beamPackages.buildMix: move phases to hooks
This commit is contained in:
@@ -2,8 +2,13 @@
|
||||
elixir,
|
||||
erlang,
|
||||
hex,
|
||||
beamCopySourceHook,
|
||||
beamModuleInstallHook,
|
||||
mixBuildDirHook,
|
||||
mixCompileHook,
|
||||
mixAppConfigPatchHook,
|
||||
|
||||
lib,
|
||||
mixConfigureHook,
|
||||
stdenv,
|
||||
writeText,
|
||||
}:
|
||||
@@ -16,42 +21,46 @@ lib.extendMkDerivation {
|
||||
extendDrvArgs =
|
||||
finalAttrs:
|
||||
{
|
||||
nativeBuildInputs ? [ ],
|
||||
propagatedBuildInputs ? [ ],
|
||||
passthru ? { },
|
||||
beamDeps ? [ ],
|
||||
mixEnv ? "prod",
|
||||
mixTarget ? "host",
|
||||
enableDebugInfo ? false,
|
||||
# A handful of libraries require compile time configuration
|
||||
|
||||
# Allow passing compile time config instead of an empty config
|
||||
appConfigPath ? null,
|
||||
|
||||
enableDebugInfo ? false,
|
||||
erlangCompilerOptions ? [ ],
|
||||
# Deterministic Erlang builds remove full system paths from debug information
|
||||
# among other things to keep builds more reproducible. See their docs for more:
|
||||
# https://www.erlang.org/doc/man/compile
|
||||
erlangDeterministicBuilds ? true,
|
||||
beamDeps ? [ ],
|
||||
...
|
||||
}@args:
|
||||
{
|
||||
name = "erlang-${erlang.version}-${args.name}-${finalAttrs.version}";
|
||||
name = "erlang${erlang.version}-${args.name}-${finalAttrs.version}";
|
||||
|
||||
env = {
|
||||
MIX_ENV = mixEnv;
|
||||
MIX_TARGET = mixTarget;
|
||||
MIX_BUILD_PREFIX = (if mixTarget == "host" then "" else "${mixTarget}_") + "${mixEnv}";
|
||||
MIX_DEBUG = if enableDebugInfo then 1 else 0;
|
||||
HEX_OFFLINE = 1;
|
||||
ERL_COMPILER_OPTIONS =
|
||||
let
|
||||
options = erlangCompilerOptions ++ lib.optionals erlangDeterministicBuilds [ "deterministic" ];
|
||||
in
|
||||
"[${lib.concatStringsSep "," options}]";
|
||||
|
||||
MIX_ENV = mixEnv;
|
||||
MIX_TARGET = mixTarget;
|
||||
MIX_BUILD_PREFIX = (if mixTarget == "host" then "" else "${mixTarget}_") + "${mixEnv}";
|
||||
MIX_DEBUG = if enableDebugInfo then 1 else 0;
|
||||
HEX_OFFLINE = 1;
|
||||
|
||||
LANG = if stdenv.hostPlatform.isLinux then "C.UTF-8" else "C";
|
||||
LC_CTYPE = if stdenv.hostPlatform.isLinux then "C.UTF-8" else "UTF-8";
|
||||
__darwinAllowLocalNetworking = true;
|
||||
|
||||
# some hooks need name-version, but we've overridden name above for the nix package
|
||||
beamModuleName = args.name;
|
||||
};
|
||||
|
||||
__darwinAllowLocalNetworking = 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
|
||||
@@ -60,70 +69,21 @@ lib.extendMkDerivation {
|
||||
addToSearchPath ERL_LIBS "$1/lib/erlang/lib"
|
||||
'';
|
||||
|
||||
nativeBuildInputs = nativeBuildInputs ++ [
|
||||
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
|
||||
elixir
|
||||
hex
|
||||
mixConfigureHook
|
||||
|
||||
beamCopySourceHook
|
||||
beamModuleInstallHook
|
||||
mixBuildDirHook
|
||||
mixCompileHook
|
||||
mixAppConfigPatchHook
|
||||
];
|
||||
propagatedBuildInputs = propagatedBuildInputs ++ beamDeps;
|
||||
|
||||
# We don't want to include whatever config a dependency brings; per
|
||||
# https://hexdocs.pm/elixir/main/Config.html, config is application specific.
|
||||
patchPhase =
|
||||
args.patchPhase or (
|
||||
''
|
||||
runHook prePatch
|
||||
propagatedBuildInputs = (args.propagatedBuildInputs or [ ]) ++ beamDeps;
|
||||
|
||||
rm -rf config
|
||||
''
|
||||
+ lib.optionalString (!isNull appConfigPath) ''
|
||||
cp -r ${appConfigPath} config
|
||||
''
|
||||
+ ''
|
||||
runHook postPatch
|
||||
''
|
||||
);
|
||||
|
||||
buildPhase =
|
||||
args.buildPhase or ''
|
||||
runHook preBuild
|
||||
|
||||
export HEX_HOME="$TEMPDIR/hex"
|
||||
export MIX_HOME="$TEMPDIR/mix"
|
||||
mix compile --no-deps-check
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase =
|
||||
args.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/${finalAttrs.name}-${finalAttrs.version}-${args.version}"
|
||||
|
||||
# Some packages like db_connection will use _build/shared instead of
|
||||
# honoring the $MIX_ENV variable.
|
||||
for reldir in _build/{$MIX_BUILD_PREFIX,shared}/lib/${finalAttrs.name}-${finalAttrs.version}/{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/${finalAttrs.name}-${finalAttrs.version}" "$reldir"
|
||||
fi
|
||||
done
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
# stripping does not have any effect on beam files
|
||||
# it is however needed for dependencies with NIFs like bcrypt for example
|
||||
dontStrip = args.dontStrip or false;
|
||||
|
||||
passthru = {
|
||||
passthru = (args.passthru or { }) // {
|
||||
inherit beamDeps;
|
||||
}
|
||||
// passthru;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -101,7 +101,11 @@ let
|
||||
webdriver = callPackage ./webdriver { };
|
||||
|
||||
inherit (callPackages ./hooks { })
|
||||
mixConfigureHook
|
||||
beamCopySourceHook
|
||||
beamModuleInstallHook
|
||||
mixBuildDirHook
|
||||
mixCompileHook
|
||||
mixAppConfigPatchHook
|
||||
;
|
||||
};
|
||||
in
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# shellcheck shell=bash
|
||||
#
|
||||
# Copy the source so it can be used by mix projects to assemble `deps`
|
||||
# do this before building to avoid build artifacts but after patching
|
||||
# to include any user modifications to the source
|
||||
|
||||
beamCopySourceHook() {
|
||||
echo "Executing beamCopySourceHook"
|
||||
|
||||
mkdir -p "$out/src"
|
||||
cp -r "." "$out/src"
|
||||
|
||||
echo "Finished beamCopySourceHook"
|
||||
}
|
||||
|
||||
postPatchHooks+=(beamCopySourceHook)
|
||||
@@ -0,0 +1,25 @@
|
||||
# shellcheck shell=bash
|
||||
#
|
||||
# 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.
|
||||
|
||||
beamModuleInstallHook() {
|
||||
echo "Executing beamModuleInstallHook"
|
||||
|
||||
mkdir -p "$out/lib/erlang/lib/${beamModuleName}-${version}"
|
||||
|
||||
for reldir in _build/{$MIX_BUILD_PREFIX,shared}/lib/${beamModuleName}/{src,ebin,priv,include}; do
|
||||
if test -d "$reldir"; then
|
||||
# Some builds produce symlinks (eg: phoenix priv directory). They must
|
||||
# be followed with -H flag.
|
||||
cp -vHrt "$out/lib/erlang/lib/${beamModuleName}-${version}" "$reldir"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Finished beamModuleInstallHook"
|
||||
}
|
||||
|
||||
if [ -z "${dontBeamModuleInstall-}" ] && [ -z "${installPhase-}" ]; then
|
||||
installPhase=beamModuleInstallHook
|
||||
fi
|
||||
@@ -1,8 +1,22 @@
|
||||
{ makeSetupHook }:
|
||||
{
|
||||
makeSetupHook,
|
||||
}:
|
||||
{
|
||||
mixConfigureHook = makeSetupHook {
|
||||
beamCopySourceHook = makeSetupHook {
|
||||
name = "beam-copy-source-hook.sh";
|
||||
} ./beam-copy-source-hook.sh;
|
||||
|
||||
beamModuleInstallHook = makeSetupHook {
|
||||
name = "beam-module-install-hook.sh";
|
||||
} ./beam-module-install-hook.sh;
|
||||
|
||||
mixBuildDirHook = makeSetupHook {
|
||||
name = "mix-configure-hook.sh";
|
||||
} ./mix-configure-hook.sh;
|
||||
} ./mix-build-dir-hook.sh;
|
||||
|
||||
mixCompileHook = makeSetupHook {
|
||||
name = "mix-compile-hook.sh";
|
||||
} ./mix-compile-hook.sh;
|
||||
|
||||
mixAppConfigPatchHook = makeSetupHook {
|
||||
name = "mix-config-patch-hook.sh";
|
||||
} ./mix-app-config-patch-hook.sh;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# shellcheck shell=bash
|
||||
#
|
||||
# We don't want to include whatever config a dependency brings; per
|
||||
# https://hexdocs.pm/elixir/main/Config.html, config is application specific.
|
||||
|
||||
mixAppConfigPatchHook() {
|
||||
echo "Executing mixAppConfigPatchHook"
|
||||
|
||||
rm -rvf config
|
||||
|
||||
# But we still need a way to provide config for deps that need compile time config
|
||||
if [ ! -z "${appConfigPath}" ]; then
|
||||
ln -sf "${appConfigPath}" config
|
||||
fi
|
||||
|
||||
echo "Finished mixAppConfigPatchHook"
|
||||
}
|
||||
|
||||
prePatchHooks+=(mixAppConfigPatchHook)
|
||||
@@ -0,0 +1,26 @@
|
||||
# shellcheck shell=bash
|
||||
#
|
||||
# Symlink all dependencies found in ERL_LIBS since Elixir does not honor ERL_LIBS
|
||||
|
||||
mixBuildDirHook() {
|
||||
echo "Executing mixBuildDirHook"
|
||||
|
||||
mkdir -p _build/"$MIX_BUILD_PREFIX"/lib
|
||||
while read -r -d ':' lib; do
|
||||
for dir in "$lib"/*; do
|
||||
# Strip version number for directory name if it exists, so naming of
|
||||
# all libs matches what mix's expectation.
|
||||
dest=$(basename "$dir" | cut -d '-' -f1)
|
||||
build_dir="_build/$MIX_BUILD_PREFIX/lib/$dest"
|
||||
|
||||
# Symlink libs to _build so that mix can find them when compiling.
|
||||
# This is what allows mix to compile the package without searching
|
||||
# for dependencies over the network.
|
||||
ln -sv "$dir" "$build_dir"
|
||||
done
|
||||
done <<<"$ERL_LIBS:"
|
||||
|
||||
echo "Finished mixBuildDirHook"
|
||||
}
|
||||
|
||||
preConfigureHooks+=(mixBuildDirHook)
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
mixCompileHook() {
|
||||
echo "Executing mixCompileHook"
|
||||
|
||||
runHook preBuild
|
||||
|
||||
local flagsArray=()
|
||||
concatTo flagsArray mixCompileFlags
|
||||
|
||||
mix compile --no-deps-check "${flagsArray[@]}"
|
||||
|
||||
runHook postBuild
|
||||
|
||||
echo "Finished mixCompileHook"
|
||||
}
|
||||
|
||||
if [ -z "${dontMixCompile-}" ] && [ -z "${buildPhase-}" ]; then
|
||||
buildPhase=mixCompileHook
|
||||
fi
|
||||
@@ -1,34 +0,0 @@
|
||||
# shellcheck shell=bash
|
||||
mixConfigureHook() {
|
||||
echo "Executing mixConfigureHook"
|
||||
|
||||
runHook preConfigure
|
||||
|
||||
# Copy the source so it can be used by mix projects
|
||||
# do this before building to avoid build artifacts but after patching
|
||||
# to include any modifications
|
||||
mkdir -p "$out/src"
|
||||
cp -r "." "$out/src"
|
||||
|
||||
# Symlink all dependencies found in ERL_LIBS since Elixir does not honor ERL_LIBS
|
||||
mkdir -p _build/"$MIX_BUILD_PREFIX"/lib
|
||||
while read -r -d ':' lib; do
|
||||
for dir in "$lib"/*; do
|
||||
# Strip version number for directory name if it exists, so naming of
|
||||
# all libs matches what mix's expectation.
|
||||
dest=$(basename "$dir" | cut -d '-' -f1)
|
||||
build_dir="_build/$MIX_BUILD_PREFIX/lib/$dest"
|
||||
((MIX_DEBUG == 1)) && echo "Linking $dir to $build_dir"
|
||||
# Symlink libs to _build so that mix can find them when compiling.
|
||||
# This is what allows mix to compile the package without searching
|
||||
# for dependencies over the network.
|
||||
ln -s "$dir" "$build_dir"
|
||||
done
|
||||
done <<<"$ERL_LIBS:"
|
||||
|
||||
runHook postConfigure
|
||||
}
|
||||
|
||||
if [ -z "${dontCargoConfigure-}" ] && [ -z "${configurePhase-}" ]; then
|
||||
configurePhase=mixConfigureHook
|
||||
fi
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
# Added 2026-02-12 for external users
|
||||
echo "mix-configure-hook.sh has been removed and is now a setup hook.
|
||||
Add 'beamPackages.mixBuildDirHook' to 'nativeBuildInputs' instead.
|
||||
" >&2
|
||||
exit 1
|
||||
@@ -171,8 +171,6 @@ stdenv.mkDerivation (
|
||||
attrs.configurePhase or ''
|
||||
runHook preConfigure
|
||||
|
||||
${./mix-configure-hook.sh}
|
||||
|
||||
# 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.
|
||||
|
||||
@@ -146,6 +146,7 @@ mixRelease rec {
|
||||
${lib.getExe nixfmt} pkgs/servers/mobilizon/mix.nix
|
||||
'';
|
||||
elixirPackage = beamPackages.elixir;
|
||||
inherit mixNixDeps;
|
||||
};
|
||||
|
||||
meta = {
|
||||
|
||||
Reference in New Issue
Block a user