1{
2 lib,
3 stdenv,
4 alsa-lib,
5 autoPatchelfHook,
6 cairo,
7 cups,
8 fontconfig,
9 glib,
10 glibc,
11 gtk3,
12 makeWrapper,
13 musl,
14 runCommandCC,
15 setJavaClassPath,
16 unzip,
17 xorg,
18 zlib,
19 # extra params
20 extraCLibs ? [ ],
21 gtkSupport ? stdenv.hostPlatform.isLinux,
22 useMusl ? false,
23 ...
24}@args:
25
26let
27 extraArgs = builtins.removeAttrs args [
28 "lib"
29 "stdenv"
30 "alsa-lib"
31 "autoPatchelfHook"
32 "cairo"
33 "cups"
34 "darwin"
35 "darwinMinVersionHook"
36 "fontconfig"
37 "glib"
38 "glibc"
39 "gtk3"
40 "makeWrapper"
41 "musl"
42 "runCommandCC"
43 "setJavaClassPath"
44 "unzip"
45 "xorg"
46 "zlib"
47 "extraCLibs"
48 "gtkSupport"
49 "useMusl"
50 "passthru"
51 "meta"
52 ];
53
54 cLibs = lib.optionals stdenv.hostPlatform.isLinux (
55 [
56 glibc
57 zlib.static
58 ]
59 ++ lib.optionals (!useMusl) [ glibc.static ]
60 ++ lib.optionals useMusl [ musl ]
61 ++ extraCLibs
62 );
63
64 # GraalVM 21.3.0+ expects musl-gcc as <system>-musl-gcc
65 musl-gcc = (
66 runCommandCC "musl-gcc" { } ''
67 mkdir -p $out/bin
68 ln -s ${lib.getDev musl}/bin/musl-gcc $out/bin/${stdenv.hostPlatform.system}-musl-gcc
69 ''
70 );
71 binPath = lib.makeBinPath (lib.optionals useMusl [ musl-gcc ] ++ [ stdenv.cc ]);
72
73 runtimeLibraryPath = lib.makeLibraryPath (
74 [ cups ]
75 ++ lib.optionals gtkSupport [
76 cairo
77 glib
78 gtk3
79 ]
80 );
81
82 graalvm-ce = stdenv.mkDerivation (
83 {
84 pname = "graalvm-ce";
85
86 unpackPhase = ''
87 runHook preUnpack
88
89 mkdir -p "$out"
90
91 # The tarball on Linux has the following directory structure:
92 #
93 # graalvm-ce-java11-20.3.0/*
94 #
95 # while on Darwin it looks like this:
96 #
97 # graalvm-ce-java11-20.3.0/Contents/Home/*
98 #
99 # We therefor use --strip-components=1 vs 3 depending on the platform.
100 tar xf "$src" -C "$out" --strip-components=${if stdenv.hostPlatform.isLinux then "1" else "3"}
101
102 # Sanity check
103 if [ ! -d "$out/bin" ]; then
104 echo "The `bin` is directory missing after extracting the graalvm"
105 echo "tarball, please compare the directory structure of the"
106 echo "tarball with what happens in the unpackPhase (in particular"
107 echo "with regards to the `--strip-components` flag)."
108 exit 1
109 fi
110
111 runHook postUnpack
112 '';
113
114 dontStrip = true;
115
116 nativeBuildInputs = [
117 unzip
118 makeWrapper
119 ]
120 ++ lib.optional stdenv.hostPlatform.isLinux autoPatchelfHook;
121
122 propagatedBuildInputs = [
123 setJavaClassPath
124 zlib
125 ];
126
127 buildInputs = lib.optionals stdenv.hostPlatform.isLinux [
128 alsa-lib # libasound.so wanted by lib/libjsound.so
129 fontconfig
130 (lib.getLib stdenv.cc.cc) # libstdc++.so.6
131 xorg.libX11
132 xorg.libXext
133 xorg.libXi
134 xorg.libXrender
135 xorg.libXtst
136 ];
137
138 postInstall =
139 let
140 cLibsAsFlags = (map (l: "--add-flags '-H:CLibraryPath=${l}/lib'") cLibs);
141 preservedNixVariables = [
142 "-ENIX_BINTOOLS"
143 "-ENIX_BINTOOLS_WRAPPER_TARGET_HOST_${stdenv.cc.suffixSalt}"
144 "-ENIX_BUILD_CORES"
145 "-ENIX_BUILD_TOP"
146 "-ENIX_CC"
147 "-ENIX_CC_WRAPPER_TARGET_HOST_${stdenv.cc.suffixSalt}"
148 "-ENIX_CFLAGS_COMPILE"
149 "-ENIX_HARDENING_ENABLE"
150 "-ENIX_LDFLAGS"
151 ]
152 ++ lib.optionals stdenv.hostPlatform.isLinux [
153 "-ELOCALE_ARCHIVE"
154 ]
155 ++ lib.optionals stdenv.hostPlatform.isDarwin [
156 "-EDEVELOPER_DIR"
157 "-EDEVELOPER_DIR_FOR_BUILD"
158 "-EDEVELOPER_DIR_FOR_TARGET"
159 "-EMACOSX_DEPLOYMENT_TARGET"
160 "-EMACOSX_DEPLOYMENT_TARGET_FOR_BUILD"
161 "-EMACOSX_DEPLOYMENT_TARGET_FOR_TARGET"
162 "-ENIX_APPLE_SDK_VERSION"
163 ];
164 preservedNixVariablesAsFlags = (map (f: "--add-flags '${f}'") preservedNixVariables);
165 in
166 ''
167 # jni.h expects jni_md.h to be in the header search path.
168 ln -sf $out/include/linux/*_md.h $out/include/
169
170 mkdir -p $out/share
171 # move files in $out like LICENSE.txt
172 find $out/ -maxdepth 1 -type f -exec mv {} $out/share \;
173 # symbolic link to $out/lib/svm/LICENSE_NATIVEIMAGE.txt
174 rm -f $out/LICENSE_NATIVEIMAGE.txt
175
176 # copy-paste openjdk's preFixup
177 # Set JAVA_HOME automatically.
178 mkdir -p $out/nix-support
179 cat > $out/nix-support/setup-hook << EOF
180 if [ -z "\''${JAVA_HOME-}" ]; then export JAVA_HOME=$out; fi
181 EOF
182
183 wrapProgram $out/bin/native-image \
184 --prefix PATH : ${binPath} \
185 ${toString (cLibsAsFlags ++ preservedNixVariablesAsFlags)}
186 '';
187
188 preFixup = lib.optionalString (stdenv.hostPlatform.isLinux) ''
189 for bin in $(find "$out/bin" -executable -type f); do
190 wrapProgram "$bin" --prefix LD_LIBRARY_PATH : "${runtimeLibraryPath}"
191 done
192 '';
193
194 doInstallCheck = true;
195 installCheckPhase = ''
196 runHook preInstallCheck
197
198 ${
199 # broken in darwin
200 lib.optionalString stdenv.hostPlatform.isLinux ''
201 echo "Testing Jshell"
202 echo '1 + 1' | $out/bin/jshell
203 ''
204 }
205
206 echo ${lib.escapeShellArg ''
207 public class HelloWorld {
208 public static void main(String[] args) {
209 System.out.println("Hello World");
210 }
211 }
212 ''} > HelloWorld.java
213 $out/bin/javac HelloWorld.java
214
215 # run on JVM with Graal Compiler
216 echo "Testing GraalVM"
217 $out/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler HelloWorld | fgrep 'Hello World'
218
219 echo "Ahead-Of-Time compilation"
220 $out/bin/native-image -H:+UnlockExperimentalVMOptions -H:-CheckToolchain -H:+ReportExceptionStackTraces -march=compatibility HelloWorld
221 ./helloworld | fgrep 'Hello World'
222
223 ${
224 # -H:+StaticExecutableWithDynamicLibC is only available in Linux
225 lib.optionalString (stdenv.hostPlatform.isLinux && !useMusl) ''
226 echo "Ahead-Of-Time compilation with -H:+StaticExecutableWithDynamicLibC"
227 $out/bin/native-image -H:+UnlockExperimentalVMOptions -H:+StaticExecutableWithDynamicLibC -march=compatibility $extraNativeImageArgs HelloWorld
228 ./helloworld | fgrep 'Hello World'
229 ''
230 }
231
232 ${
233 # --static is only available in x86_64 Linux
234 lib.optionalString (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isx86_64 && useMusl) ''
235 echo "Ahead-Of-Time compilation with --static and --libc=musl"
236 $out/bin/native-image $extraNativeImageArgs -march=compatibility --libc=musl --static HelloWorld
237 ./helloworld | fgrep 'Hello World'
238 ''
239 }
240
241 runHook postInstallCheck
242 '';
243
244 passthru = {
245 home = graalvm-ce;
246 updateScript = [
247 ./update.sh
248 "graalvm-ce"
249 ];
250 }
251 // (args.passhtru or { });
252
253 meta =
254 with lib;
255 (
256 {
257 homepage = "https://www.graalvm.org/";
258 description = "High-Performance Polyglot VM";
259 license = with licenses; [
260 upl
261 gpl2
262 classpathException20
263 bsd3
264 ];
265 sourceProvenance = with sourceTypes; [ binaryNativeCode ];
266 mainProgram = "java";
267 teams = [ teams.graalvm-ce ];
268 }
269 // (args.meta or { })
270 );
271 }
272 // extraArgs
273 );
274in
275graalvm-ce