graalvm*-ce: wrap native-image to pass -H:CLibraryPath, misc improvements

Fixes issue #214922 by not adding C libraries to the default library
path of GraalVM. This should reduce the closure size of native compiled
binaries in nixpkgs again, e.g.:

Before:
```
$ ldd ./result/bin/bb
	linux-vdso.so.1 (0x00007fff2669b000)
	libstdc++.so.6 => /nix/store/qbgfsaviwqi2p6jr7an1g2754sv3xqhn-gcc-11.3.0-lib/lib/libstdc++.so.6 (0x00007f77fc0cf000)
	libm.so.6 => /nix/store/l7vp7c9z03dspbmss3gq5wdwx5c6ifcq-graalvm11-ce-22.3.0/lib/svm/clibraries/linux-amd64/libm.so.6 (0x00007f77fbfef000)
	libpthread.so.0 => /nix/store/l7vp7c9z03dspbmss3gq5wdwx5c6ifcq-graalvm11-ce-22.3.0/lib/svm/clibraries/linux-amd64/libpthread.so.0 (0x00007f77fbfea000)
	libdl.so.2 => /nix/store/l7vp7c9z03dspbmss3gq5wdwx5c6ifcq-graalvm11-ce-22.3.0/lib/svm/clibraries/linux-amd64/libdl.so.2 (0x00007f77fbfe5000)
	librt.so.1 => /nix/store/l7vp7c9z03dspbmss3gq5wdwx5c6ifcq-graalvm11-ce-22.3.0/lib/svm/clibraries/linux-amd64/librt.so.1 (0x00007f77fbfde000)
	libc.so.6 => /nix/store/l7vp7c9z03dspbmss3gq5wdwx5c6ifcq-graalvm11-ce-22.3.0/lib/svm/clibraries/linux-amd64/libc.so.6 (0x00007f77fbdd5000)
	/nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/ld-linux-x86-64.so.2 => /nix/store/9xfad3b5z4y00mzmk2wnn4900q0qmxns-glibc-2.35-224/lib64/ld-linux-x86-64.so.2 (0x00007f77fc2e7000)
	libgcc_s.so.1 => /nix/store/qbgfsaviwqi2p6jr7an1g2754sv3xqhn-gcc-11.3.0-lib/lib/libgcc_s.so.1 (0x00007f77fbdbb000)
```

After:
```
$ ldd ./result/bin/bb
	linux-vdso.so.1 (0x00007fffdfd4e000)
	libstdc++.so.6 => /nix/store/qbgfsaviwqi2p6jr7an1g2754sv3xqhn-gcc-11.3.0-lib/lib/libstdc++.so.6 (0x00007fc3a5658000)
	libm.so.6 => /nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/libm.so.6 (0x00007fc3a5578000)
	libpthread.so.0 => /nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/libpthread.so.0 (0x00007fc3a5573000)
	libdl.so.2 => /nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/libdl.so.2 (0x00007fc3a556e000)
	librt.so.1 => /nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/librt.so.1 (0x00007fc3a5569000)
	libc.so.6 => /nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/libc.so.6 (0x00007fc3a535e000)
	/nix/store/c35hf8g5b9vksadym9dbjrd6p2y11m8h-glibc-2.35-224/lib/ld-linux-x86-64.so.2 => /nix/store/9xfad3b5z4y00mzmk2wnn4900q0qmxns-glibc-2.35-224/lib64/ld-linux-x86-64.so.2 (0x00007fc3a5870000)
	libgcc_s.so.1 => /nix/store/qbgfsaviwqi2p6jr7an1g2754sv3xqhn-gcc-11.3.0-lib/lib/libgcc_s.so.1 (0x00007fc3a5344000)
```

Also improves the installCheckPhase to include more tests and improve
the old onest .
This commit is contained in:
Thiago Kenji Okada 2023-02-07 09:56:44 +00:00
parent 93783fee57
commit afb99ad5d4
2 changed files with 39 additions and 27 deletions

View file

