idris2: Make it an "unwrapped" compiler, add wrapper

Patch source so the unwrapped compiler can run at all
This commit is contained in:
Ross Smyth
2025-10-21 12:45:50 -04:00
parent f5a33c56af
commit d5365578dd
2 changed files with 154 additions and 100 deletions
+106 -100
View File
@@ -7,17 +7,16 @@
clang,
gmp,
installShellFiles,
makeWrapper,
gambit,
nodejs,
zsh,
callPackage,
idris2Packages,
testers,
}:
# NOTICE: An `idris2WithPackages` is available at: https://github.com/claymager/idris2-pkgs
let
inherit (stdenv.hostPlatform) extensions;
version = "0.7.0";
src = fetchFromGitHub {
owner = "idris-lang";
@@ -36,115 +35,122 @@ let
chez
else
chez-racket;
in
stdenv.mkDerivation (finalAttrs: {
inherit version src;
pname = "idris2";
strictDeps = true;
nativeBuildInputs = [
clang
platformChez
installShellFiles
]
++ lib.optionals stdenv.hostPlatform.isDarwin [ zsh ];
buildInputs = [
platformChez
gmp
libidris2_support
];
unwrapped = stdenv.mkDerivation (finalAttrs: {
inherit version src;
pname = "idris2";
enableParallelBuilding = true;
postPatch = ''
shopt -s globstar
makeFlags = [
"PREFIX=${placeholder "out"}"
"IDRIS2_SUPPORT_DIR=${libsupportLib}"
]
++ lib.optional stdenv.hostPlatform.isDarwin "OS=";
# Patch all occurences of the support lib with an absolute path so it
# works without wrapping.
substituteInPlace **/*.idr \
--replace-quiet "libidris2_support" "${libidris2_support}/lib/libidris2_support${extensions.sharedLibrary}"
# The name of the main executable of pkgs.chez is `scheme`
buildFlags = [
"bootstrap"
"SCHEME=scheme"
"IDRIS2_LIBS=${libsupportLib}"
"IDRIS2_DATA=${libsupportShare}"
];
substituteInPlace src/Compiler/RefC/CC.idr \
--replace-fail "libidris2_support${extensions.sharedLibrary}.a" "libidris2_support.a"
doCheck = false;
checkTarget = "test";
nativeCheckInputs = [
gambit
nodejs
];
checkFlags = [
"INTERACTIVE="
"IDRIS2_DATA=${libsupportShare}"
"IDRIS2_LIBS=${libsupportLib}"
"TEST_IDRIS2_DATA=${libsupportShare}"
"TEST_IDRIS2_LIBS=${libsupportLib}"
"TEST_IDRIS2_SUPPORT_DIR=${libsupportLib}"
];
patchShebangs --build tests
'';
# TODO: Move this into its own derivation, such that this can be changed
# without having to recompile idris2 every time.
postInstall =
let
name = "${pname}-${version}";
globalLibraries = [
"\\$HOME/.nix-profile/lib/${name}"
"/run/current-system/sw/lib/${name}"
"$out/${name}"
];
globalLibrariesPath = builtins.concatStringsSep ":" globalLibraries;
in
''
strictDeps = true;
nativeBuildInputs = [
clang
platformChez
installShellFiles
]
++ lib.optionals stdenv.hostPlatform.isDarwin [ zsh ];
buildInputs = [
platformChez
gmp
libidris2_support
];
enableParallelBuilding = true;
makeFlags = [
"PREFIX=${placeholder "out"}"
"IDRIS2_SUPPORT_DIR=${libsupportLib}"
]
++ lib.optional stdenv.hostPlatform.isDarwin "OS=";
# The name of the main executable of pkgs.chez is `scheme`
buildFlags = [
"bootstrap"
"SCHEME=scheme"
"IDRIS2_LIBS=${libsupportLib}"
"IDRIS2_DATA=${libsupportShare}"
];
doCheck = false;
checkTarget = "test";
nativeCheckInputs = [
gambit
nodejs
];
checkFlags = [
"INTERACTIVE="
"IDRIS2_DATA=${libsupportShare}"
"IDRIS2_LIBS=${libsupportLib}"
"TEST_IDRIS2_DATA=${libsupportShare}"
"TEST_IDRIS2_LIBS=${libsupportLib}"
"TEST_IDRIS2_SUPPORT_DIR=${libsupportLib}"
];
postInstall = ''
# Remove existing idris2 wrapper that sets incorrect LD_LIBRARY_PATH
rm $out/bin/idris2
# The only thing we need from idris2_app is the actual binary
# The only thing we need from idris2_app is the actual binary, which is
# a Chez Scheme object.
# The extensions is .so on Darwin and Linux for some reason
mv $out/bin/idris2_app/idris2.so $out/bin/idris2
rm $out/bin/idris2_app/*
rmdir $out/bin/idris2_app
# idris2 needs to find scheme at runtime to compile
# idris2 installs packages with --install into the path given by
# IDRIS2_PREFIX. We set that to a default of ~/.idris2, to mirror the
# behaviour of the standard Makefile install.
# TODO: Make support libraries their own derivation such that
# overriding LD_LIBRARY_PATH is unnecessary
wrapProgram "$out/bin/idris2" \
--set-default CHEZ "${platformChez}/bin/scheme" \
--run 'export IDRIS2_PREFIX=''${IDRIS2_PREFIX-"$HOME/.idris2"}' \
--suffix IDRIS2_LIBS ':' "$out/${name}/lib" \
--suffix IDRIS2_DATA ':' "$out/${name}/support" \
--suffix IDRIS2_PACKAGE_PATH ':' "${globalLibrariesPath}" \
--suffix DYLD_LIBRARY_PATH ':' "$out/${name}/lib" \
--suffix LD_LIBRARY_PATH ':' "$out/${name}/lib"
rm -rf $out/bin/idris2_app
''
+ lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
installShellCompletion --cmd idris2 \
--bash <($out/bin/idris2 --bash-completion-script idris2)
'';
# Run package tests
passthru = {
inherit libidris2_support;
tests = callPackage ./tests.nix {
idris2 = finalAttrs.finalPackage;
idris2Packages = idris2Packages.override { idris2 = finalAttrs.finalPackage; };
};
};
# Run package tests
passthru = {
inherit libidris2_support;
tests = {
wrapped = testers.testVersion {
package = finalAttrs.finalPackage.withPackages (p: [ p.idris2Api ]);
};
}
// (callPackage ./tests.nix {
idris2 = finalAttrs.finalPackage;
idris2Packages = idris2Packages.override { idris2 = finalAttrs.finalPackage; };
});
meta = {
description = "Purely functional programming language with first class types";
mainProgram = "idris2";
homepage = "https://github.com/idris-lang/Idris2";
changelog = "https://github.com/idris-lang/Idris2/releases/tag/v${finalAttrs.version}";
license = lib.licenses.bsd3;
maintainers = with lib.maintainers; [
fabianhjr
wchresta
mattpolzin
RossSmyth
];
platforms = lib.platforms.all;
};
})
chez = platformChez;
withPackages =
f:
callPackage ./wrapped.nix {
idris2-unwrapped = finalAttrs.finalPackage;
extraPackages = f idris2Packages;
};
};
meta = {
description = "Purely functional programming language with first class types";
mainProgram = "idris2";
homepage = "https://github.com/idris-lang/Idris2";
changelog = "https://github.com/idris-lang/Idris2/releases/tag/v${finalAttrs.version}";
license = lib.licenses.bsd3;
maintainers = with lib.maintainers; [
fabianhjr
wchresta
mattpolzin
RossSmyth
];
platforms = lib.platforms.all;
};
});
in
unwrapped.withPackages (_: [ ])
+48
View File
@@ -0,0 +1,48 @@
{
lib,
makeBinaryWrapper,
symlinkJoin,
idris2-unwrapped,
extraPackages ? [ ],
}:
let
supportLibrariesPath = lib.makeLibraryPath [ idris2-unwrapped.libidris2_support ];
supportSharePath = lib.makeSearchPath "share" [ idris2-unwrapped.libidris2_support ];
in
symlinkJoin {
inherit (idris2-unwrapped) version;
pname = "idris2-wrapped";
paths = [ idris2-unwrapped ] ++ extraPackages;
nativeBuildInputs = [ makeBinaryWrapper ];
postBuild = ''
wrapProgram "$out/bin/idris2" \
--set CHEZ "${lib.getExe idris2-unwrapped.chez}" \
--suffix IDRIS2_LIBS ':' "${supportLibrariesPath}" \
--suffix IDRIS2_DATA ':' "${supportSharePath}" \
--suffix IDRIS2_PACKAGE_PATH ':' "$out/idris2-${idris2-unwrapped.version}" \
--suffix LD_LIBRARY_PATH ':' "${supportLibrariesPath}" \
--suffix DYLD_LIBRARY_PATH ':' "${supportLibrariesPath}"
'';
passthru = {
unwrapped = idris2-unwrapped;
src = idris2-unwrapped.src;
}
// idris2-unwrapped.passthru;
meta = {
# Manually inherit so that pos works
inherit (idris2-unwrapped.meta)
description
mainProgram
homepage
changelog
license
maintainers
platforms
;
};
}