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