Expand bazel command with bazelrc - bazel

given a bazel command, for example bazel build //..., is it possible to see what build command this expands to based on the bazelrc(s)?
bazelrcs are great to set default flags, like the default platform to build for setting some variables based on profiles.
They also allow for nested bazelrcs, that you can import and try-import leading to a rather complex expansion of bazel commands via bazelrcs.
To verify that the bazelrcs did indeed configure the correct things and did not override some flags accidentally, I would love to see the output of what bazel would expand a bazel command to.
Is that possible?
I tried setting --logging=0 and --logging=6 with bazel 5.3.0 but see no such output.

You can run your build using the --explain flag.
Something like
bazel build --explain explain.log //...
should produce a file explain.log where the first line contains the expanded flags.

Related

Bazel builds from scratch ignoring cache

I observe that my Bazel build agent frequently builds the project from scratch (including compiling grpc, which keeps unchanged) instead of taking results from cache. Is there a way, like query or cquery (pardon my ignorance) to determine why is the cache considered invalid for particular target? Or any techniques to tackle cache invalidation problem?
This is How the bazel build works :
When running a build or a test, Bazel does the following: Loads the BUILD files relevant to the target. Analyzes the inputs and their dependencies, applies the specified build rules, and produces an action graph. Executes the build actions on the inputs until the final build outputs are produced.
If you are having any clear assumptions can you please share the complete details!
This is most likely due to the rebuild sensitivity to particular environment variables. Many build actions will read from environment variables and use them to change the outputs. Bazel keeps track of this and will rebuild seemingly unchanged remote targets when your env changes.
To demonstrate this;
Build grpc (2x ensure it is cached the second time)
Change the PATH environment variable (your IDE may do this without you knowing)
mkdir ~/bin && export PATH=$PATH:~/bin
Rebuild grpc (This should trigger a complete rebuild)
There are a couple helpful flags to combat this rebuild sensitivity, and I'd recommend adding them to your bazelrc.
incompatible_strict_action_env: Freezes your environment and doesn't source environment variables from your shell.
action_env modify environment variables as needed for you build.
# file //.bazelrc
# Don't source environment from shell
build --incompatible_strict_action_env
# Use action_env as needed for your project
build --action_env=CC=clang

How do I debug an annotation processor in a bazel java_library rule?

I have added an annotation processor as a java_plugin and have added this into the plugins section of my java_library rule. I was wondering what are the bazel options to step through the annotation processor code and the javac compiler's code?
One way to do this is to run bazel build with --subcommands. Bazel will then print out all the commands it executes during a build. You can then find the javac invocation you're interested in, copy the command line (including the cd part so you're in the correct directory), modify the command line to include the debugging options, and run it manually. Then you can debug it like you would any java program.
One thing to note is that bazel will print only the commands that it actually runs in that build, so if the action you're interested in is already up-to-date, you may have to delete one of its outputs (e.g. the jar output of that library) to get bazel to re-run the action.

How to determine absolute path of target using bazel query?

Question
Is there any way I could use bazel query or aspects to identify where on the package path bazel is picking up a package? Something similar to the which command.
The documentation suggests using the --show_package_location. However that is deprecated and no longer supported, see #5592. Additionally, my attempts at using it have not uncovered much useful information. I have tried bazel query //some/target/... --output label_kind --show_package_location as well as other permutations with bazel build and it doesn't add output anything different to the console output.
Motivation
I have two different directories on my package path for fetch, query and build.
--package_path=%workspace%:%workspace%/__fuse__
This configuration supports a workflow where users perform sparse-checkouts of our large repository, while still being able to build code that has not been locally checked out. When building targets, Bazel checks for the locally checked out version of package, and if that doesn't exist, it searches a read only fuse mount.
Sometimes it's unclear to users where a package is getting picked up from, i.e. whether it's the locally checked out version or the one served from fuse. This becomes problematic when they delete or move a Bazel package, and Bazel picks up the version on the fuse mount.
It'd be nice if I could point them to a command that would map each package to where it's being picked up. For example, if i ran the command on ...
//some/package/foo --> package_path/some/package/foo
//some/package/bar --> other_package_path/some/package/bar
I completely missed this in the bazel query documentation.
With bazel query, I simply needed to add --output location, so provided I make a query like:
bazel query //some/package/... --output location
Then bazel query will output
/absolute/path/some/package/BUILD:lineno:colno target_kind label
for each target in //some/package/...

How to specify "default" target labels when running bazel test

We're considering migrating to Bazel from Make. To make the transition easier I would like to have bazel test (no flags / options) run the current directory's tests, if any.
So instead of bazel test my_tests bazel test would find the current directory's BUILD file, find any *_test rules and run those.
If you want to do exactly as you said then you can use your own script.
When you run “bazel” it actually looks to see if there is a script named “bazel” under tools directory of the current workspace. So if you have an executable under “$workspace/tools/bazel” bazel will run that instead of the bazel binary itself.
This means you can write a script that checks if the only argument is “test” and if so calls “bazel-real test :all”
It can also check the exit code to see if there were no tests (it’s a specific error code) and return 0 instead
You can use the all target pattern to match all targets in the current package: bazel test :all
You can read more about it here: https://docs.bazel.build/versions/master/user-manual.html#target-patterns
Note however that if there are no test targets in the current package, bazel will give an error: "ERROR: No test targets were found, yet testing was requested.". In this case bazel will give an exit code of 4: https://docs.bazel.build/versions/master/user-manual.html#what-exit-code-will-i-get
I recommend creating a alias called bazel-test to bazel test :all.

How do I set the dart2js --minify option from the command line when executing `pub build`?

For my release process I need several different "modes." However, if I use the --mode option for pub build and set it to any value other than release, it forces un-minified javascript.
I know I can configure the dart2js transformer in my pubspec.yaml, but if I set minify: true under the $dart2js heading in my pubspec.yaml I am then forcing them to be minified, and then cannot produce un-minified debug builds.
What I'm really looking for is a way to configure arbitrary dart2js options (minified, checked, etc.) in pub build via the CLI (so that I don't have to hardcode in pubspec.yaml), or, failing that, to be able to specify additional arbitrary flags from the pub build CLI so that I can reserve --mode for debug and release. The asPlugin() transformer constructor takes a BarbackSettings object, but I can't see how to see arbitrary params in that via the command line.
I have never seen anything like that mentioned (for example in any of the bug reports) and I'm pretty sure this is not supported. I suggest to just create a feature request at http://dartbug.com.
One way I can think of is to create a script which manipulates the pubspec.yaml file before executing pub build. This should be easy using the https://pub.dartlang.org/packages/yaml package.

Resources