bazel-compile-commands-extractor icon indicating copy to clipboard operation
bazel-compile-commands-extractor copied to clipboard

Relevant arguments are lost by the `bazel aquery ...` portion of compile command generation

Open btalb opened this issue 1 year ago • 6 comments

I've had a setup evolve so that it is now using a bazelrc in a custom location (i.e. bazel --bazelrc=/path/to/.bazelrc ... is now how all of my commands are run).

The bazel aquery ... portion of the compile command generation is a raw call that doesn't receive any of the arguments forwarded to it. Some simple examples:

  • build --action_env=BAZEL_CXXOPTS="-std=c++20" works when in a bazelrc in the default location, but not when in a custom location
  • --registry args also go missing

It leaves me in a situation where my project builds perfectly fine, but I can't generate commands because the logic is in a non-standard bazelrc location or passed via the bazel run ... command itself.

I've:

  • confirmed manually forcing those arguments in as a patch to refresh.template.py works, but that is to brittle to meet what I need
  • looked for something dirty like recovering the arguments from the process tree, but the process holding the args isn't still around when the Python script runs
  • tried messing around with the refresh_compile_commands function, but don't know enough about Bazel yet to know if it's even possible to access / forward these types of args

Any ideas?

btalb avatar Feb 18 '24 13:02 btalb

I've just seen the -- args workaround, which functionally does the job.

It still doesn't work for --bazelrc as it treats it as a command arg rather than startup option (i.e. before the aquery command).

I guess this is more a feature request then:

  • low-hanging fruit: support startup options via the -- arg passthrough (probably pulling the list from bazel help startup_options is the sanest path to go)
  • is there any possible way to pull the args directly from the command (manually duplicating long arg lists / bazelrcs is tedious / error prone)?

btalb avatar Feb 18 '24 20:02 btalb

Hey, thanks for raising this, Ben.

I really wish we could pull the args from Bazel, but I don't know of a way. (Won't bazel help return the options from its invocation, which wouldn't automatically include the additional options)

Some workaround-ish ideas:

  • Would it work to supply the basil RC option on both sides of the --?, that way passing it to both invocations?
  • Alternately, would it work to import the bazelrc you want to use from one in the default location, thus sparing you having to pass it all the time?

Chris

cpsauer avatar Feb 19 '24 00:02 cpsauer

Thanks @cpsauer ; I had a feeling this may be the result.

  • the passing --bazelrc both sides doesn't work because that's a startup option which means it has to come before the aquery part of the command
  • I've got a project that will potentially have lots of modules, so I want to avoid having a file that I've got to keep in sync between them all if possible

I've got a gnarly workaround where I've wrapped my bazel invocations in scripts that pull args out of the bazelrc and directly pass them in as -- args which does the job.

The only suggestion I've got which is feasible but tedious, would be to evaluate the provided -- args against bazel help startup_options, and put those that match before the aquery part of the command in: https://github.com/hedronvision/bazel-compile-commands-extractor/blob/33658bab23a4858b513d767480b43d3d8fb6a3d1/refresh.template.py#L1208-L1212 That's probably just putting lipstick on a pig / complicating your project, so I'm not sure if it would be the type of thing you'd want to add.

btalb avatar Feb 21 '24 22:02 btalb

Oh darn. I see. (Sorry for misunderstanding the `bazel help startup_options part and the startup positional restriction.)

Sorta open to it if there's not a better way, but I think it'll be a bit tricky to get right with args?

Just to make sure there aren't better ways given Bazel's functionality

  • I want to make sure that we're on the same page about .bazelrc import or try-import: You wouldn't have to duplicate/sync the settings across all the files, since bazelrcs can import each other.
  • Similarly, there are the system/home rc files if you want something applied automatically everywhere

cpsauer avatar Feb 22 '24 01:02 cpsauer

I'm probably getting towards the nit-picky territory, but neither quite meet my needs:

  • I'd still need to have a bazelrc with that import line in every module, which feels like a bit of an anti-pattern to insist on that file existing when it specifies nothing project specific.
  • I'm still getting my head around Bazel's ever-changing terminology... but I'm creating a "collection of related modules that should have this shared bazelrc". I'd like to avoid forcing users of this collection of modules to break all their other bazel projects to use mine.

Anyway, I'm happy for this to be closed as won't do given it's a bit boutique. Just thought I'd raise it in case I was missing something obvious :slightly_smiling_face:

btalb avatar Feb 22 '24 08:02 btalb

I probably can't do given some severe time constraints over here--but I'd be open to a PR if you're down to do it well. (Up to you, close if no.) Sorry to not have a magic bullet up my sleeve for ya here. I really wish also that bazel handled some things differently here: accepting the args in any location and offering a way to introspect its args within bazel run. Maybe we should be filing an issue asking them for that? [I think I'm still not fully understanding why the gnarly wrapper script beats these alternatives--but maybe that's ok.]

Cheers, Chris

cpsauer avatar Feb 23 '24 06:02 cpsauer