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