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

CROSSTOOLS wrapped_clang: handle spaces in paths #5147

Closed
wants to merge 1 commit into from

Conversation

ob
Copy link
Contributor

@ob ob commented May 2, 2018

When bazel calls wrapped_clang, it single-quotes all arguments. However
it passes flags with arguments quoted as a whole. That is, wrapped_clang
will be called with arguments like these:

wrapped_clang '-isysroot /a/path/with spaces' '/a/file with spaces.m'

Before this commit, wrapped_clang was blindly splitting on space and
calling clang with invalid arguments. Now it only splits on the first
space, and only if the argument starts with '-'.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

@ob
Copy link
Contributor Author

ob commented May 3, 2018

I signed in!

@googlebot
Copy link

CLAs look good, thanks!

@googlebot googlebot added cla: yes and removed cla: no labels May 3, 2018
// Splits txt using whitespace delimiter, pushing each substring into strs.
// Splits txt on the first whitespace delimiter, pushing both substring into strs.
// This is because the wrapped_clang binary is called with arguments like:
// wrapped_clang '-isysroot a/path/that might have/spaces' and we need to
Copy link
Contributor

Choose a reason for hiding this comment

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

what if it's passed as -isysroota/path/that might have/spaces? or with the = syntax?

Copy link
Contributor Author

@ob ob May 3, 2018

Choose a reason for hiding this comment

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

Good point. I'm assuming this is called by Bazel right? I grepped for isysroot and it seems Bazel does use a single space:

tools/osx/crosstool/CROSSTOOL.tpl:        flag: "-isysroot %{sdk_dir}"

for example. Is it the intent to have it be general purpose and support all the different syntaxes? Note that this might be really hard, for instance in the -isysroota/path case, how do you know where the flag ends and the path starts without knowing all of clang's flags?

Also note the previous version would fail in similar or worse ways with either of these other syntaxes.

@ob
Copy link
Contributor Author

ob commented May 7, 2018

Thinking a bit more about this change I'm wondering if it wouldn't be better to change Bazel to not combine multiple arguments into one. Is there a reason it does: wrapped_tool '-isysroot path instead of wrapped_tool '-isysroot' 'path'? That way the wrapped tools wouldn't have to parse arguments which is fragile...

@ob
Copy link
Contributor Author

ob commented May 18, 2018

As an update, I have found a case where this change breaks. When trying to build a sample app, I found Bazel calling the wrapped_clang tool with the following argument, which would need to be split into multiple arguments.

'-Xlinker -add_ast_path -Xlinker bazel-out/ios-x86_64-min9.0-applebin_ios-ios_x86_64-fastbuild/genfiles/sample_appBinary/_objs/sample_appBinary.swiftmodule'

I think what I said in my previous comment is the right way forward.

@ulfjack
Copy link
Contributor

ulfjack commented May 28, 2018

+1

@ob
Copy link
Contributor Author

ob commented May 29, 2018

Okay, I played a little with this but I'm stuck. The way the flags end up with spaces in them is because in tools/osx/crosstool/CROSSTOOL.tpl they are specified as:

       flag_group {
         flag: "-isysroot %{sdk_dir}"
       }

I've verified that if I remove that space and make the flag two entries, like so:

       flag_group {
         flag: "-isysroot"
         flag: "%{sdk_dir}"
       }

The problem is solved. However that file says at the beginning:

# This file was auto-generated by a script maintained internally by
# Google.

Which makes me think that changing it directly is a bad idea. Also, there are other instances of spaces in the flags, but there is some kind of iteration going on, e.g.

      flag_group {
        flag: "-weak_framework %{weak_framework_names}"
        iterate_over: "weak_framework_names"
      }

I am not familiar with the language specification for this file so I don't know how that could be turned into multiple flag entries that are paired with their arguments.

@ob
Copy link
Contributor Author

ob commented May 30, 2018

Those last commits kind of work for me but I'm not sure whether that iterate_over iterates over the flag_group or single flags... or whether this needs to be changed in some internal Google script.

@sergiocampama sergiocampama removed their assignment May 31, 2018
@ulfjack
Copy link
Contributor

