idris2Packages.buildIdris: add retroactive support for building a whole dependency tree with source
This commit is contained in:
parent
e3b7ada410
commit
8079c8bd6d
@ -11,13 +11,17 @@
|
||||
# idrisLibraries = [ ];
|
||||
# };
|
||||
# in {
|
||||
# lib = pkg.library { withSource = true; };
|
||||
# lib1 = pkg.library { withSource = true; };
|
||||
#
|
||||
# # implicitly without source:
|
||||
# lib2 = pkg.library';
|
||||
#
|
||||
# bin = pkg.executable;
|
||||
# }
|
||||
#
|
||||
{
|
||||
src,
|
||||
ipkgName,
|
||||
ipkgName, # ipkg filename without the extension
|
||||
version ? "unversioned",
|
||||
idrisLibraries, # Other libraries built with buildIdris
|
||||
...
|
||||
@ -44,78 +48,91 @@ let
|
||||
ipkgFileName = ipkgName + ".ipkg";
|
||||
idrName = "idris2-${idris2.version}";
|
||||
libSuffix = "lib/${idrName}";
|
||||
propagatedIdrisLibraries = propagate idrisLibraryLibs;
|
||||
libDirs = (lib.makeSearchPath libSuffix propagatedIdrisLibraries) + ":${idris2}/${idrName}";
|
||||
libDirs = libs: (lib.makeSearchPath libSuffix libs) + ":${idris2}/${idrName}";
|
||||
supportDir = "${idris2}/${idrName}/lib";
|
||||
drvAttrs = builtins.removeAttrs attrs [
|
||||
"ipkgName"
|
||||
"idrisLibraries"
|
||||
];
|
||||
|
||||
derivation = stdenv.mkDerivation (
|
||||
finalAttrs:
|
||||
drvAttrs
|
||||
// {
|
||||
pname = ipkgName;
|
||||
inherit version;
|
||||
src = src;
|
||||
nativeBuildInputs = [
|
||||
idris2
|
||||
makeBinaryWrapper
|
||||
] ++ attrs.nativeBuildInputs or [ ];
|
||||
buildInputs = propagatedIdrisLibraries ++ attrs.buildInputs or [ ];
|
||||
mkDerivation =
|
||||
withSource:
|
||||
let
|
||||
applyWithSource = lib: if withSource then lib.withSource else lib;
|
||||
propagatedIdrisLibraries = map applyWithSource (propagate idrisLibraryLibs);
|
||||
in
|
||||
stdenv.mkDerivation (
|
||||
finalAttrs:
|
||||
drvAttrs
|
||||
// {
|
||||
pname = ipkgName;
|
||||
inherit src version;
|
||||
nativeBuildInputs = [
|
||||
idris2
|
||||
makeBinaryWrapper
|
||||
] ++ attrs.nativeBuildInputs or [ ];
|
||||
buildInputs = propagatedIdrisLibraries ++ attrs.buildInputs or [ ];
|
||||
|
||||
env.IDRIS2_PACKAGE_PATH = libDirs;
|
||||
env.IDRIS2_PACKAGE_PATH = libDirs propagatedIdrisLibraries;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
idris2 --build ${ipkgFileName}
|
||||
runHook postBuild
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
idris2 --build ${ipkgFileName}
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit propagatedIdrisLibraries;
|
||||
} // (attrs.passthru or { });
|
||||
|
||||
shellHook = ''
|
||||
export IDRIS2_PACKAGE_PATH="${finalAttrs.env.IDRIS2_PACKAGE_PATH}"
|
||||
'';
|
||||
}
|
||||
);
|
||||
|
||||
mkExecutable =
|
||||
withSource:
|
||||
let
|
||||
derivation = mkDerivation withSource;
|
||||
in
|
||||
derivation.overrideAttrs {
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/bin
|
||||
scheme_app="$(find ./build/exec -name '*_app')"
|
||||
if [ "$scheme_app" = ''' ]; then
|
||||
mv -- build/exec/* $out/bin/
|
||||
chmod +x $out/bin/*
|
||||
# ^ remove after Idris2 0.8.0 is released. will be superfluous:
|
||||
# https://github.com/idris-lang/Idris2/pull/3189
|
||||
else
|
||||
cd build/exec/*_app
|
||||
rm -f ./libidris2_support.{so,dylib}
|
||||
for file in *.so; do
|
||||
bin_name="''${file%.so}"
|
||||
mv -- "$file" "$out/bin/$bin_name"
|
||||
|
||||
wrapProgram "$out/bin/$bin_name" \
|
||||
--prefix LD_LIBRARY_PATH : ${supportDir} \
|
||||
--prefix DYLD_LIBRARY_PATH : ${supportDir}
|
||||
done
|
||||
fi
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit propagatedIdrisLibraries;
|
||||
} // (attrs.passthru or { });
|
||||
# allow an executable's dependencies to be built with source. this is convenient when
|
||||
# building a development shell for the exectuable using `mkShell`'s `inputsFrom`.
|
||||
passthru = derivation.passthru // {
|
||||
withSource = mkExecutable true;
|
||||
};
|
||||
};
|
||||
|
||||
shellHook = ''
|
||||
export IDRIS2_PACKAGE_PATH="${finalAttrs.env.IDRIS2_PACKAGE_PATH}"
|
||||
'';
|
||||
}
|
||||
);
|
||||
|
||||
in
|
||||
{
|
||||
executable = derivation.overrideAttrs {
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/bin
|
||||
scheme_app="$(find ./build/exec -name '*_app')"
|
||||
if [ "$scheme_app" = ''' ]; then
|
||||
mv -- build/exec/* $out/bin/
|
||||
chmod +x $out/bin/*
|
||||
# ^ remove after Idris2 0.8.0 is released. will be superfluous:
|
||||
# https://github.com/idris-lang/Idris2/pull/3189
|
||||
else
|
||||
cd build/exec/*_app
|
||||
rm -f ./libidris2_support.so
|
||||
for file in *.so; do
|
||||
bin_name="''${file%.so}"
|
||||
mv -- "$file" "$out/bin/$bin_name"
|
||||
wrapProgram "$out/bin/$bin_name" \
|
||||
--prefix LD_LIBRARY_PATH : ${supportDir} \
|
||||
--prefix DYLD_LIBRARY_PATH : ${supportDir}
|
||||
done
|
||||
fi
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
|
||||
library =
|
||||
{
|
||||
withSource ? false,
|
||||
}:
|
||||
mkLibrary =
|
||||
withSource:
|
||||
let
|
||||
installCmd = if withSource then "--install-with-src" else "--install";
|
||||
derivation = mkDerivation withSource;
|
||||
in
|
||||
derivation.overrideAttrs {
|
||||
installPhase = ''
|
||||
@ -125,5 +142,30 @@ in
|
||||
idris2 ${installCmd} ${ipkgFileName}
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
# allow a library built without source to be changed to one with source
|
||||
# via a passthru attribute; i.e. `my-pkg.library'.withSource`.
|
||||
# this is convenient because a library derivation can be distributed as
|
||||
# without-source by default but downstream projects can still build it
|
||||
# with-source. We surface this regardless of whether the original library
|
||||
# was built with source because that allows downstream to call this
|
||||
# property unconditionally.
|
||||
passthru = derivation.passthru // {
|
||||
withSource = mkLibrary true;
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
executable = mkExecutable false;
|
||||
|
||||
library =
|
||||
{
|
||||
withSource ? false,
|
||||
}:
|
||||
mkLibrary withSource;
|
||||
|
||||
# Make a library without source; you can still use the `withSource` attribute
|
||||
# on the resulting derivation to build the library with source at a later time.
|
||||
library' = mkLibrary false;
|
||||
}
|
||||
|
@ -55,12 +55,13 @@ let
|
||||
{
|
||||
testName,
|
||||
buildIdrisArgs,
|
||||
makeExecutable,
|
||||
# function that takes result of `buildIdris` and transforms it (commonly
|
||||
# by calling `.executable` or `.library {}` upon it):
|
||||
transformBuildIdrisOutput,
|
||||
expectedTree,
|
||||
}:
|
||||
let
|
||||
final = pkg: if makeExecutable then pkg.executable else pkg.library { };
|
||||
idrisPkg = final (idris2Packages.buildIdris buildIdrisArgs);
|
||||
idrisPkg = transformBuildIdrisOutput (idris2Packages.buildIdris buildIdrisArgs);
|
||||
in
|
||||
runCommand "${pname}-${testName}"
|
||||
{
|
||||
@ -140,7 +141,7 @@ in
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
makeExecutable = false;
|
||||
transformBuildIdrisOutput = pkg: pkg.library { withSource = false; };
|
||||
expectedTree = ''
|
||||
`-- lib
|
||||
`-- idris2-0.7.0
|
||||
@ -153,6 +154,82 @@ in
|
||||
5 directories, 3 files'';
|
||||
};
|
||||
|
||||
buildLibraryWithSource = testBuildIdris {
|
||||
testName = "library-with-source-package";
|
||||
buildIdrisArgs = {
|
||||
ipkgName = "pkg";
|
||||
idrisLibraries = [ idris2Packages.idris2Api ];
|
||||
src = runCommand "library-package-src" { } ''
|
||||
mkdir $out
|
||||
|
||||
cat > $out/Main.idr <<EOF
|
||||
module Main
|
||||
|
||||
import Compiler.ANF -- from Idris2Api
|
||||
|
||||
hello : String
|
||||
hello = "world"
|
||||
EOF
|
||||
|
||||
cat > $out/pkg.ipkg <<EOF
|
||||
package pkg
|
||||
modules = Main
|
||||
depends = idris2
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
transformBuildIdrisOutput = pkg: pkg.library { withSource = true; };
|
||||
expectedTree = ''
|
||||
`-- lib
|
||||
`-- idris2-0.7.0
|
||||
`-- pkg-0
|
||||
|-- 2023090800
|
||||
| |-- Main.ttc
|
||||
| `-- Main.ttm
|
||||
|-- Main.idr
|
||||
`-- pkg.ipkg
|
||||
|
||||
5 directories, 4 files'';
|
||||
};
|
||||
|
||||
buildLibraryWithSourceRetroactively = testBuildIdris {
|
||||
testName = "library-with-source-retro-package";
|
||||
buildIdrisArgs = {
|
||||
ipkgName = "pkg";
|
||||
idrisLibraries = [ idris2Packages.idris2Api ];
|
||||
src = runCommand "library-package-src" { } ''
|
||||
mkdir $out
|
||||
|
||||
cat > $out/Main.idr <<EOF
|
||||
module Main
|
||||
|
||||
import Compiler.ANF -- from Idris2Api
|
||||
|
||||
hello : String
|
||||
hello = "world"
|
||||
EOF
|
||||
|
||||
cat > $out/pkg.ipkg <<EOF
|
||||
package pkg
|
||||
modules = Main
|
||||
depends = idris2
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
transformBuildIdrisOutput = pkg: pkg.library'.withSource;
|
||||
expectedTree = ''
|
||||
`-- lib
|
||||
`-- idris2-0.7.0
|
||||
`-- pkg-0
|
||||
|-- 2023090800
|
||||
| |-- Main.ttc
|
||||
| `-- Main.ttm
|
||||
|-- Main.idr
|
||||
`-- pkg.ipkg
|
||||
|
||||
5 directories, 4 files'';
|
||||
};
|
||||
|
||||
buildExecutable = testBuildIdris {
|
||||
testName = "executable-package";
|
||||
buildIdrisArgs = {
|
||||
@ -176,7 +253,7 @@ in
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
makeExecutable = true;
|
||||
transformBuildIdrisOutput = pkg: pkg.executable;
|
||||
expectedTree = ''
|
||||
`-- bin
|
||||
`-- mypkg
|
||||
|
Loading…
x
Reference in New Issue
Block a user