@ -10,7 +10,6 @@
# except in special cases. In most cases, use extraNativeBuildArgs instead
, nativeImageBuildArgs ? [
"-jar" jar
"-H:CLibraryPath=${lib.getLib graalvm}/lib"
(lib.optionalString stdenv.isDarwin "-H:-CheckToolchain")
"-H:Name=${executable}"
"--verbose"
@ -50,6 +49,8 @@ stdenv.mkDerivation (args // {
runHook postInstall
'';
disallowedReferences = [ graalvmDrv ];
meta = {
# default to graalvm's platforms
platforms = graalvmDrv.meta.platforms;

View file

@ -32,6 +32,8 @@
# Native Image (i.e.: `--static --libc=musl`). This will cause glibc static
# builds to fail, so it should be used with care
, useMusl ? false
# Extra libraries to be included in native-image using '-H:CLibraryPath' flag
, extraCLibs ? [ ]
}:
{ stdenv
@ -76,6 +78,11 @@ let
name = "graalvm${javaVersion}-ce";
sources = builtins.fromJSON (builtins.readFile sourcesPath);
cLibs = [ glibc zlib.static ]
++ lib.optionals (!useMusl) [ glibc.static ]
++ lib.optionals useMusl [ musl ]
++ extraCLibs;
runtimeLibraryPath = lib.makeLibraryPath
([ cups ] ++ lib.optionals gtkSupport [ cairo glib gtk3 ]);
@ -118,6 +125,8 @@ let
++ lib.optional stdenv.hostPlatform.isLinux autoPatchelfHook;
unpackPhase = ''
runHook preUnpack
unpack_jar() {
jar=$1
unzip -q -o $jar -d $out
@ -164,13 +173,13 @@ let
for jar in "''${arr[@]:1}"; do
unpack_jar "$jar"
done
runHook postUnpack
'';
outputs = [ "out" "lib" ];
installPhase = ''
# ensure that $lib/lib exists to avoid breaking builds
mkdir -p "$lib/lib"
runHook preInstall
# jni.h expects jni_md.h to be in the header search path.
ln -s $out/include/linux/*_md.h $out/include/
@ -181,26 +190,15 @@ let
if [ -z "\''${JAVA_HOME-}" ]; then export JAVA_HOME=$out; fi
EOF
${
lib.optionalString (stdenv.isLinux) ''
# provide libraries needed for static compilation
${
if useMusl then
''for f in "${musl.stdenv.cc.cc}/lib/"* "${musl}/lib/"* "${zlib.static}/lib/"*; do''
else
''for f in "${glibc}/lib/"* "${glibc.static}/lib/"* "${zlib.static}/lib/"*; do''
}
ln -s "$f" "$out/lib/svm/clibraries/${platform.arch}/$(basename $f)"
done
# add those libraries to $lib output too, so we can use them with
# `native-image -H:CLibraryPath=''${lib.getLib graalvmXX-ce}/lib ...` and reduce
# closure size by not depending on GraalVM $out (that is much bigger)
# we always use glibc here, since musl is only supported for static compilation
for f in "${glibc}/lib/"*; do
ln -s "$f" "$lib/lib/$(basename $f)"
done
# Wrap native-image binary to pass -H:CLibraryPath flag and find glibc
lib.optionalString (withNativeImageSvm && stdenv.isLinux) ''
wrapProgram $out/bin/native-image \
${lib.concatStringsSep " "
(map (l: "--add-flags '-H:CLibraryPath=${l}/lib'") cLibs)}
''
}
runHook postInstall
'';
dontStrip = true;
@ -240,6 +238,8 @@ let
doInstallCheck = true;
installCheckPhase = ''
runHook preInstallCheck
echo ${
lib.escapeShellArg ''
public class HelloWorld {
@ -252,16 +252,25 @@ let
$out/bin/javac HelloWorld.java
# run on JVM with Graal Compiler
echo "Testing GraalVM"
$out/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler HelloWorld | fgrep 'Hello World'
${
lib.optionalString withNativeImageSvm ''
echo "Ahead-Of-Time compilation"
$out/bin/native-image -H:-CheckToolchain -H:+ReportExceptionStackTraces HelloWorld
./helloworld | fgrep 'Hello World'
''
}
${# --static flag doesn't work for darwin
lib.optionalString (withNativeImageSvm && stdenv.isLinux && !useMusl) ''
echo "Ahead-Of-Time compilation"
$out/bin/native-image -H:-CheckToolchain -H:+ReportExceptionStackTraces --no-server HelloWorld
echo "Ahead-Of-Time compilation with -H:+StaticExecutableWithDynamicLibC"
$out/bin/native-image -H:+StaticExecutableWithDynamicLibC HelloWorld
./helloworld | fgrep 'Hello World'
echo "Ahead-Of-Time compilation with --static"
$out/bin/native-image --no-server --static HelloWorld
$out/bin/native-image --static HelloWorld
./helloworld | fgrep 'Hello World'
''
}
@ -269,7 +278,7 @@ let
${# --static flag doesn't work for darwin
lib.optionalString (withNativeImageSvm && stdenv.isLinux && useMusl) ''
echo "Ahead-Of-Time compilation with --static and --libc=musl"
$out/bin/native-image --no-server --libc=musl --static HelloWorld
$out/bin/native-image --libc=musl --static HelloWorld
./helloworld | fgrep 'Hello World'
''
}
@ -302,6 +311,8 @@ let
echo '1 + 1' | $out/bin/irb
''
}
runHook postInstallCheck
'';
passthru = {