Query the output destination of a bazel target, with --symlink_prefix - bazel

Can bazel tell me where --symlink_prefix points?
Different users have different ~/.bazelrc files, which specify different values for this flag. I'd like to query, in a given workspace, where the binary files will get (or have been) written to.
Thanks.

bazel info bazel-bin and bazel info bazel-genfiles will tell you the absolute paths.

Related

How to get dependency graph for dependencies of a target?

I want to get mutual dependencies of all dependencies of a target, to provide this information to a binary (for static analysis).
I defined a rule that loop through direct dependencies. How can I get dependencies of each dependency, to discover the entire graph recursively? Is it possible at all? If no, is there an alternative way?
def _impl(ctx):
for i, d in enumerate(ctx.attr.deps):
# I need to get dependencies of d somehow here
Depending on exactly what information you want, Aspects may do what you want:
https://docs.bazel.build/versions/master/skylark/aspects.html
They allow a rule to collect additional information from transitive dependencies.
There's also the genquery rule, but this may or may not give you all the information you want: https://docs.bazel.build/versions/master/be/general.html#genquery
genquery makes bazel query results available to actions.
I need to pass parameter --output=graph to genquery:
blaze query "kind(rule, deps(//path/to/mytarget))" --output=graph

Can I query for a set of tags?

I want to run a set of Bazel targets. My BUILD file look like this
load("#rules_java//java:defs.bzl", "java_binary")
java_binary(
name = "run_me",
srcs = glob(["src1/main/java/com/example/*.java"]),
tags = ["java", "good"],
)
java_binary(
name = "me_also",
srcs = glob(["src2/main/java/com/example/*.java"]),
tags = ["java", "good"],
)
java_binary(
name = "do_not_run_me",
srcs = glob(["src3/main/java/com/example/*.java"]),
tags = ["java", "bad"],
)
I want to run all the targets tagged as "good". I'm hoping to be able to do something like
bazel query 'tags(["good"], //...)'
I don't see the ability to query for tags in the documentation. I do see attr, so I tried
bazel query 'attr(tags, "\[good\]", //...)'
But that doesn't work. I assume because
List-type attributes (such as srcs, data, etc) are converted to strings of the form [value1, ..., valuen], starting with a [ bracket, ending with a ] bracket and using ", " (comma, space) to delimit multiple values
I am able to make it work with an exact match,
bazel query 'attr(tags, "\[good, java\]", //...)'
However, notice that
The ordering of the list swapped ("\[java, good\]") doesn't get any results). I'm not sure if it's alphabetizing or if it's putting them in a hash-set. But it means the ordering isn't reliable.
I don't want to have to list all the tags. I want to be able to run all the "good" targets even if some are also tagged "slow" or "local".
Can I use tags for this task? Are tags really just intended for tests? (The test_suite is the reason I thought to use tags in the first place.)
If by "run a set of Bazel targets" you mean bazel run, you can use --build_tag_filters for this:
https://docs.bazel.build/versions/3.2.0/command-line-reference.html#flag--build_tag_filters
Note however that bazel run supports running only 1 executable target at a time.
If you want to run many binaries in a single call, you'll need to continue to pursue bazel query.
The attr() filter accepts a regular expression, so to get around the problem of tags being in arbitrary order, you can do something like:
bazel query "attr(tags, '\\bgood\\b', //...)"
(where \b is the word boundary matcher)
If you have multiple tags, you can use intersect:
bazel query "attr(tags, '\\bgood\\b', //...) intersect attr(tags, '\\balso-good\\b', //...)"
That will give you the list of targets to run, then you can do something like:
targets=$(bazel query "attr(tags, '\\bgood\\b', //...)")
bazel build ${targets[#]}
for target in ${targets[#]}; do
bazel run $target &
done
bazel run will build the targets before running them, and bazel will wait on previous invocations of itself in the same workspace[1]. So to get the binaries to run in parallel (if that's something you want), the example builds all the targets before running them. (bazel won't block subsequent invocations of itself once the binary is running)
There's also another idea that seems nicer, which is to have an sh_binary which depends on all the binaries you want to run, and the sh_binary script simply runs them. You would then be able to do bazel run on that single sh_binary. The problem with that is you'd have to list each binary you want to run in the data attribute of the sh_binary, because it's not possible to create dependencies in a BUILD file using a query (despite there being a genquery rule -- that just outputs the results of the query to a file).
[1] unless you have separate output bases using --output_base for the different invocations

What do the last two entries of PATH tell you?

I'm still learning how PATH works, what exactly is echo $PATH's output meant to be? What do they tell us?
What exactly is echo $PATH's output meant to be?
The current path.
What do the last two entries tell you?
The last two directories on your path.
In other words, it's unclear what you're asking. Do you not know what a path is? Are you asking what a particular sequence of special characters mean in the context of a path? What is the explicit path you're asking about?
$PATH variable is simply a list of paths that your system automatically checks whenever you run a command on, say your bash terminal.
PATH is a colon : (Unix-like) or semi-colon ; (Windows) separated list.
Whenever you run a command like ls -lrt, your system looks for the definition of the command (or function) ls. So the definition of the PATH variable being established, we can answer your two questions:
what exactly is echo $PATH's output meant to be
The $PATH's output provides a list of paths.
What do the last two entries of PATH tell you?
PATH is list is of all the paths where your system will look for a command. So the last 2 entries tell you the last 2 paths out of the list.

How to target HDF5 datasets as Snakemake input/output?

How can I tell Snakemake that the input/output of a rule should be an HDF5 dataset (so with its own specific "path" within the actual real HDF5 file path)?
snakemake considers the input and output file paths as strings, regardless of the file type and content. If your HDF5 files have a specific path, then use those paths in the input/output directives, possibly using a function-as-input to locate the HDF5 path.
For a more useful answer you should add to your question some example code of what you are trying to do.

can bazel test if two rules are identical

I'd like to compare two rules to see whether or not they are identical (in particular, I'd like to be able to test a bazel target before and after a commit to see if it has changed)
Is there a way to accomplish this, perhaps with bazel query?
You can try bazel query with --output=build to have bazel print out the rule with everything expanded (e.g. macros evaluated, globs expanded, expressions evaluated, etc) before and after the change, and compare the results. See https://docs.bazel.build/versions/master/query.html#output-build for more information.

Resources