at master 349 lines 12 kB view raw
1{ 2 callPackage, 3 jdk11, 4 jdk17, 5 jdk21, 6}: 7 8let 9 wrapGradle = 10 { 11 lib, 12 callPackage, 13 mitm-cache, 14 replaceVars, 15 symlinkJoin, 16 concatTextFile, 17 makeSetupHook, 18 nix-update-script, 19 20 # This is the "current" version of gradle in nixpkgs. 21 # Used to define the update script. 22 gradle-unwrapped, 23 24 runCommand, 25 }: 26 this-gradle-unwrapped: 27 lib.makeOverridable ( 28 args: 29 let 30 gradle = this-gradle-unwrapped.override args; 31 in 32 symlinkJoin { 33 pname = "gradle"; 34 inherit (gradle) version; 35 36 paths = [ 37 (makeSetupHook { name = "gradle-setup-hook"; } (concatTextFile { 38 name = "setup-hook.sh"; 39 files = [ 40 (mitm-cache.setupHook) 41 (replaceVars ./setup-hook.sh { 42 # jdk used for keytool 43 inherit (gradle) jdk; 44 init_script = "${./init-build.gradle}"; 45 }) 46 ]; 47 })) 48 gradle 49 mitm-cache 50 ]; 51 52 passthru = { 53 fetchDeps = callPackage ./fetch-deps.nix { inherit mitm-cache; }; 54 inherit (gradle) jdk; 55 unwrapped = gradle; 56 tests = { 57 toolchains = 58 let 59 javaVersion = lib.getVersion jdk11; 60 javaMajorVersion = lib.versions.major javaVersion; 61 in 62 runCommand "detects-toolchains-from-nix-env" 63 { 64 # Use JDKs that are not the default for any of the gradle versions 65 nativeBuildInputs = [ 66 (gradle.override { 67 javaToolchains = [ 68 jdk11 69 ]; 70 }) 71 ]; 72 src = ./tests/toolchains; 73 } 74 '' 75 cp -a $src/* . 76 substituteInPlace ./build.gradle --replace-fail '@JAVA_VERSION@' '${javaMajorVersion}' 77 env GRADLE_USER_HOME=$TMPDIR/gradle org.gradle.native.dir=$TMPDIR/native \ 78 gradle run --no-daemon --quiet --console plain > $out 79 actual="$(<$out)" 80 if [[ "${javaVersion}" != "$actual"* ]]; then 81 echo "Error: Expected '${javaVersion}', to start with '$actual'" >&2 82 exit 1 83 fi 84 ''; 85 } 86 // gradle.tests; 87 } 88 // lib.optionalAttrs (this-gradle-unwrapped == gradle-unwrapped) { 89 updateScript = nix-update-script { 90 extraArgs = [ 91 "--url=https://github.com/gradle/gradle" 92 # Gradle’s .0 releases are tagged as `vX.Y.0`, but the actual 93 # release version omits the `.0`, so we’ll wanto to only capture 94 # the version up but not including the the trailing `.0`. 95 "--version-regex=^v(\\d+\\.\\d+(?:\\.[1-9]\\d?)?)(\\.0)?$" 96 ]; 97 }; 98 }; 99 100 meta = gradle.meta // { 101 # prefer normal gradle/mitm-cache over this wrapper, this wrapper only provides the setup hook 102 # and passthru 103 priority = (gradle.meta.priority or lib.meta.defaultPriority) + 1; 104 }; 105 } 106 ) { }; 107 108 gen = 109 { 110 version, 111 hash, 112 113 # The default JDK/JRE that will be used for derived Gradle packages. 114 # A current LTS version of a JDK is a good choice. 115 defaultJava, 116 117 # The platforms supported by this Gradle package. 118 # Gradle Native-Platform ships some binaries that 119 # are compatible only with specific platforms. 120 # As of 2022-04 this affects platform compatibility 121 # of multiple Gradle releases, so this is used as default. 122 # See https://github.com/gradle/native-platform#supported-platforms 123 platforms ? [ 124 "aarch64-darwin" 125 "aarch64-linux" 126 "i686-windows" 127 "x86_64-cygwin" 128 "x86_64-darwin" 129 "x86_64-linux" 130 "x86_64-windows" 131 ], 132 133 # Extra attributes to be merged into the resulting derivation's 134 # meta attribute. 135 meta ? { }, 136 }@genArgs: 137 138 { 139 lib, 140 stdenv, 141 fetchurl, 142 callPackage, 143 makeWrapper, 144 unzip, 145 ncurses5, 146 ncurses6, 147 udev, 148 testers, 149 runCommand, 150 writeText, 151 autoPatchelfHook, 152 buildPackages, 153 154 # The JDK/JRE used for running Gradle. 155 java ? defaultJava, 156 157 # Additional JDK/JREs to be registered as toolchains. 158 # See https://docs.gradle.org/current/userguide/toolchains.html 159 javaToolchains ? [ ], 160 }: 161 162 stdenv.mkDerivation (finalAttrs: { 163 pname = "gradle"; 164 inherit version; 165 166 src = fetchurl { 167 inherit hash; 168 url = "https://services.gradle.org/distributions/gradle-${version}-bin.zip"; 169 }; 170 171 dontBuild = true; 172 173 nativeBuildInputs = [ 174 makeWrapper 175 unzip 176 ] 177 ++ lib.optionals stdenv.hostPlatform.isLinux [ 178 autoPatchelfHook 179 ]; 180 181 buildInputs = [ 182 stdenv.cc.cc 183 ncurses5 184 ncurses6 185 ]; 186 187 # We only need to patchelf some libs embedded in JARs. 188 dontAutoPatchelf = true; 189 190 installPhase = 191 with builtins; 192 let 193 # set toolchains via installations.path property in gradle.properties. 194 # See https://docs.gradle.org/current/userguide/toolchains.html#sec:custom_loc 195 toolchainPaths = "org.gradle.java.installations.paths=${concatStringsSep "," javaToolchains}"; 196 jnaLibraryPath = if stdenv.hostPlatform.isLinux then lib.makeLibraryPath [ udev ] else ""; 197 jnaFlag = 198 if stdenv.hostPlatform.isLinux then "--add-flags \"-Djna.library.path=${jnaLibraryPath}\"" else ""; 199 in 200 '' 201 mkdir -pv $out/lib/gradle/ 202 cp -rv lib/ $out/lib/gradle/ 203 204 gradle_launcher_jar=$(echo $out/lib/gradle/lib/gradle-launcher-*.jar) 205 test -f $gradle_launcher_jar 206 makeWrapper ${java}/bin/java $out/bin/gradle \ 207 --set JAVA_HOME ${java} \ 208 ${jnaFlag} \ 209 --add-flags "-classpath $gradle_launcher_jar org.gradle.launcher.GradleMain" 210 211 echo "${toolchainPaths}" > $out/lib/gradle/gradle.properties 212 ''; 213 214 dontFixup = !stdenv.hostPlatform.isLinux; 215 216 fixupPhase = 217 let 218 arch = if stdenv.hostPlatform.is64bit then "amd64" else "i386"; 219 newFileEvents = toString (lib.versionAtLeast version "8.12"); 220 in 221 '' 222 # get the correct jar executable for cross 223 export PATH="${buildPackages.jdk}/bin:$PATH" 224 . ${./patching.sh} 225 226 nativeVersion="$(extractVersion native-platform $out/lib/gradle/lib/native-platform-*.jar)" 227 for variant in "" "-ncurses5" "-ncurses6"; do 228 autoPatchelfInJar \ 229 $out/lib/gradle/lib/native-platform-linux-${arch}$variant-''${nativeVersion}.jar \ 230 "${lib.getLib stdenv.cc.cc}/lib64:${ 231 lib.makeLibraryPath [ 232 stdenv.cc.cc 233 ncurses5 234 ncurses6 235 ] 236 }" 237 done 238 239 # The file-events library _seems_ to follow the native-platform version, but 240 # we wont assume that. 241 if [ -n "${newFileEvents}" ]; then 242 fileEventsVersion="$(extractVersion gradle-fileevents $out/lib/gradle/lib/gradle-fileevents-*.jar)" 243 autoPatchelfInJar \ 244 $out/lib/gradle/lib/gradle-fileevents-''${fileEventsVersion}.jar \ 245 "${lib.getLib stdenv.cc.cc}/lib64:${lib.makeLibraryPath [ stdenv.cc.cc ]}" 246 else 247 fileEventsVersion="$(extractVersion file-events $out/lib/gradle/lib/file-events-*.jar)" 248 autoPatchelfInJar \ 249 $out/lib/gradle/lib/file-events-linux-${arch}-''${fileEventsVersion}.jar \ 250 "${lib.getLib stdenv.cc.cc}/lib64:${lib.makeLibraryPath [ stdenv.cc.cc ]}" 251 fi 252 253 # The scanner doesn't pick up the runtime dependency in the jar. 254 # Manually add a reference where it will be found. 255 mkdir $out/nix-support 256 echo ${stdenv.cc.cc} > $out/nix-support/manual-runtime-dependencies 257 # Gradle will refuse to start without _both_ 5 and 6 versions of ncurses. 258 echo ${ncurses5} >> $out/nix-support/manual-runtime-dependencies 259 echo ${ncurses6} >> $out/nix-support/manual-runtime-dependencies 260 ${lib.optionalString stdenv.hostPlatform.isLinux "echo ${udev} >> $out/nix-support/manual-runtime-dependencies"} 261 ''; 262 263 passthru.tests = { 264 version = testers.testVersion { 265 package = finalAttrs.finalPackage; 266 command = '' 267 env GRADLE_USER_HOME=$TMPDIR/gradle org.gradle.native.dir=$TMPDIR/native \ 268 gradle --version 269 ''; 270 }; 271 272 java-application = testers.testEqualContents { 273 assertion = "can build and run a trivial Java application"; 274 expected = writeText "expected" "hello\n"; 275 actual = 276 runCommand "actual" 277 { 278 nativeBuildInputs = [ finalAttrs.finalPackage ]; 279 src = ./tests/java-application; 280 } 281 '' 282 cp -a $src/* . 283 env GRADLE_USER_HOME=$TMPDIR/gradle org.gradle.native.dir=$TMPDIR/native \ 284 gradle run --no-daemon --quiet --console plain > $out 285 ''; 286 }; 287 }; 288 passthru.jdk = defaultJava; 289 passthru.wrapped = callPackage wrapGradle { } (gen' genArgs); 290 291 meta = 292 with lib; 293 { 294 inherit platforms; 295 description = "Enterprise-grade build system"; 296 longDescription = '' 297 Gradle is a build system which offers you ease, power and freedom. 298 You can choose the balance for yourself. It has powerful multi-project 299 build support. It has a layer on top of Ivy that provides a 300 build-by-convention integration for Ivy. It gives you always the choice 301 between the flexibility of Ant and the convenience of a 302 build-by-convention behavior. 303 ''; 304 homepage = "https://www.gradle.org/"; 305 changelog = "https://docs.gradle.org/${version}/release-notes.html"; 306 downloadPage = "https://gradle.org/next-steps/?version=${version}"; 307 sourceProvenance = with sourceTypes; [ 308 binaryBytecode 309 binaryNativeCode 310 ]; 311 license = licenses.asl20; 312 maintainers = with maintainers; [ 313 britter 314 liff 315 lorenzleutgeb 316 ]; 317 teams = [ lib.teams.java ]; 318 mainProgram = "gradle"; 319 } 320 // meta; 321 }); 322 323 # Calls the generated Gradle package with default arguments. 324 gen' = args: callPackage (gen args) { }; 325in 326rec { 327 # NOTE: Default JDKs that are hardcoded below must be LTS versions 328 # and respect the compatibility matrix at 329 # https://docs.gradle.org/current/userguide/compatibility.html 330 331 gradle_9 = gen' { 332 version = "9.1.0"; 333 hash = "sha256-oX3dhaJran9d23H/iwX8UQTAICxuZHgkKXkMkzaGyAY="; 334 defaultJava = jdk21; 335 }; 336 gradle_8 = gen' { 337 version = "8.14.3"; 338 hash = "sha256-vXEQIhNJMGCVbsIp2Ua+7lcVjb2J0OYrkbyg+ixfNTE="; 339 defaultJava = jdk21; 340 }; 341 gradle_7 = gen' { 342 version = "7.6.6"; 343 hash = "sha256-Zz2XdvMDvHBI/DMp0jLW6/EFGweJO9nRFhb62ahnO+A="; 344 defaultJava = jdk17; 345 }; 346 347 # Default version of Gradle in nixpkgs. 348 gradle = gradle_8; 349}