Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hermetic nixpkgs_cc_toolchain #5976

Merged
merged 14 commits into from
May 18, 2020
Merged

Hermetic nixpkgs_cc_toolchain #5976

merged 14 commits into from
May 18, 2020

Conversation

aherrmann-da
Copy link
Contributor

So far we were using nixpkgs_cc_toolchain of rules_nixpkgs which uses Bazel's auto configured CC toolchain applied to a Nix provided compiler under the hood. This is not hermetic as the auto configure toolchain picks up header include paths defined in the environment. These may change for example within a nix-shell environment. These builtin include paths affect the cache keys of all actions that depend on the cc toolchain and cause cache misses on mismatch.

This updates rules_nixpkgs and uses the new nixpkgs_cc_toolchain_hermetic (via patch until tweag/rules_nixpkgs#128 is merged). This new toolchain is hermetic in that it configures the cc toolchain during a nix-build within Nix's sandbox.

Pull Request Checklist

  • Read and understand the contribution guidelines
  • Include appropriate tests
  • Set a descriptive title and thorough description
  • Add a reference to the issue this PR will solve, if appropriate
  • Include changelog additions in one or more commit message bodies between the CHANGELOG_BEGIN and CHANGELOG_END tags
  • Normal production system change, include purpose of change in description

NOTE: CI is not automatically run on non-members pull-requests for security
reasons. The reviewer will have to comment with /AzurePipelines run to
trigger the build.

@aherrmann-da aherrmann-da force-pushed the hermetic-cc-toolchain branch 4 times, most recently from fb972e2 to f61232f Compare May 15, 2020 15:34
@aherrmann-da aherrmann-da marked this pull request as ready for review May 15, 2020 16:19
@aherrmann-da aherrmann-da requested review from cocreature and a user May 15, 2020 16:19
Copy link
Contributor

@cocreature cocreature left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, thank you so much!

deps.bzl Show resolved Hide resolved
nix/tools/bazel-cc-toolchain/default.nix Outdated Show resolved Hide resolved
@@ -70,5 +70,5 @@ let cc-darwin =
in
buildEnv {
name = "bazel-cc-toolchain";
paths = [ customStdenv.cc ] ++ (if stdenv.isDarwin then [ ] else [ binutils ]);
paths = [ customStdenv.cc ] ++ (if stdenv.isDarwin then [ darwin.binutils ] else [ binutils ]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary now? For what?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the old toolchain just picked /usr/bin/strip and friends. To make these parts hermetic as well, we want to use nixpkgs provided tools. On MacOS one use to use darwin.binutils instead of binutils. The latter includes a bin/strip that chokes on MACH-O binaries. See https://github.com/NixOS/nixpkgs-channels/blob/10100a97c8964e82b30f180fda41ade8e6f69e41/pkgs/os-specific/darwin/binutils/default.nix#L32

+Use `nixpkgs_cc_configure_hermetic` instead.
+
+This uses Bazel's autoconfigure toolchain under the hood, which is
+inhermetic. In particular, system include directories specified in the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description says “overriding this autodetection makes builds more hermetic” while here you then (correctly) specify that it is “inhermetic”. While that’s not really contradictory it does sound a bit confusing (no need to address this here but maybe worth keeping in mind for the rules_nixpkgs PR).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the docstrings could use a second pass. It is more hermetic than the builtin autodetection in that at least it doesn't use whatever cc is in PATH but the one provided by nixpkgs. However, it is still inhermetic in that it is influenced by some environment variables.

+ Returns:
+ The string with all instances of `$(location )` replaced by paths.
+ """
+ num = string.count("$(location ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it is inconsistent with how Bazel handles this kind of stuff where you have to escape the $ if you want it to not have special meaning. Probably not a big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow. We do want $(location ) to have special meaning, just that here we define that special meaning with _expand_location. Note $(location ) expension is not automatic, a rule has to invoke ctx.expand_location explicitly. However, here we are within a repository rule, so ctx.expand_location is not available to us.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is that only $(location …) has special meaning. In other contexts in Bazel where $(location …) has special meaning, everything starting with $ has special meaning and you have to escape something like $abc whereas here you do not need the escaping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see, yes that would be more consistent. location expansion is not enabled by default, so it's not a big deal here. But, yes, this should be improved upstream.

CHANGELOG_BEGIN
CHANGELOG_END
When using --incompatible_enable_cc_toolchain_resolution instead
cc actions still depend on
`external/local_config_cc/builtin_include_directory_paths`
as well as
`external/nixpkgs_cc_toolchain_config/builtin_include_directory_paths`.
The toolchain only considers `bin/cc` and having the other symlinks
around could lead to confusion
@ghost
Copy link

ghost commented May 18, 2020

I can confirm that this PR fixes rebuilding when within a Nix shell. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants