You probably cannot do that
in general, but there are probably ways to get something usable for you. Let me explain:
The short version is that you cannot use the result of a build action (e.g. trying to compile) to modify the shape of the build graph. This is not limited to Bazel, nearly all other build systems like make, CMake or GN do have an independent "configuration" step that generates the final build graph, and this is where the kind of probing you describe is performed.
Bazel does allow you to probe the host system
before the build graph is loaded, by writing a custom
repository rule. This is a Starlark function that can inspect your system, even download things for the network, and do plenty of other non-hermetic things. The result is stored in a "repository directory", which is stored in the same location as build outputs, and its content is later available to your BUILD files. For example see
https://github.com/solarhess/rules_build_secrets which loads environment variables into a @my_secrets//:BUILD.bazel file, so you can access their values in your project BUILD definitions (without ever committing these values to your source tree).
Thus you could write a custom repository rule to invoke your compiler and probe the C runtime, look what libraries are installed on the host system, etc. And then use the result in your project. But there are a few gotchas:
- Repository rules don't know anything about the build configuration, the toolchain you want to use, and you cannot use target rules like cc_binary() in their implementation function (instead you would use repository_ctx.execute() directly to invoke the compiler and parse the result manually). There is also no Bazel command-line flag you can pass to change their behavior (they take arguments from your WORKSPACE file exclusively, which also doesn't know anything about your build configuration either).
- At build time, which C library is used to build a C++ executable depends on which C++ toolchain is used, which itself depends on the current build configuration.
And this information is not available to repository rules. Besides, Bazel supports using multiple build configurations in a single build invocation / graph, and repository rules are run before any graph is constructed.
In other words, if all you care are the C library and the installed libraries of your host system,
and that you always build with the default C++ toolchain configuration (which matches your host system), you may be able to use a repository rule. Because the information it will find will be correct.
Otherwise, e.g. when cross-compiling, or using a different toolchain, this is not possible, just like you cannot write a Makefile or Ninja build plan that would do the probing itself and modify its dependencies based on the result.
A simpler solution would be to model possible values for the flags you are interested in into
build configuration attributes, and set them either on the command-line (e.g. `
bazel build --//my_build_config:libc_has_explicit_bzero --cpu=<cpu> --crosstool_top=<toolchain> <targets>`, or in your
.bazelrc to avoid too much typing).
Hope this helps,