1{
2 jdk,
3 version,
4 src,
5 lib,
6 stdenv,
7 gradle,
8 extraConfig ? [ ],
9 rsync,
10 runCommand,
11 testers,
12}:
13
14# Each Corretto version is based on a corresponding OpenJDK version. So
15# building Corretto is more or less the same as building OpenJDK. Hence, the
16# Corretto derivation overrides the corresponding OpenJDK derivation in order
17# to have access to all the version-specific fixes for the various OpenJDK
18# builds. However, Corretto uses `gradle` as build tool (which in turn will
19# invoke `make`). The configure/build phases are adapted as needed.
20
21# The version scheme is different between OpenJDK & Corretto.
22# See https://github.com/corretto/corretto-17/blob/release-17.0.8.8.1/build.gradle#L40
23# "major.minor.security.build.revision"
24let
25 majorVersion = builtins.head (lib.strings.splitString "." version); # same as "featureVersion" for OpenJDK
26 pname = "corretto${majorVersion}";
27in
28jdk.overrideAttrs (
29 finalAttrs: oldAttrs: {
30 inherit pname version src;
31 name = "${pname}-${version}";
32
33 nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [
34 jdk
35 gradle
36 rsync
37 ];
38
39 dontConfigure = true;
40
41 postPatch =
42 let
43 extra_config = builtins.concatStringsSep " " extraConfig;
44 in
45 ''
46 # The rpm/deb task definitions require a Gradle plugin which we don't
47 # have and so the build fails. We'll simply remove them here because
48 # they are not needed anyways.
49 rm -rf installers/linux/universal/{rpm,deb}
50
51 # `/usr/bin/rsync` is invoked to copy the source tree. We don't have that.
52 for file in $(find installers -name "build.gradle"); do
53 substituteInPlace $file --replace-warn "workingDir '/usr/bin'" "workingDir '.'"
54 done
55
56 gradleFlagsArray+=(-Pcorretto.extra_config="${extra_config}")
57 '';
58
59 # since we dontConfigure, we must run this manually
60 preBuild = "gradleConfigureHook";
61
62 # The Linux installer is placed at linux/universal/tar whereas the MacOS
63 # one is at mac/tar.
64 gradleBuildTask =
65 if stdenv.hostPlatform.isDarwin then
66 ":installers:mac:tar:build"
67 else
68 ":installers:linux:universal:tar:packageBuildResults";
69
70 postBuild = ''
71 # Prepare for the installPhase so that it looks like if a normal
72 # OpenJDK had been built.
73 dir=build/jdkImageName/images
74 mkdir -p $dir
75 file=$(find ./installers -name 'amazon-corretto-${version}*.tar.gz')
76 tar -xzf $file -C $dir
77 mv $dir/amazon-corretto-* $dir/jdk
78 ''
79 + oldAttrs.postBuild or "";
80
81 installPhase = oldAttrs.installPhase + ''
82 # The installPhase will place everything in $out/lib/openjdk and
83 # reference through symlinks. We don't rewrite the installPhase but at
84 # least move the folder to convey that this is not OpenJDK anymore.
85 mv $out/lib/openjdk $out/lib/corretto
86 ln -s $out/lib/corretto $out/lib/openjdk
87 '';
88
89 passthru =
90 let
91 pkg = finalAttrs.finalPackage;
92 in
93 oldAttrs.passthru
94 // {
95 tests = {
96 version = testers.testVersion { package = pkg; };
97 vendor = runCommand "${pname}-vendor" { nativeBuildInputs = [ pkg ]; } ''
98 output=$(${pkg.meta.mainProgram} -XshowSettings:properties -version 2>&1 | grep vendor)
99 grep -Fq "java.vendor = Amazon.com Inc." - <<< "$output" && touch $out
100 '';
101 compiler = runCommand "${pname}-compiler" { nativeBuildInputs = [ pkg ]; } ''
102 cat << EOF > Main.java
103 class Main {
104 public static void main(String[] args) {
105 System.out.println("Hello, World!");
106 }
107 }
108 EOF
109 ${pkg}/bin/javac Main.java
110 ${pkg}/bin/java Main | grep -q "Hello, World!" && touch $out
111 '';
112 };
113 };
114
115 # Some of the OpenJDK derivation set their `pos` by hand. We need to
116 # overwrite this in order to point to Corretto, not OpenJDK.
117 pos = __curPos;
118 meta = oldAttrs.meta // {
119 homepage = "https://aws.amazon.com/corretto";
120 license = lib.licenses.gpl2Only;
121 description = "Amazon's distribution of OpenJDK";
122 maintainers = with lib.maintainers; [ rollf ];
123 teams = [ ];
124 };
125 }
126)