From afb99ad5d444beab408e996a3eed005a50558d18 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Tue, 7 Feb 2023 09:56:44 +0000 Subject: [PATCH] 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 . --- .../build-graalvm-native-image/default.nix | 3 +- .../graalvm/community-edition/mkGraal.nix | 63 +++++++++++-------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/pkgs/build-support/build-graalvm-native-image/default.nix b/pkgs/build-support/build-graalvm-native-image/default.nix index f223009cba5..64c6568e1bc 100644 --- a/pkgs/build-support/build-graalvm-native-image/default.nix +++ b/pkgs/build-support/build-graalvm-native-image/default.nix @@ -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; diff --git a/pkgs/development/compilers/graalvm/community-edition/mkGraal.nix b/pkgs/development/compilers/graalvm/community-edition/mkGraal.nix index bd2d4413ec5..b66058d35c9 100644 --- a/pkgs/development/compilers/graalvm/community-edition/mkGraal.nix +++ b/pkgs/development/compilers/graalvm/community-edition/mkGraal.nix @@ -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 = {