nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at fix-function-merge 189 lines 7.3 kB view raw view rendered
1# Gradle {#gradle} 2 3Gradle is a popular build tool for Java/Kotlin. Gradle itself doesn't 4currently provide tools to make dependency resolution reproducible, so 5nixpkgs has a proxy designed for intercepting Gradle web requests to 6record dependencies so they can be restored in a reproducible fashion. 7 8## Building a Gradle package {#building-a-gradle-package} 9 10Here's how a typical derivation will look like: 11 12```nix 13stdenv.mkDerivation (finalAttrs: { 14 pname = "pdftk"; 15 version = "3.3.3"; 16 17 src = fetchFromGitLab { 18 owner = "pdftk-java"; 19 repo = "pdftk"; 20 rev = "v${finalAttrs.version}"; 21 hash = "sha256-ciKotTHSEcITfQYKFZ6sY2LZnXGChBJy0+eno8B3YHY="; 22 }; 23 24 nativeBuildInputs = [ gradle ]; 25 26 # if the package has dependencies, mitmCache must be set 27 mitmCache = gradle.fetchDeps { 28 inherit (finalAttrs) pname; 29 data = ./deps.json; 30 }; 31 32 # this is required for using mitm-cache on Darwin 33 __darwinAllowLocalNetworking = true; 34 35 gradleFlags = [ "-Dfile.encoding=utf-8" ]; 36 37 # defaults to "assemble" 38 gradleBuildTask = "shadowJar"; 39 40 # will run the gradleCheckTask (defaults to "test") 41 doCheck = true; 42 43 installPhase = '' 44 mkdir -p $out/{bin,share/pdftk} 45 cp build/libs/pdftk-all.jar $out/share/pdftk 46 47 makeWrapper ${jre}/bin/java $out/bin/pdftk \ 48 --add-flags "-jar $out/share/pdftk/pdftk-all.jar" 49 50 cp ${finalAttrs.src}/pdftk.1 $out/share/man/man1 51 ''; 52 53 meta.sourceProvenance = with lib.sourceTypes; [ 54 fromSource 55 binaryBytecode # mitm cache 56 ]; 57}) 58``` 59 60To update (or initialize) dependencies, run the update script via 61something like `$(nix-build -A <pname>.mitmCache.updateScript)` 62(`nix-build` builds the `updateScript`, `$(...)` runs the script at the 63path printed by `nix-build`). 64 65If your package can't be evaluated using a simple `pkgs.<pname>` 66expression (for example, if your package isn't located in nixpkgs, or if 67you want to override some of its attributes), you will usually have to 68pass `pkg` instead of `pname` to `gradle.fetchDeps`. There are two ways 69of doing it. 70 71The first is to add the derivation arguments required for getting the 72package. Using the pdftk example above: 73 74```nix 75{ lib 76, stdenv 77# ... 78, pdftk 79}: 80 81stdenv.mkDerivation (finalAttrs: { 82 # ... 83 mitmCache = gradle.fetchDeps { 84 pkg = pdftk; 85 data = ./deps.json; 86 }; 87}) 88``` 89 90This allows you to `override` any arguments of the `pkg` used for 91the update script (for example, `pkg = pdftk.override { enableSomeFlag = 92true };`), so this is the preferred way. 93 94The second is to create a `let` binding for the package, like this: 95 96```nix 97let self = stdenv.mkDerivation { 98 # ... 99 mitmCache = gradle.fetchDeps { 100 pkg = self; 101 data = ./deps.json; 102 }; 103}; in self 104``` 105 106This is useful if you can't easily pass the derivation as its own 107argument, or if your `mkDerivation` call is responsible for building 108multiple packages. 109 110In the former case, the update script will stay the same even if the 111derivation is called with different arguments. In the latter case, the 112update script will change depending on the derivation arguments. It's up 113to you to decide which one would work best for your derivation. 114 115## Update Script {#gradle-update-script} 116 117The update script does the following: 118 119- Build the derivation's source via `pkgs.srcOnly` 120- Enter a `nix-shell` for the derivation in a `bwrap` sandbox (the 121 sandbox is only used on Linux) 122- Set the `IN_GRADLE_UPDATE_DEPS` environment variable to `1` 123- Run the derivation's `unpackPhase`, `patchPhase`, `configurePhase` 124- Run the derivation's `gradleUpdateScript` (the Gradle setup hook sets 125 a default value for it, which runs `preBuild`, `preGradleUpdate` 126 hooks, fetches the dependencies using `gradleUpdateTask`, and finally 127 runs the `postGradleUpdate` hook) 128- Finally, store all of the fetched files' hashes in the lockfile. They 129 may be `.jar`/`.pom` files from Maven repositories, or they may be 130 files otherwise used for building the package. 131 132`fetchDeps` takes the following arguments: 133 134- `attrPath` - the path to the package in nixpkgs (for example, 135 `"javaPackages.openjfx22"`). Used for update script metadata. 136- `pname` - an alias for `attrPath` for convenience. This is what you 137 will generally use instead of `pkg` or `attrPath`. 138- `pkg` - the package to be used for fetching the dependencies. Defaults 139 to `getAttrFromPath (splitString "." attrPath) pkgs`. 140- `bwrapFlags` - allows you to override bwrap flags (only relevant for 141 downstream, non-nixpkgs projects) 142- `data` - path to the dependencies lockfile (can be relative to the 143 package, can be absolute). In nixpkgs, it's discouraged to have the 144 lockfiles be named anything other `deps.json`, consider creating 145 subdirectories if your package requires multiple `deps.json` files. 146 147## Environment {#gradle-environment} 148 149The Gradle setup hook accepts the following environment variables: 150 151- `mitmCache` - the MITM proxy cache imported using `gradle.fetchDeps` 152- `gradleFlags` - command-line flags to be used for every Gradle 153 invocation (this simply registers a function that uses the necessary 154 flags). 155 - You can't use `gradleFlags` for flags that contain spaces, in that 156 case you must add `gradleFlagsArray+=("-flag with spaces")` to the 157 derivation's bash code instead. 158 - If you want to build the package using a specific Java version, you 159 can pass `"-Dorg.gradle.java.home=${jdk}"` as one of the flags. 160- `gradleBuildTask` - the Gradle task (or tasks) to be used for building 161 the package. Defaults to `assemble`. 162- `gradleCheckTask` - the Gradle task (or tasks) to be used for checking 163 the package if `doCheck` is set to `true`. Defaults to `test`. 164- `gradleUpdateTask` - the Gradle task (or tasks) to be used for 165 fetching all of the package's dependencies in 166 `mitmCache.updateScript`. Defaults to `nixDownloadDeps`. 167- `gradleUpdateScript` - the code to run for fetching all of the 168 package's dependencies in `mitmCache.updateScript`. Defaults to 169 running the `preBuild` and `preGradleUpdate` hooks, running the 170 `gradleUpdateTask`, and finally running the `postGradleUpdate` hook. 171- `gradleInitScript` - path to the `--init-script` to pass to Gradle. By 172 default, a simple init script that enables reproducible archive 173 creation is used. 174 - Note that reproducible archives might break some builds. One example 175 of an error caused by it is `Could not create task ':jar'. Replacing 176 an existing task that may have already been used by other plugins is 177 not supported`. If you get such an error, the easiest "fix" is 178 disabling reproducible archives altogether by setting 179 `gradleInitScript` to something like `writeText 180 "empty-init-script.gradle" ""` 181- `enableParallelBuilding` / `enableParallelChecking` / 182 `enableParallelUpdating` - pass `--parallel` to Gradle in the 183 build/check phase or in the update script. Defaults to true. If the 184 build fails for mysterious reasons, consider setting this to false. 185- `dontUseGradleConfigure` / `dontUseGradleBuild` / `dontUseGradleCheck` 186 \- force disable the Gradle setup hook for certain phases. 187 - Note that if you disable the configure hook, you may face issues 188 such as `Failed to load native library 'libnative-platform.so'`, 189 because the configure hook is responsible for initializing Gradle.