My bazel.rc has flags that set up remote caching, but in certain situations I want to disable it, e.g. when running in an environment with network restrictions.
How do I "unset" the flags set in bazel.rc? For instance, bazel.rc sets --google_credentials=/path/to/key, so how do I override that and pass in null so it doesn't look for credentials?
I would like to retain the rest of my bazel.rc, so I don't want to simply ignore it.
Partial bazel.rc:
build --google_credentials=/path/to/key
build --google_default_credentials
build --google_auth_scopes=https://www.googleapis.com/auth/cloud-source-tools
build --bes_backend=buildeventservice.googleapis.com
build --bes_best_effort=false
build --bes_timeout=10s
build --project_id=123456
build --remote_cache=remotebuildexecution.googleapis.com
build --remote_instance_name=projects/myproject
build --spawn_strategy=remote
build --genrule_strategy=remote
build --tls_enabled=1
build --remote_accept_cached=true
Flags specified on the command line will override anything in the bazelrc file. So you can specify --google_credentials= to clear the value.
There are also other ways to set this up. In your case say you want --foo=1 --bar=2 by default, but sometimes you want to turn those off. It would be annoying to have to remember all the flags to turn things off, so you can create configs. Your bazelrc file would look like this:
build --foo=1 --bar=2
build:nofoo --foo= --bar=
When do bazel build normally, you get --foo=1 and --bar=2. When you don't want foo and bar you do bazel build --config=nofoo, which expands to bazel build --foo=1 --bar=2 --foo= --bar=, where the later flags will override the previous flags.
Related
We're starting to use gRPC and are currently using bazel as our build tool. After an engineer pulls in updates to proto definitions, they'll need to proto compile. Due to the structure of our repository, the proto compile targets will be scattered in the repo.
The only option I'm seeing is to use a target naming convention so engineers just need to do something like bazel build //...:compile-proto. Are there other ways to make it easy for engineers to proto compile all updated proto definitions?
If you add a specific tag to each of them, you can use --build_tag_filters.
For example:
a_proto_library(
name = "compile-proto",
tags = ["a_proto"],
[...]
)
and then bazel build --build_tag_filters=a_proto //....
You can also wrap the rule in a macro to add the tag automatically.
I don't think //...:compile-proto is a valid target pattern, so unfortunately I'm not sure that that would work (not that you necessarily really want to rely on naming conventions anyway). See https://docs.bazel.build/versions/main/guide.html#specifying-targets-to-build
One option is to let bazel do all the updating for you. If you're already doing builds like bazel build //... to build everything, then once you pull in updates to proto definitions, another bazel build //... should rebuild only what has changed.
Another option is to find all rules using bazel query:
https://docs.bazel.build/versions/main/query.html
https://docs.bazel.build/versions/main/query-how-to.html
https://docs.bazel.build/versions/main/query.html#kind
Something like:
targets=$(bazel query "kind('java_proto_library', //...)")
bazel build $targets
Note that query with //... will load every build file in the workspace, but not build anything.
How can I verify that my entire project does not contain errors (say, references to targets which are not declared anywhere)?
In a static language, whenever my code references something that doesn't exist, I get compiler errors. Is there a way to perform an equivalent check with bazel?
bazel build --nobuild //... has a similar effect. It evaluates all the rules (and fails with any errors), but doesn't actually build anything.
Add any additional flags you would with a full build you're checking against. Most flags result in rules evaluating differently, so you might see different errors depending on what flags you use.
A set of Bazel targets can build correctly for some configurations but not others. For example, if there's a select without a default like this:
cc_library(
name = "something",
srcs = select({
":cpu_k8": ["something_k8.cc"],
}),
)
then it will build with --cpu=k8 but not --cpu=aarch64. This means you have to specify the same set of flags when checking as with a full build.
I am trying to build a Docker image with this code:
container_image(
name = "docker_image",
base = "#java_base//image",
files = [":executable_deploy.jar"],
cmd = ["java", "-jar", "executable_deploy.jar"],
env = { "VERSION" : "$(VERSION)" }
)
I want to pass a variable to the target built so it can be replaced in $(VERSION). Is this possible?
I have tried with VERSION=1.0.0 bazel build :docker_image, but I get an error:
$(VERSION) not defined.
How can I pass that variable?
According docs:
The values of this field (env) support make variables (e.g., $(FOO)) and
stamp variables; keys support make variables as well.
But I don't understand exactly what that means.
Those variables can be set via the --define flag.
There is a section on the rules_docker page about stamping which covers this.
Essentially you can do something like:
bazel build --define=VERSION=1.0.0 //:docker_image
It is also possible to source these key / value pairs from the stable-status.txt and volatile-status.txt files. The user manual page for bazel shows how to use these files, and the use of the --workspace_status_command to populate them.
For setting defaults, you could use a .bazelrc file, with something like the following as the contents:
build --define=VERSION=0.0.0-PLACEHOLDER
The flags passed on the command line will take precedence over those in the .bazelrc file.
It's worth mentioning, that changing define values will cause bazel to analyze everything again, which depending on the graph may take some time, but only affected actions will be executed.
I was wondering if its possible for platform-specific default Bazel build flags.
For example, we want to use --workspace_status_command but this must be a shell script on Linux and must point towards a batch script for Windows.
Is there a way we can write in the tools/bazel.rc file something like...
if platform=WINDOWS build: --workspace_status_command=status_command.bat
if platform=LINUX build: --workspace_status_command=status_command.sh
We could generate a .bazelrc file by having the users run a script before building, but it would be cleaner/nicer if this was not neccessary.
Yes, kind of. You can specify config-specific bazelrc entries, which you can select by passing --config=<configname>.
For example your bazelrc could look like:
build:linux --cpu=k8
build:linux --workspace_status_command=/path/to/command.sh
build:windows --cpu=x64_windows
build:windows --workspace_status_command=c:/path/to/command.bat
And you'd build like so:
bazel build --config=linux //path/to:target
or:
bazel build --config=windows //path/to:target
You have to be careful not to mix semantically conflicting --config flags (Bazel doesn't prevent you from that). Though it will work, the results may be unpredictable when the configs tinker with the same flags.
Passing --config to all commands is tricky, it depends on developers remembering to do this, or controlling the places where Bazel is called.
I think a better answer would be to teach the version control system how to produce the values, like by putting a git-bazel-stamp script on the $PATH/%PATH% so that git bazel-stamp works.
Then we need workspace_status_command to allow commands from the PATH rather than a path on disk.
Proper way to do this is to wrap your cc_library with a custom macro, and pass hardcoded flags to copts. For full reference, look at envoy_library.bzl.
In short, your steps:
Define a macro to wrap cc_library:
def my_cc_library(
name,
copts=[],
**kwargs):
cc_library(name, copts=copts + my_flags(), **kwargs)
Define my_flags() macro as following:
config_setting(
name = "windows_x86_64",
values = {"cpu": "x64_windows"},
)
config_setting(
name = "linux_k8",
values = {"cpu": "k8"},
)
def my_flags():
x64_windows_options = ["/W4"]
k8_options = ["-Wall"]
return select({
":windows_x86_64": x64_windows_options,
":linux_k8": k8_options,
"//conditions:default": [],
})
How it works:
Depending on --cpu flag value my_flags() will return different flags.
This value is resolved automatically based on a platform. On Windows, it's x64_windows, and on Linux it's k8.
Then, your macro my_cc_library will supply this flags to every target in a project.
A better way of doing this has been added since you asked--sometime in 2019.
If you add
common --enable_platform_specific_config to your .bazelrc, then --config=windows will automatically apply on windows hosts, --config=macos on mac, --config=linux on linux, etc.
You can then add lines to your .bazelrc like:
build:windows --windows-flags
build:linux --linux-flags
There is one downside, though. This works based on the host rather than the target. So if you're cross-compiling, e.g. to mobile, and want different flags there, you'll have to go with a solution like envoy's (see other answer), or (probably better) add transitions into your graph targets. (See discussion here and here. "Flagless builds" are still under development, but there are usable hacks in the meantime.) You could also use the temporary platform_mappings API.
References:
Commit that added this functionality.
Where it appears in the Bazel docs.
I'm working on a custom Build Workflow and need to set the LastGoodBuild at the definition (MSDN Description of BuildDefinitionDetail).
Any Ideas how to set the LastGood Build (Not with an update statement in the database :-))