diff --git a/pkgs/build-support/build-bazel-package/default.nix b/pkgs/build-support/build-bazel-package/default.nix index 349a7e5aa333..07d37451ddf9 100644 --- a/pkgs/build-support/build-bazel-package/default.nix +++ b/pkgs/build-support/build-bazel-package/default.nix @@ -1,4 +1,4 @@ -{ stdenv, bazel }: +{ stdenv, bazel, enableNixHacks ? true }: args@{ name, bazelFlags ? [], bazelTarget, buildAttrs, fetchAttrs, ... }: @@ -17,14 +17,15 @@ in stdenv.mkDerivation (fBuildAttrs // { nativeBuildInputs = fFetchAttrs.nativeBuildInputs or [] ++ [ bazel ]; preHook = fFetchAttrs.preHook or "" + '' - export bazelOut="$NIX_BUILD_TOP/output" + export bazelOut="$(echo ''${NIX_BUILD_TOP}/output | sed -e 's,//,/,g')" + export bazelUserRoot="$(echo ''${NIX_BUILD_TOP}/tmp | sed -e 's,//,/,g')" export HOME="$NIX_BUILD_TOP" ''; buildPhase = fFetchAttrs.buildPhase or '' runHook preBuild - bazel --output_base="$bazelOut" fetch $bazelFlags $bazelTarget + bazel --output_base="$bazelOut" --output_user_root="$bazelUserRoot" fetch $bazelFlags $bazelTarget runHook postBuild ''; @@ -52,10 +53,11 @@ in stdenv.mkDerivation (fBuildAttrs // { outputHash = fetchAttrs.sha256; }); - nativeBuildInputs = fBuildAttrs.nativeBuildInputs or [] ++ [ (bazel.override { enableNixHacks = true; }) ]; + nativeBuildInputs = fBuildAttrs.nativeBuildInputs or [] ++ [ (if enableNixHacks then (bazel.override { enableNixHacks = true; }) else bazel) ]; preHook = fBuildAttrs.preHook or "" + '' export bazelOut="$NIX_BUILD_TOP/output" + export bazelUserRoot="$NIX_BUILD_TOP/tmp" export HOME="$NIX_BUILD_TOP" ''; @@ -71,7 +73,7 @@ in stdenv.mkDerivation (fBuildAttrs // { buildPhase = fBuildAttrs.buildPhase or '' runHook preBuild - bazel --output_base="$bazelOut" build -j $NIX_BUILD_CORES $bazelFlags $bazelTarget + bazel --output_base="$bazelOut" --output_user_root="$bazelUserRoot" build -j $NIX_BUILD_CORES $bazelFlags $bazelTarget runHook postBuild ''; diff --git a/pkgs/development/tools/build-managers/bazel/bazel-deps/default.nix b/pkgs/development/tools/build-managers/bazel/bazel-deps/default.nix new file mode 100644 index 000000000000..76e2ad1e7cac --- /dev/null +++ b/pkgs/development/tools/build-managers/bazel/bazel-deps/default.nix @@ -0,0 +1,80 @@ +{ stdenv, buildBazelPackage, lib, fetchFromGitHub, git, jre, makeWrapper }: + +buildBazelPackage rec { + name = "bazel-deps-${version}"; + version = "2018-05-31"; + + meta = with stdenv.lib; { + homepage = "https://github.com/johnynek/bazel-deps"; + description = "Generate bazel dependencies for maven artifacts"; + license = licenses.mit; + maintainers = [ maintainers.uri-canva ]; + platforms = platforms.all; + }; + + src = fetchFromGitHub { + owner = "johnynek"; + repo = "bazel-deps"; + rev = "dd7d0086d3a61c1d5c3370a0300824d0c75946e4"; + sha256 = "1h9ddgk6vn0bhnnkwwz4n1iqv2rcdj521dxhdwj5wwpndbciw855"; + }; + + bazelTarget = "//src/scala/com/github/johnynek/bazel_deps:parseproject_deploy.jar"; + + buildInputs = [ git makeWrapper ]; + + fetchAttrs = { + preInstall = '' + # Remove all built in external workspaces, Bazel will recreate them when building + rm -rf $bazelOut/external/{bazel_tools,\@bazel_tools.marker,local_*,\@local_*} + # For each external workspace, remove all files that aren't referenced by Bazel + # Many of these files are non-hermetic (for example .git/refs/remotes/origin/HEAD) + files_to_delete=() + for workspace in $(find $bazelOut/external -maxdepth 2 -name "WORKSPACE" -print0 | xargs -0L1 dirname); do + workspaceOut="$NIX_BUILD_TOP/workspaces/$(basename workspace)/output" + workspaceUserRoot="$NIX_BUILD_TOP/workspaces/$(basename workspace)/tmp" + rm -rf $workspace/.git + if ! targets_and_files=$(cd "$workspace" && bazel --output_base="$workspaceOut" --output_user_root="$workspaceUserRoot" query '//...:*' 2> /dev/null | sort -u); then + continue + fi + if ! targets=$(cd "$workspace" && bazel --output_base="$workspaceOut" --output_user_root="$workspaceUserRoot" query '//...:all' 2> /dev/null | sort -u); then + continue + fi + mapfile -t referenced_files < <(comm -23 <(printf '%s' "$targets_and_files") <(printf '%s' "$targets") | sed -e 's,^//:,,g' | sed -e 's,^//,,g' | sed -e 's,:,/,g') + referenced_files+=( "WORKSPACE" ) + for referenced_file in "''${referenced_files[@]}"; do + # Some of the referenced files are symlinks to non-referenced files. + # The symlink targets have deterministic contents, but non-deterministic + # paths. Copy them to the referenced path, which is deterministic. + if target=$(readlink "$workspace/$referenced_file"); then + rm "$workspace/$referenced_file" + cp -a "$target" "$workspace/$referenced_file" + fi + done + mapfile -t workspace_files_to_delete < <(find "$workspace" -type f -or -type l | sort -u | comm -23 - <(printf "$workspace/%s\n" "''${referenced_files[@]}" | sort -u)) + for workspace_file_to_delete in "''${workspace_files_to_delete[@]}"; do + files_to_delete+=("$workspace_file_to_delete") + done + # We're running bazel in many different workspaces in a loop. Letting the + # daemon shut down on its own would leave several daemons alive at the + # same time, using up a lot of memory. Shut them down explicitly instead. + bazel --output_base="$workspaceOut" --output_user_root="$workspaceUserRoot" shutdown 2> /dev/null + done + for file_to_delete in "''${files_to_delete[@]}"; do + rm "$file_to_delete" + done + find . -type d -empty -delete + ''; + + sha256 = "0fh9jjwk3aq0kklhl9zyy8hj8gjm1y1fy4ygjinm0469w9jdgc3g"; + }; + + buildAttrs = { + installPhase = '' + mkdir -p $out/bin/bazel-bin/src/scala/com/github/johnynek/bazel_deps + cp gen_maven_deps.sh $out/bin + wrapProgram "$out/bin/gen_maven_deps.sh" --set JAVA_HOME "${jre}" --prefix PATH : ${lib.makeBinPath [ jre ]} + cp bazel-bin/src/scala/com/github/johnynek/bazel_deps/parseproject_deploy.jar $out/bin/bazel-bin/src/scala/com/github/johnynek/bazel_deps + ''; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index e31a55782f15..d49fadac6f18 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7794,6 +7794,10 @@ with pkgs; buildozer = bazel-buildtools; unused_deps = bazel-buildtools; + bazel-deps = callPackage ../development/tools/build-managers/bazel/bazel-deps { + buildBazelPackage = buildBazelPackage.override { enableNixHacks = false; }; + }; + buildBazelPackage = callPackage ../build-support/build-bazel-package { }; bear = callPackage ../development/tools/build-managers/bear { };