ulfjack commented Jun 4, 2018

tools/osx/crosstool/CROSSTOOL.tpl changes require a change in an internal Google script, correct. Is the patch in this CL the resulting file we need to get?

@ulfjack
Copy link
Contributor

ulfjack commented Jun 4, 2018

I have a change to update the script that I'm about to send out. It should get referenced here once it's merged.

@ob
Copy link
Contributor Author

ob commented Jun 4, 2018

Yeah, the changes to CROSSTOOL.tpl are what I'm testing with. Modulo my previous comments about my lack of knowledge of tpl format and whether it expands flag_groups as I think it expands them, then yeah.

Note that I also removed the parsing from the clang wrapper.

Thank you for taking a look at this.

bazel-io pushed a commit that referenced this pull request Jun 5, 2018
@ulfjack
Copy link
Contributor

ulfjack commented Jun 5, 2018

My change was merged. Please rebase and let me know whether you can get it to work now.

@ob
Copy link
Contributor Author

ob commented Jun 5, 2018

@ulfjack I tested this with my workspace and the test case that I had added before. Note that I removed splitting on spaces that wrapped_clang used to do.

@ulfjack
Copy link
Contributor

ulfjack commented Jun 6, 2018

Generally looks good. I triggered the CI.

@ob
Copy link
Contributor Author

ob commented Jun 6, 2018

I should probably fix the comments before you merge and reference the commit you did that fixes the caller side...

Before commit 53700e2 Bazel was quoting some calls to wrapped_clang
like so:

  '-isysroot /some/path maybe with spaces'

and wrapped_clang was parsing to split on spaces (assuming the paths themselves
didn't have spaces). After 53700e2 the arguments to wrapped_clang don't
need to be parsed so this commit removes the parsing.

Also add a test for spaces in pathnames.
@ob
Copy link
Contributor Author

ob commented Jun 6, 2018

Ok, pushed a NFC with better comments... sorry I didn't do the comments right the first time. I thought the CI was triggered automatically.

@ulfjack
Copy link
Contributor

ulfjack commented Jun 7, 2018

@ob, you can't trigger CI yourself. Security told us we're required to do a code review first.

@ob
Copy link
Contributor Author

ob commented Jun 12, 2018

@ulfjack that makes sense... in a way triggering a CI on unreviewed code changes can be seen as a remote execution attack ;-)

Could you please trigger a CI run again?

@ulfjack
Copy link
Contributor

ulfjack commented Jun 12, 2018

Triggered.

@ob
Copy link
Contributor Author

ob commented Jun 12, 2018

Hmm... the test failure seems unrelated to my changes... FWIW, //src/test/java/com/google/devtools/build/lib:remote-tests passes on my machine.

@ulfjack
Copy link
Contributor

ulfjack commented Jun 12, 2018

Yeah, the test is flaky - I just disabled it earlier today. I'm going to merge this PR now.

@bazel-io bazel-io closed this in 56d98ae Jun 12, 2018
ArielleA pushed a commit to ArielleA/bazel that referenced this pull request Jun 19, 2018
When bazel calls wrapped_clang, it single-quotes all arguments. However
it passes flags with arguments quoted as a whole. That is, wrapped_clang
will be called with arguments like these:

  wrapped_clang '-isysroot /a/path/with spaces' '/a/file with spaces.m'

Before this commit, wrapped_clang was blindly splitting on space and
calling clang with invalid arguments. Now it only splits on the _first_
space, and only if the argument starts with '-'.

Closes bazelbuild#5147.

PiperOrigin-RevId: 200259496
werkt pushed a commit to werkt/bazel that referenced this pull request Aug 2, 2018
When bazel calls wrapped_clang, it single-quotes all arguments. However
it passes flags with arguments quoted as a whole. That is, wrapped_clang
will be called with arguments like these:

  wrapped_clang '-isysroot /a/path/with spaces' '/a/file with spaces.m'

Before this commit, wrapped_clang was blindly splitting on space and
calling clang with invalid arguments. Now it only splits on the _first_
space, and only if the argument starts with '-'.

Closes bazelbuild#5147.

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

Successfully merging this pull request may close these issues.

4 participants