External Include Paths Point into Unstable Execroot Instead of Stable External Directory
See original GitHub issueHello wonderful Bazel folks,
TL;DR / summary: C++ header finding–and probably more–breaks for external libraries when you run a build command that uses a different set of external libraries. This issue can be fixed by having paths go through <outputBase>/external/
, rather than the current <outputBase>/execroot/__main__/external/
.
Discovery context: I’d noticed this after initially making the same mistake when writing a VSCode<>Clangd<>Bazel integration. I think this has the same root cause as https://github.com/bazelbuild/intellij/issues/1256--a deeper fix here might allow removal of the code that patched it in https://github.com/bazelbuild/intellij/commit/81afc2cd1212828f33531d2705ce61172cfd237e. A similar problem has also caused issues in Tulsi.
What’s going wrong in more detail: When the plugin gets paths to external libraries from Bazel, they usually point into the execution root’s external folder, the temporary sandbox of symlinks reconfigured for each build. This leads leads the plugin to point the IDE into the temporary sandbox for external header search paths (and other things, I’d assume).
That’s a trap. When you run a build that doesn’t use the same set of external workspaces (like for example, a build for one of several targets in the project), external paths start breaking–and the red squiggles come out to indicate their displeasure. The temporary build sandbox, the execution root (“execroot”) has gotten torn down and reconfigured, so some paths no longer exist. You can work around this by re-syncing, but it’s annoying to have building break editing–feels like clearly undesirable behavior.
You can see that this problem is happening by opening, say, an NDK file in ASwB and looking at the header include paths. You can see the header include paths for a given file in Android Studio by “Show Compiler Info” (via Help→Find Action, aka CMD+SHIFT+A). You’ll see paths containing /private/var/tmp/_bazel_<username>/<hash>/execroot/__main__/external
, and verify that the symlinks those paths go through broken if you build some other part will get broken if a build that doesn’t use the external workspace in question.
The fix: Those files live more durably inside /private/var/tmp/_bazel_<username>/<hash>/external
, so the execroot-based paths should be rewritten to point there, just as we’d do for paths in the execroot that point into the normal workspace. That way you aren’t relying on the symlinks in execroot that often get deleted out from under you!
Thanks for the work you do! Chris (ex-Googler)
P.S. This is parallel to a lingering Bug in Tulsi: https://github.com/bazelbuild/tulsi/issues/164 [Now resolved.] P.P.S. If someone’s taking a serious look at this, it’d be good to check that there isn’t a parallel problem with generated files.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:7 (2 by maintainers)
Wow! Hi @sgowroji. Sure. I thought there was no chance I’d ever hear back from you on this.
Here’s the PR https://github.com/bazelbuild/intellij/pull/4063 I just cherrypicked the above commits and then took a shot at fixing the tests. Hopefully that works. Took me a bit to load this back into my head, since it’s been a good while.
As evidence that I’m not full of it: Since filing, I fixed this over at tulsi, too, and got that merged (see linked issue above). Plus, I built hedronvision/bazel-compile-commands-extractor, which provides this functionality for vscode.
Friendly bump! Checking in since you’d asked for a PR for review and it’s been a month. Thanks for all you do.
[Btw, I also happened to be browsing the gazelle source, and noted that they also handle external correctly, under output_base, as per the PR.