-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
PATH
not propagated to many darwin actions
#12049
Comments
Because of this issue bazelbuild#12049 this call to python doesn't respect the PATH users invoke bazel with. Because the default shell path contains /usr/local/bin, this `python` could end up being from homebrew. Homebrew's python installations are easily borked which leads to hashlib being unusable: https://discuss.bitrise.io/t/broken-python-2-7-hashlib-in-new-xcode-10-3-x-mojave-stack/11401/7 This changes this use case to a path that always exists (at least for now) on macOS, and only falls back to the bare executable if it doesn't. Ideally this would utilize the python version from the toolchain instead.
Because of this issue bazelbuild#12049 this call to python doesn't respect the PATH users invoke bazel with. Because the default shell path contains /usr/local/bin, this `python` could end up being from homebrew. Homebrew's python installations are easily borked which leads to hashlib being unusable: https://discuss.bitrise.io/t/broken-python-2-7-hashlib-in-new-xcode-10-3-x-mojave-stack/11401/7 This changes this use case to a path that always exists (at least for now) on macOS, and only falls back to the bare executable if it doesn't. Ideally this would utilize the python version from the toolchain instead.
Because of this issue bazelbuild#12049 this call to python doesn't respect the PATH users invoke bazel with. Because the default shell path contains /usr/local/bin, this `python` could end up being from homebrew. Homebrew's python installations are easily borked which leads to hashlib being unusable: https://discuss.bitrise.io/t/broken-python-2-7-hashlib-in-new-xcode-10-3-x-mojave-stack/11401/7 This changes this use case to a path that always exists (at least for now) on macOS, and only falls back to the bare executable if it doesn't. Ideally this would utilize the python version from the toolchain instead.
@gregestren is this something you'd be able to advise on? |
Actually, this may be an Apple Rules issue, not an --action_env issue. @googlewalt , is this in your wheelhouse? |
I think there are two issues:
In both cases, the issue seems to be that |
Sorry. I found the setup code in |
Have you tried |
I have tried that flag, AFAICT that flag is only read here: bazel/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java Lines 187 to 201 in 84834db
and IIRC this codepath isn't even hit, otherwise action_env would work as well: bazel/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java Lines 202 to 207 in 84834db
|
[edit: this is wrong, see below] I verified that this behavior is not specific to apple rules, and it has been this way since at least bazel 1.0. I would have expected the SHELL_ACTION_ENV to be applied to all the rules that run a shell, but I'm not familiar with exactly how that logic works. The most recent non-trivial refactoring of this code was done in commit 8626623. Perhaps someone more familiar with this code can comment? |
cc @lberki (author of that commit) |
I'm certainly not that "someone familiar with this code" :( The commit 8626623 was meant to be a refactoring without user-visible effects; do you have a reason to believe that this is what caused the behavior change? Looking at https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java#L205 , it looks like the variables set in |
Apologies for the red herring. My statements from previous post was wrong (user error).
But some other Apple actions don't appear to be have default PATHs, or be hooked up to those flags: StoreboardCompile, AssetCatalogCompile, CompileRootInfoPlist, Processing and signing. |
No worries! Unfortunately, I won't be able to help further then :( |
No actions in rules_apple seems to employ |
Are you suggesting all actions should set that? Is that the right switch for this? It surprises me a bit that that would be the way to make this work. Because that means that all non-native rules would need to set that to Somewhat related I guess: |
The documentation recommends all actions set it.
Native rules must also opt in, but some effort was historically put into fixing them (#3320).
The |
This fixes bazelbuild/bazel#12049 and apparently is the recommendation wherever possible.
It looks like this is mutually exclusive with setting |
Example of the failures caused by this in the Apple toolchain bazelbuild/rules_swift#497
|
Yeah, it sounds like it might make sense to go back to your first suggestion, to set a conservative default PATH for Apple-related actions. We do need the environment that's set for Apple rules, but it's ok to add to it. |
Using Action I'm surprised by some here looking briefly at the code: bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java Lines 726 to 740 in ecab72e
|
So there was some confusion with the list above, the problem is that some actions don't print their env with aquery. I'll try to submit a follow up for some of those. This fixes some of my use case bazelbuild/rules_swift#502 but it's not perfect. Firstly piping bazel/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java Lines 486 to 500 in 080547f
There doesn't seem to be a way to get any of the other variables from starlark, but I might be missing something? |
The CppLinkAction is one of the ones where its environment doesn't show up in aquery because it doesn't implement SpawnAction |
Through the investigation of bazelbuild/bazel#12049 one of the things I discovered was that when using `actions.run` there are 2 options for environment variables. `use_default_shell_env = True` is recommended, but cannot be used if you want to also pass `env` to the actions. To support Xcode version selection we have to pass `env` with those variables. Without the default shell env, we only get the environment variables defined in the crosstool, but not those passed with `--action_env`. This now adds variables passed as `--action_env=FOO=BAR`, but not those passed as `--action_env=FOO` (where the value is supposed to pass through). This is useful to ensure a few things: 1. The default PATH things are executed with includes /usr/local/bin. This can result in pollution of binaries from homebrew. Previously there was no way to limit this 2. This should be a good replacement for using custom Swift toolchains. Currently those environment variables only apply to some actions (excluding those from bazel) using `--action_env=TOOLCHAINS=foo` should work better than the current solution (this change can be made as a followup)
Ran into a variant of this, switching over to an Apple Silicon machine. It's worth noting that on Apple Silicon, Homebrew no longer installs into the default PATH but rather to /opt/homebrew/bin. That said, if we do get into this and change defaults, I think it might well make sense to include Homebrew installs in the strict_action_env default. I get the hermeticity concerns, but it's also probably a good idea to default to the tools the user is more likely to expect, rather than, e.g., use the 2007 era bash, old python, and other os-bundled binaries that I think most users replace with those installed from brew. Always possible to make it more restrictive with --action_env, ofc. |
@keith, what are your thoughts these days on the desirability of having homebrew tools on the action path? |
At least with python3 macOS has been keeping relatively up to date so I'm happy to be using that version since it's the same for everyone (assuming you only maintain 1 Xcode version). For the bash thing we just deal with the old one. I think the downside we saw before we started excluding the brew path was just people's brew states could be all over the place depending on when things were last updated, so it added a lot of variance. |
Got it. Thanks, @keith. |
I also believe that since brew has thousands of formulae in their core repo alone, and most developers are probably using at least some binaries provided by brew (but can be widely-varying and selected according to personal habits), that including it by default opens the door to a ton of subtle variances. I think a lot of developers who are just "using" Bazel as their build system because it's what their projects use, can then easily run into issues that may be hard to debug. The GNU bash on macOS is old, yes, but since macOS has also shipped with an immutable zsh since 2015 there's now also opportunity for Darwin-specific wrapper scripts to use /bin/zsh if there's a desire for more modern shell scripting language features. |
So what's the conclusion here? Making copious PRs to rule sets to set |
#18235 would be the best of both worlds I think. In my case right now we can't get it to work 100% because values like |
If possible definitely set |
With the new flag, Starlark actions that specify both `env` and `use_default_shell_env` will no longer have `env` ignored. Instead, the values of `env` will override the default shell environment. This allows Starlark actions to both pick up user-configured variables such as `PATH` from the shell environment as well as set variables to fixed values required for the action, e.g., variables provided by the C++ toolchain. Rationale for having `env` override the default shell env: The rules know best which values they have to set specific environment variables to in order to successfully execute an action, so a situation where users break an action by a globally applied `--action_env` is prevented. If users really do have to be able to modify an environment variables fixed by the rule, the rule can always make this configurable via an attribute. Work towards bazelbuild#5980 Fixes bazelbuild#12049 Closes bazelbuild#18235. PiperOrigin-RevId: 559506535 Change-Id: I7ec6ae17b076bbca72fab8394f3a8b3e4f9ea9d8
With the new flag, Starlark actions that specify both `env` and `use_default_shell_env` will no longer have `env` ignored. Instead, the values of `env` will override the default shell environment. This allows Starlark actions to both pick up user-configured variables such as `PATH` from the shell environment as well as set variables to fixed values required for the action, e.g., variables provided by the C++ toolchain. Rationale for having `env` override the default shell env: The rules know best which values they have to set specific environment variables to in order to successfully execute an action, so a situation where users break an action by a globally applied `--action_env` is prevented. If users really do have to be able to modify an environment variables fixed by the rule, the rule can always make this configurable via an attribute. Work towards bazelbuild#5980 Fixes bazelbuild#12049 Closes bazelbuild#18235. PiperOrigin-RevId: 559506535 Change-Id: I7ec6ae17b076bbca72fab8394f3a8b3e4f9ea9d8
With the new flag, Starlark actions that specify both `env` and `use_default_shell_env` will no longer have `env` ignored. Instead, the values of `env` will override the default shell environment. This allows Starlark actions to both pick up user-configured variables such as `PATH` from the shell environment as well as set variables to fixed values required for the action, e.g., variables provided by the C++ toolchain. Rationale for having `env` override the default shell env: The rules know best which values they have to set specific environment variables to in order to successfully execute an action, so a situation where users break an action by a globally applied `--action_env` is prevented. If users really do have to be able to modify an environment variables fixed by the rule, the rule can always make this configurable via an attribute. Work towards #5980 Fixes #12049 Closes #18235. Commit d1fdc53 PiperOrigin-RevId: 559506535 Change-Id: I7ec6ae17b076bbca72fab8394f3a8b3e4f9ea9d8 Fixes #19312 --------- Co-authored-by: Ivo List <[email protected]> Co-authored-by: Ian (Hee) Cha <[email protected]>
A fix for this issue has been included in Bazel 6.4.0 RC1. Please test out the release candidate and report any issues as soon as possible. Thanks! |
for others note that the change is only if you enable |
This is a wider reaching version of #8425
In the linked issue I did some investigation around default PATH variables for actions that at the time I thought only affected
py_*
targets but it turns out that many other actions on darwin do not inherit anyPATH
and therefore fallback to macOS's default shell env of/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
which can allow leakage of/usr/local/*
binaries (which is specifically an issue because of homebrew).While the default PATH may be ok for some use cases, if you actually try to restrict it using
--action_env=PATH=something
or by executing bazel withenv -i PATH=something bazel ...
, neither of these are applied to these actions.For example any action that is executed in the context of Xcode is executed with these environment variables:
Some actions that don't require Xcode are executed with no environment variables:
This is not the behavior of some other rules like
genrule
where if you build this target with--action_env=/usr/bin:/bin
it hits the "Valid path":I think that either all actions should get a very conservative default PATH like
/usr/bin:/bin
, or the flags like--action_env
should be able to add env vars to these actions (I believe the latter is likely the more flexible path, but I'm not sure about the implementation implications).For native actions it seems that this can be resolved by adding:
to this logic
bazel/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
Lines 140 to 144 in 8f67892
But for starlark actions they inherit this environment:
bazel/tools/osx/crosstool/cc_toolchain_config.bzl
Lines 4546 to 4557 in 8f67892
When accessing the environment variables for an action with the
cc_common
api. There doesn't seem to be a way to craft anenv_entry
that doesn't impose a value. So I could add/usr/bin:/bin
there, but it wouldn't allow overrides via--action_env=PATH=foo
I'm happy to make a change here but I'm hoping for some guidance on the right path!
What operating system are you running Bazel on?
macOS
Bazel version?
8f67892
The text was updated successfully, but these errors were encountered: