nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 featureVersion,
3
4 lib,
5 stdenv,
6
7 fetchurl,
8 fetchpatch,
9
10 buildPackages,
11 autoPatchelfHook,
12 pkg-config,
13 autoconf,
14 lndir,
15 unzip,
16 ensureNewerSourcesForZipFilesHook,
17 pandoc,
18
19 cpio,
20 file,
21 which,
22 zip,
23 zlib,
24 cups,
25 freetype,
26 harfbuzz,
27 alsa-lib,
28 libjpeg,
29 giflib,
30 libpng,
31 lcms2,
32 libX11,
33 libICE,
34 libXext,
35 libXrender,
36 libXtst,
37 libXt,
38 libXi,
39 libXinerama,
40 libXcursor,
41 libXrandr,
42 fontconfig,
43
44 setJavaClassPath,
45
46 versionCheckHook,
47
48 liberation_ttf,
49 cacert,
50 jre-generate-cacerts,
51
52 nixpkgs-openjdk-updater,
53
54 # TODO(@sternenseemann): gtk3 fails to evaluate in pkgsCross.ghcjs.buildPackages
55 # which should be fixable, this is a no-rebuild workaround for GHC.
56 headless ? lib.versionAtLeast featureVersion "21" && stdenv.targetPlatform.isGhcjs,
57
58 enableJavaFX ? false,
59 openjfx17,
60 openjfx21,
61 openjfx25,
62 openjfx_jdk ?
63 {
64 "17" = openjfx17;
65 "21" = openjfx21;
66 "25" = openjfx25;
67 }
68 .${featureVersion} or (throw "JavaFX is not supported on OpenJDK ${featureVersion}"),
69
70 enableGtk ? true,
71 gtk3,
72 gtk2,
73 glib,
74
75 temurin-bin-8,
76 temurin-bin-11,
77 temurin-bin-17,
78 temurin-bin-21,
79 temurin-bin-25,
80 jdk-bootstrap ?
81 {
82 "8" = temurin-bin-8.__spliced.buildBuild or temurin-bin-8;
83 "11" = temurin-bin-11.__spliced.buildBuild or temurin-bin-11;
84 "17" = temurin-bin-17.__spliced.buildBuild or temurin-bin-17;
85 "21" = temurin-bin-21.__spliced.buildBuild or temurin-bin-21;
86 "25" = temurin-bin-25.__spliced.buildBuild or temurin-bin-25;
87 }
88 .${featureVersion},
89}:
90
91let
92 sourceFile = ./. + "/${featureVersion}/source.json";
93 source = nixpkgs-openjdk-updater.openjdkSource {
94 inherit sourceFile;
95 featureVersionPrefix = tagPrefix + featureVersion;
96 };
97
98 atLeast11 = lib.versionAtLeast featureVersion "11";
99 atLeast17 = lib.versionAtLeast featureVersion "17";
100 atLeast21 = lib.versionAtLeast featureVersion "21";
101 atLeast23 = lib.versionAtLeast featureVersion "23";
102 atLeast25 = lib.versionAtLeast featureVersion "25";
103
104 tagPrefix = if atLeast11 then "jdk-" else "jdk";
105 version = lib.removePrefix "refs/tags/${tagPrefix}" source.src.rev;
106 versionSplit = builtins.match (if atLeast11 then "(.+)+(.+)" else "(.+)-b(.+)") version;
107 versionBuild = lib.elemAt versionSplit 1;
108
109 # The JRE 8 libraries are in directories that depend on the CPU.
110 architecture =
111 if atLeast11 then
112 ""
113 else
114 {
115 i686-linux = "i386";
116 x86_64-linux = "amd64";
117 aarch64-linux = "aarch64";
118 powerpc64le-linux = "ppc64le";
119 }
120 .${stdenv.system} or (throw "Unsupported platform ${stdenv.system}");
121
122 jdk-bootstrap' = jdk-bootstrap.override {
123 # when building a headless jdk, also bootstrap it with a headless jdk
124 gtkSupport = !headless;
125 };
126in
127
128assert lib.assertMsg (lib.pathExists sourceFile)
129 "OpenJDK ${featureVersion} is not a supported version";
130
131stdenv.mkDerivation (finalAttrs: {
132 pname = "openjdk" + lib.optionalString headless "-headless";
133 inherit version;
134
135 outputs = [
136 "out"
137 ]
138 ++ lib.optionals (!atLeast11) [
139 "jre"
140 ];
141
142 inherit (source) src;
143
144 patches = [
145 (
146 if atLeast25 then
147 ./25/patches/fix-java-home-jdk25.patch
148 else if atLeast21 then
149 ./21/patches/fix-java-home-jdk21.patch
150 else if atLeast11 then
151 ./11/patches/fix-java-home-jdk10.patch
152 else
153 ./8/patches/fix-java-home-jdk8.patch
154 )
155 (
156 if atLeast25 then
157 ./25/patches/read-truststore-from-env-jdk25.patch
158 else if atLeast11 then
159 ./11/patches/read-truststore-from-env-jdk10.patch
160 else
161 ./8/patches/read-truststore-from-env-jdk8.patch
162 )
163 ]
164 ++ lib.optionals (!atLeast23) [
165 (
166 if atLeast11 then
167 ./11/patches/currency-date-range-jdk10.patch
168 else
169 ./8/patches/currency-date-range-jdk8.patch
170 )
171 ]
172 ++ lib.optionals atLeast11 [
173 (
174 if atLeast17 then
175 ./17/patches/increase-javadoc-heap-jdk13.patch
176 else
177 ./11/patches/increase-javadoc-heap.patch
178 )
179 ]
180 ++ lib.optionals atLeast17 [
181 (
182 if atLeast21 then
183 ./21/patches/ignore-LegalNoticeFilePlugin-jdk18.patch
184 else
185 ./17/patches/ignore-LegalNoticeFilePlugin-jdk17.patch
186 )
187 ]
188 ++ lib.optionals (!atLeast21) [
189 (
190 if atLeast17 then
191 ./17/patches/fix-library-path-jdk17.patch
192 else if atLeast11 then
193 ./11/patches/fix-library-path-jdk11.patch
194 else
195 ./8/patches/fix-library-path-jdk8.patch
196 )
197 ]
198 ++ lib.optionals (atLeast17 && !atLeast23) [
199 # -Wformat etc. are stricter in newer gccs, per
200 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79677
201 # so grab the work-around from
202 # https://src.fedoraproject.org/rpms/java-openjdk/pull-request/24
203 (fetchurl {
204 url = "https://src.fedoraproject.org/rpms/java-openjdk/raw/06c001c7d87f2e9fe4fedeef2d993bcd5d7afa2a/f/rh1673833-remove_removal_of_wformat_during_test_compilation.patch";
205 sha256 = "082lmc30x64x583vqq00c8y0wqih3y4r0mp1c4bqq36l22qv6b6r";
206 })
207 ]
208 ++ lib.optionals (featureVersion == "17") [
209 # Patch borrowed from Alpine to fix build errors with musl libc and recent gcc.
210 # This is applied anywhere to prevent patchrot.
211 (fetchurl {
212 url = "https://git.alpinelinux.org/aports/plain/community/openjdk17/FixNullPtrCast.patch?id=41e78a067953e0b13d062d632bae6c4f8028d91c";
213 sha256 = "sha256-LzmSew51+DyqqGyyMw2fbXeBluCiCYsS1nCjt9hX6zo=";
214 })
215 ]
216 ++ lib.optionals (atLeast11 && !atLeast25) [
217 # Fix build for gnumake-4.4.1:
218 # https://github.com/openjdk/jdk/pull/12992
219 (fetchpatch {
220 name = "gnumake-4.4.1";
221 url = "https://github.com/openjdk/jdk/commit/9341d135b855cc208d48e47d30cd90aafa354c36.patch";
222 hash = "sha256-Qcm3ZmGCOYLZcskNjj7DYR85R4v07vYvvavrVOYL8vg=";
223 })
224 ]
225 ++ lib.optionals atLeast25 [
226 ./25/patches/make-4.4.1.patch
227 ]
228 ++ lib.optionals (!headless && enableGtk) [
229 (
230 if atLeast17 then
231 ./17/patches/swing-use-gtk-jdk13.patch
232 else if atLeast11 then
233 ./11/patches/swing-use-gtk-jdk10.patch
234 else
235 ./8/patches/swing-use-gtk-jdk8.patch
236 )
237 ];
238
239 strictDeps = true;
240
241 depsBuildBuild = [ buildPackages.stdenv.cc ];
242
243 nativeBuildInputs = [
244 autoPatchelfHook
245 pkg-config
246 unzip
247 zip
248 which
249 # Probably for BUILD_CC but not sure, not in closure.
250 zlib
251 ]
252 ++ lib.optionals atLeast11 [
253 autoconf
254 ]
255 ++ lib.optionals (!atLeast11) [
256 lndir
257 ]
258 ++ lib.optionals (!atLeast11 && !stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
259 # Certificates generated using keytool in `installPhase`
260 buildPackages.jdk8
261 ]
262 ++ lib.optionals atLeast21 [
263 ensureNewerSourcesForZipFilesHook
264 ]
265 ++ lib.optionals atLeast25 [
266 pandoc
267 ];
268
269 buildInputs = [
270 # TODO: Many of these should likely be in `nativeBuildInputs`.
271 cpio
272 # `-lmagic` in NIX_LDFLAGS
273 file
274 cups
275 freetype
276 alsa-lib
277 libjpeg
278 giflib
279 libX11
280 libICE
281 libXext
282 libXrender
283 libXtst
284 libXt
285 libXi
286 libXinerama
287 libXcursor
288 libXrandr
289 fontconfig
290 ]
291 ++ lib.optionals (atLeast11 && !atLeast21) [
292 harfbuzz
293 ]
294 ++ lib.optionals atLeast11 [
295 libpng
296 zlib # duplicate
297 lcms2
298 ]
299 ++ lib.optionals (!headless && enableGtk) [
300 (if atLeast11 then gtk3 else gtk2)
301 glib
302 ];
303
304 propagatedBuildInputs = [ setJavaClassPath ];
305
306 nativeInstallCheckInputs = lib.optionals atLeast23 [
307 versionCheckHook
308 ];
309
310 # JDK's build system attempts to specifically detect
311 # and special-case WSL, and we don't want it to do that,
312 # so pass the correct platform names explicitly
313 configurePlatforms = lib.optionals atLeast17 [
314 "build"
315 "host"
316 ];
317
318 # https://openjdk.org/groups/build/doc/building.html
319 configureFlags = [
320 # https://github.com/openjdk/jdk/blob/471f112bca715d04304cbe35c6ed63df8c7b7fee/make/autoconf/util_paths.m4#L315
321 # Ignoring value of READELF from the environment. Use command line variables instead.
322 "READELF=${stdenv.cc.targetPrefix}readelf"
323 "AR=${stdenv.cc.targetPrefix}ar"
324 "STRIP=${stdenv.cc.targetPrefix}strip"
325 "NM=${stdenv.cc.targetPrefix}nm"
326 "OBJDUMP=${stdenv.cc.targetPrefix}objdump"
327 "OBJCOPY=${stdenv.cc.targetPrefix}objcopy"
328 "--with-boot-jdk=${jdk-bootstrap'.home}"
329 "--enable-unlimited-crypto"
330 "--with-native-debug-symbols=internal"
331 "--with-stdc++lib=dynamic"
332 "--with-zlib=system"
333 "--with-giflib=system"
334 ]
335 ++ (
336 if atLeast23 then
337 [
338 "--with-version-string=${version}"
339 "--with-vendor-version-string=(nix)"
340 ]
341 else if atLeast11 then
342 lib.optionals atLeast17 [
343 "--with-version-build=${versionBuild}"
344 "--with-version-opt=nixos"
345 ]
346 ++ [
347 "--with-version-pre="
348 ]
349 else
350 [
351 "--with-update-version=${lib.removePrefix "${featureVersion}u" (lib.elemAt versionSplit 0)}"
352 "--with-build-number=${versionBuild}"
353 "--with-milestone=fcs"
354 ]
355 )
356 ++ lib.optionals (!atLeast21) (
357 if atLeast11 then
358 [
359 "--with-freetype=system"
360 "--with-harfbuzz=system"
361 ]
362 else
363 [
364 "--disable-freetype-bundling"
365 ]
366 )
367 ++ lib.optionals atLeast11 [
368 "--with-libjpeg=system"
369 "--with-libpng=system"
370 "--with-lcms=system"
371 ]
372 ++ lib.optionals (featureVersion == "11") [
373 "--disable-warnings-as-errors"
374 ]
375 # OpenJDK 11 cannot be built by recent versions of Clang, as far as I can tell (see
376 # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260319). Known to
377 # compile with LLVM 12.
378 ++ lib.optionals (atLeast11 && stdenv.cc.isClang) [
379 "--with-toolchain-type=clang"
380 # Explicitly tell Clang to compile C++ files as C++, see
381 # https://github.com/NixOS/nixpkgs/issues/150655#issuecomment-1935304859
382 "--with-extra-cxxflags=-xc++"
383 ]
384 # This probably shouldn’t apply to OpenJDK 21; see
385 # b7e68243306833845cbf92e2ea1e0cf782481a51 which removed it for
386 # versions 15 through 20.
387 ++ lib.optional (
388 (featureVersion == "11" || featureVersion == "21") && stdenv.hostPlatform.isx86_64
389 ) "--with-jvm-features=zgc"
390 ++ lib.optional headless (if atLeast11 then "--enable-headless-only" else "--disable-headful")
391 ++ lib.optional (!headless && enableJavaFX) "--with-import-modules=${openjfx_jdk}";
392
393 buildFlags = if atLeast17 then [ "images" ] else [ "all" ];
394
395 separateDebugInfo = true;
396 __structuredAttrs = true;
397
398 # -j flag is explicitly rejected by the build system:
399 # Error: 'make -jN' is not supported, use 'make JOBS=N'
400 # Note: it does not make build sequential. Build system
401 # still runs in parallel.
402 enableParallelBuilding = false;
403
404 preConfigure =
405 # Set number of jobs to use when building.
406 ''
407 configureFlags+=("--with-jobs=''${NIX_BUILD_CORES}")
408 '';
409
410 env = {
411 NIX_CFLAGS_COMPILE =
412 if atLeast17 then
413 "-Wno-error"
414 else if atLeast11 then
415 lib.concatStringsSep " " (
416 # Workaround for
417 # `cc1plus: error: '-Wformat-security' ignored without '-Wformat' [-Werror=format-security]`
418 # when building jtreg
419 [ "-Wformat" ]
420 ++ lib.optionals (stdenv.cc.isGNU && featureVersion == "11") [
421 # Fix build with gcc15
422 "-std=gnu17"
423 ]
424 )
425 else
426 lib.concatStringsSep " " (
427 [
428 # glibc 2.24 deprecated readdir_r so we need this
429 # See https://www.mail-archive.com/openembedded-devel@lists.openembedded.org/msg49006.html
430 "-Wno-error=deprecated-declarations"
431 ]
432 ++ lib.optionals stdenv.cc.isGNU [
433 # https://bugzilla.redhat.com/show_bug.cgi?id=1306558
434 # https://github.com/JetBrains/jdk8u/commit/eaa5e0711a43d64874111254d74893fa299d5716
435 "-fno-lifetime-dse"
436 "-fno-delete-null-pointer-checks"
437 "-std=gnu++98"
438 "-Wno-error"
439 ]
440 ++ [
441 # error by default in GCC 14
442 "-Wno-error=int-conversion"
443 "-Wno-error=incompatible-pointer-types"
444 ]
445 ++ lib.optionals (stdenv.cc.isGNU && featureVersion == "8") [
446 # Fix build with gcc15
447 "-std=gnu17"
448 ]
449 );
450
451 NIX_LDFLAGS = lib.concatStringsSep " " (
452 lib.optionals (!headless) [
453 "-lfontconfig"
454 "-lcups"
455 "-lXinerama"
456 "-lXrandr"
457 "-lmagic"
458 ]
459 ++ lib.optionals (!headless && enableGtk) [
460 (if atLeast11 then "-lgtk-3" else "-lgtk-x11-2.0")
461 "-lgio-2.0"
462 ]
463 );
464 }
465 // lib.optionalAttrs (!atLeast11) {
466 # OpenJDK 8 Hotspot cares about the host(!) version otherwise
467 DISABLE_HOTSPOT_OS_VERSION_CHECK = "ok";
468 };
469
470 versionCheckProgram = lib.optionalString atLeast23 "${placeholder "out"}/bin/java";
471
472 # Fails with "No rule to make target 'y'."
473 doCheck = false;
474
475 doInstallCheck = atLeast23;
476
477 postPatch = ''
478 chmod +x configure
479 patchShebangs --build configure
480 ''
481 + lib.optionalString atLeast25 ''
482 chmod +x make/scripts/*.{template,sh,pl}
483 patchShebangs --build make/scripts
484 ''
485 + lib.optionalString (!atLeast11) ''
486 # Fix build w/ glibc-2.42. Oldest backport target of this fix was
487 # JDK 11.
488 # See https://bugs.openjdk.org/browse/JDK-8354941
489 substituteInPlace \
490 hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp \
491 hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp \
492 hotspot/src/cpu/aarch64/vm/assembler_aarch64.cpp \
493 hotspot/src/share/vm/opto/mulnode.cpp \
494 hotspot/src/share/vm/utilities/globalDefinitions.hpp \
495 --replace-fail "uabs" "g_uabs"
496 '';
497
498 installPhase = ''
499 mkdir -p $out/lib
500 mv build/*/images/${if atLeast11 then "jdk" else "j2sdk-image"} $out/lib/openjdk
501 ''
502 # Remove some broken manpages.
503 + ''
504 rm -rf $out/lib/openjdk/man/ja*
505 ''
506 # Mirror some stuff in top-level.
507 + ''
508 mkdir -p $out/share
509 ln -s $out/lib/openjdk/bin $out/bin
510 ln -s $out/lib/openjdk/include $out/include
511 ln -s $out/lib/openjdk/man $out/share/man
512 ''
513 # IDEs use the provided src.zip to navigate the Java codebase (https://github.com/NixOS/nixpkgs/pull/95081)
514 + lib.optionalString atLeast11 ''
515 ln -s $out/lib/openjdk/lib/src.zip $out/lib/src.zip
516 ''
517 # jni.h expects jni_md.h to be in the header search path.
518 + ''
519 ln -s $out/include/linux/*_md.h $out/include/
520 ''
521 # Remove crap from the installation.
522 + (
523 ''
524 rm -rf $out/lib/openjdk/demo
525 ''
526 + lib.optionalString (!atLeast11) ''
527 rm -rf $out/lib/openjdk/sample
528 ''
529 + lib.optionalString headless (
530 if atLeast11 then
531 ''
532 rm $out/lib/openjdk/lib/{libjsound,libfontmanager}.so
533 ''
534 else
535 ''
536 rm $out/lib/openjdk/jre/lib/${architecture}/{libjsound,libjsoundalsa,libsplashscreen,libfontmanager}.so
537 rm $out/lib/openjdk/jre/bin/policytool
538 rm $out/lib/openjdk/bin/{policytool,appletviewer}
539 ''
540 )
541 )
542 + lib.optionalString (!atLeast11) (
543 # Move the JRE to a separate output
544 ''
545 mkdir -p $jre/lib/openjdk
546 mv $out/lib/openjdk/jre $jre/lib/openjdk/jre
547 mkdir $out/lib/openjdk/jre
548 lndir $jre/lib/openjdk/jre $out/lib/openjdk/jre
549
550 ln -s $jre/lib/openjdk/jre $out/jre
551 ln -s $jre/lib/openjdk/jre/bin $jre/bin
552 ''
553 # Make sure cmm/*.pf are not symlinks:
554 # https://youtrack.jetbrains.com/issue/IDEA-147272
555 + ''
556 rm -rf $out/lib/openjdk/jre/lib/cmm
557 ln -s {$jre,$out}/lib/openjdk/jre/lib/cmm
558 ''
559 # Setup fallback fonts
560 + lib.optionalString (!headless) ''
561 mkdir -p $jre/lib/openjdk/jre/lib/fonts
562 ln -s ${liberation_ttf}/share/fonts/truetype $jre/lib/openjdk/jre/lib/fonts/fallback
563 ''
564 # Remove duplicate binaries.
565 + ''
566 for i in $(ls $out/lib/openjdk/bin); do
567 if [ "$i" = java ]; then continue; fi
568 if cmp -s $out/lib/openjdk/bin/$i $jre/lib/openjdk/jre/bin/$i; then
569 ln -sfn $jre/lib/openjdk/jre/bin/$i $out/lib/openjdk/bin/$i
570 fi
571 done
572 ''
573 # Generate certificates.
574 + ''
575 cd $jre/lib/openjdk/jre/lib/security
576 rm cacerts
577 ${jre-generate-cacerts} ${
578 if stdenv.buildPlatform.canExecute stdenv.hostPlatform then
579 "$jre/lib/openjdk/jre/bin/keytool"
580 else
581 "keytool"
582 } ${cacert}/etc/ssl/certs/ca-bundle.crt
583 ''
584 );
585
586 preFixup =
587 # Set JAVA_HOME automatically.
588 ''
589 mkdir -p $out/nix-support
590 cat <<EOF > $out/nix-support/setup-hook
591 if [ -z "\''${JAVA_HOME-}" ]; then export JAVA_HOME=$out/lib/openjdk; fi
592 EOF
593 ''
594 # Propagate the setJavaClassPath setup hook from the JRE so that
595 # any package that depends on the JRE has $CLASSPATH set up
596 # properly.
597 + lib.optionalString (!atLeast11) ''
598 mkdir -p $jre/nix-support
599 printWords "${setJavaClassPath}" > $jre/nix-support/propagated-build-inputs
600 '';
601
602 # If binaries in the jre output have RPATH dependencies on libraries from the out output, Nix will
603 # detect a cyclic reference and abort the build.
604 # To fix that, we need to patch the binaries from each output in separate auto-patchelf executions.
605 dontAutoPatchelf = true;
606 postFixup = ''
607 autoPatchelf -- $out
608 ''
609 + lib.optionalString (!atLeast11) ''
610 autoPatchelf -- $jre
611 '';
612
613 disallowedReferences = [ jdk-bootstrap' ];
614
615 passthru = {
616 home = "${finalAttrs.finalPackage}/lib/openjdk";
617 # Shouldn't this be `jdk-bootstrap = jdk-bootstrap'`?
618 inherit jdk-bootstrap;
619 inherit (source) updateScript;
620 }
621 // (if atLeast11 then { inherit gtk3; } else { inherit gtk2; })
622 // lib.optionalAttrs (!atLeast23) {
623 inherit architecture;
624 };
625
626 meta = {
627 description = "Open-source Java Development Kit";
628 homepage = "https://openjdk.java.net/";
629 license = lib.licenses.gpl2Only;
630 maintainers = with lib.maintainers; [
631 infinidoge
632 ];
633 teams = [ lib.teams.java ];
634 mainProgram = "java";
635 platforms = [
636 "i686-linux"
637 "x86_64-linux"
638 "aarch64-linux"
639 ]
640 ++ lib.optionals atLeast11 [
641 "armv7l-linux"
642 "armv6l-linux"
643 "powerpc64le-linux"
644 ]
645 ++ lib.optionals atLeast17 [
646 "riscv64-linux"
647 ];
648 # OpenJDK 8 was broken for musl at 2024-01-17. Tracking issue:
649 # https://github.com/NixOS/nixpkgs/issues/281618
650 # error: ‘isnanf’ was not declared in this scope
651 broken = !atLeast11 && stdenv.hostPlatform.isMusl;
652 };
653})