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

Be less aggressive in interpreting flags as response files #13044

Closed
wants to merge 1 commit into from

Conversation

cocreature
Copy link

Both -Xlinker and -install_name will often receive flags starting with
@, specifically @loader_path or @rpath. Bazel 4.0 started
interpreting those as response files which broke our build.

This PR addresses this by hardcoding those flags. This is a pretty
ugly solution so I’m very open to better ideas. That said, there is
some precedence for doing that in
rules-haskell.

Both -Xlinker and -install_name will often receive flags starting with
`@`, specifically `@loader_path` or `@rpath`. Bazel 4.0 started
interpreting those as response files which broke our build.

This PR addresses this by hardcoding those flags. This is a pretty
ugly solution so I’m very open to better ideas. That said, there is
some precedence for doing that in
[rules-haskell](https://github.com/tweag/rules_haskell/blob/e8623a8c5ea502fbe6286d8ae5fb58f4915e92c5/haskell/private/cc_wrapper.py.tpl#L448).
@google-cla google-cla bot added the cla: yes label Feb 15, 2021
@keith
Copy link
Member

keith commented Feb 15, 2021

The thought at the time we made this decision was that this form of linker flag should be replaced with -Wl,-install_name,@foo

@cocreature
Copy link
Author

Those flags are not under our control. In this case, it is the Haskell compiler GHC that is passing them https://gitlab.haskell.org/ghc/ghc/-/blob/ab1b49108e2665eb9ccdccffde0099d1785315ee/compiler/main/SysTools.hs#L376 I do agree that in an ideal world, changing the flags would be preferable but I think this is a good example that this isn’t really feasible for users in a lot of cases.

@cocreature
Copy link
Author

I guess one option would be for rules_haskell’s cc wrapper to do the rewriting but I’m not sure that’s better than handling it in Bazel itself.

@keith
Copy link
Member

keith commented Feb 16, 2021

Ah interesting. I do think it would be safe to make that compiler change, but that wouldn't solve this in the short term. At least 1 problem with this change is that there are a few other places that also duplicate this logic, see the original change and conversation for details #12265

@aiuto aiuto added the team-Rules-CPP Issues for C++ rules label Feb 19, 2021
@aherrmann
Copy link
Contributor

@keith GHC's reasoning for preferring -Xlinker over -Wl,... is documented here:

Note [-Xlinker -rpath vs -Wl,-rpath]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-Wl takes a comma-separated list of options which in the case of
-Wl,-rpath -Wl,some,path,with,commas parses the path with commas
as separate options.
Buck, the build system, produces paths with commas in them.

-Xlinker doesn't have this disadvantage and as far as I can tell
it is supported by both gcc and clang. Anecdotally nvcc supports
-Xlinker, but not -Wl.

@keith
Copy link
Member

keith commented Feb 19, 2021

ugh!! thanks for the link. I've never heard that buck could produce commas in paths, any idea where I can see more details on that? FWIW I think a change like this would be accepted as long as it covered all the cases (although I'm not a googler so I can't make that call overall), it's just we didn't have a compelling reason to do the extra work in the previous case, so we didn't want to enumerate a list of all possible flags that could have a @ after them

@aherrmann
Copy link
Contributor

@keith I'm not familiar with Buck myself. What I understand, Buck can append comma separated flavors to targets and file names, e.g. sometarget#default,static, see also this GHC related issue on Buck's issue tracker here.

FWIW I think a change like this would be accepted as long as it covered all the cases (although I'm not a googler so I can't make that call overall)

The ones I'm aware of are -install_name, e.g. -install_name @rpath/..., and -rpath, e.g. -rpath @loader_path/....

@keith
Copy link
Member

keith commented Feb 22, 2021

I actually meant which scripts not which args. There are 3 scripts which have similar logic for this unfortunately. But it depends on what rules_haskell calls through how much of an issue that will be. I believe I solved this for wrapped_clang already with this logic

// Ignore non-file args such as '@loader_path/...'
if (!original_file.good()) {
return false;
}

You should be able to implement something similar in tools/cpp/osx_cc_wrapper.sh.tpl and tools/cpp/osx_cc_wrapper.sh (both are used in different places unfortunately)

Instead of specifying the flags that can have arguments starting with @ I think you can do something like what's being done in the C++ with:

diff --git i/tools/cpp/osx_cc_wrapper.sh w/tools/cpp/osx_cc_wrapper.sh
index 8c9c111a75..23604c7c7e 100755
--- i/tools/cpp/osx_cc_wrapper.sh
+++ w/tools/cpp/osx_cc_wrapper.sh
@@ -53,7 +53,7 @@ function parse_option() {
 
 # let parse the option list
 for i in "$@"; do
-    if [[ "$i" = @* ]]; then
+    if [[ "$i" = @* && -r "$i" ]]; then
         while IFS= read -r opt
         do
             parse_option "$opt"

@aherrmann
Copy link
Contributor

I actually meant which scripts not which args.

Oh, I see, sorry, misread.

But it depends on what rules_haskell calls through how much of an issue that will be.

Just for completeness, rules_haskell doesn't call any of these scripts explicitly. It calls the C compiler provided by Bazel's cc toolchain. I.e.

cc_common.get_tool_for_action(
        feature_configuration = feature_configuration,
        action_name = ACTION_NAMES.c_compile,
)

That may be one of Bazel's cc-wrappers. So far @bazel_tools//tools/cpp:osx_cc_wrapper.sh.tpl was the only script that triggered this issue. But, it makes sense to try and cover all instances.

Instead of specifying the flags that can have arguments starting with @ I think you can do something like what's being done in the C++ with [...]

Looks good to me.

@aherrmann
Copy link
Contributor

@keith @cocreature I've opened #13148 to replace this PR with @keith's suggestions from above applied.

@cocreature cocreature closed this Mar 3, 2021
bazel-io pushed a commit that referenced this pull request Mar 21, 2022
Closes #13044
Applies the changes suggested in #13044 (comment)

Not all arguments starting with `@` represent response files, e.g. `-install_name @rpath/...` or `-Xlinker -rpath -Xlinker @loader_path/...` do not refer to response files and attempting to read them as such will fail the build.

Users don't always have control over these arguments, meaning transforming them to `-Wl,-install_name,@rpath/...` or `-Wl,-rpath,@loader_path/...` is not always an option. E.g. as described in #13044 (comment) where these flags are emitted by the Haskell compiler GHC (see #13044 (comment) for their reasoning).

With this change `osx_cc_wrapper` will only interpret arguments starting with `@` as response files if the corresponding file exists and is readable. This is analogous to the behavior defined in `wrapped_clang.cc`. See #13044 (comment) for discussion.

Closes #13148.

PiperOrigin-RevId: 436207868
@brentleyjones
Copy link
Contributor

@bazel-io fork 5.1

brentleyjones pushed a commit to brentleyjones/bazel that referenced this pull request Mar 21, 2022
Closes bazelbuild#13044
Applies the changes suggested in bazelbuild#13044 (comment)

Not all arguments starting with `@` represent response files, e.g. `-install_name @rpath/...` or `-Xlinker -rpath -Xlinker @loader_path/...` do not refer to response files and attempting to read them as such will fail the build.

Users don't always have control over these arguments, meaning transforming them to `-Wl,-install_name,@rpath/...` or `-Wl,-rpath,@loader_path/...` is not always an option. E.g. as described in bazelbuild#13044 (comment) where these flags are emitted by the Haskell compiler GHC (see bazelbuild#13044 (comment) for their reasoning).

With this change `osx_cc_wrapper` will only interpret arguments starting with `@` as response files if the corresponding file exists and is readable. This is analogous to the behavior defined in `wrapped_clang.cc`. See bazelbuild#13044 (comment) for discussion.

Closes bazelbuild#13148.

PiperOrigin-RevId: 436207868
(cherry picked from commit efb2b80)
Wyverald pushed a commit that referenced this pull request Mar 21, 2022
Closes #13044
Applies the changes suggested in #13044 (comment)

Not all arguments starting with `@` represent response files, e.g. `-install_name @rpath/...` or `-Xlinker -rpath -Xlinker @loader_path/...` do not refer to response files and attempting to read them as such will fail the build.

Users don't always have control over these arguments, meaning transforming them to `-Wl,-install_name,@rpath/...` or `-Wl,-rpath,@loader_path/...` is not always an option. E.g. as described in #13044 (comment) where these flags are emitted by the Haskell compiler GHC (see #13044 (comment) for their reasoning).

With this change `osx_cc_wrapper` will only interpret arguments starting with `@` as response files if the corresponding file exists and is readable. This is analogous to the behavior defined in `wrapped_clang.cc`. See #13044 (comment) for discussion.

Closes #13148.

PiperOrigin-RevId: 436207868
(cherry picked from commit efb2b80)

Co-authored-by: Andreas Herrmann <andreash87@gmx.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes team-Rules-CPP Issues for C++ rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants