I have the following directory structure:
my_dir
|
--> src
| |
| --> foo.cc
| --> BUILD
|
--> WORKSPACE
|
--> bazel-out/ (symlink)
|
| ...
src/BUILD
contains the following code:
cc_binary(
name = "foo",
srcs = ["foo.cc"]
)
The file foo.cc
creates a file named bar.txt
using the regular way with <fstream>
utilities.
However, when I invoke Bazel with bazel run //src:foo
the file bar.txt
is created and placed in bazel-out/darwin-fastbuild/bin/src/foo.runfiles/foo/bar.txt
instead of my_dir/src/bar.txt
, where the original source is.
I tried adding an outs
field to the foo
rule, but Bazel complained that outs
is not a recognized attribute for cc_binary
.
I also thought of creating a filegroup
rule, but there is no deps
field where I can declare foo
as a dependency for those files.
How can I make sure that the files generated by running the cc_binary
rule are placed in my_dir/src/bar.txt
instead of bazel-out/...
?
The Bazel user's build state is located beneath outputRoot/_bazel_$USER . This is called the outputUserRoot directory. Beneath the outputUserRoot directory there is an install directory, and in it is an installBase directory whose name is the MD5 hash of the Bazel installation manifest.
A BUILD file contains several different types of instructions for Bazel. The most important type is the build rule, which tells Bazel how to build the desired outputs, such as executable binaries or libraries.
Workspace. A workspace is a directory on your filesystem that contains the source files for the software you want to build. Each workspace directory has a text file named WORKSPACE which may be empty, or may contain references to external dependencies required to build the outputs.
To do so, bazel caches all files downloaded in the repository cache which, by default, is located at ~/. cache/bazel/_bazel_$USER/cache/repos/v1/ . The location can be changed by the --repository_cache option. The cache is shared between all workspaces and installed versions of bazel.
Bazel doesn't allow you to modify the state of your workspace, by design.
The short answer is that you don't want the results of the past builds to modify the state of your workspace, hence potentially modifying the results of the future builds. It'll violate reproducibility if running Bazel multiple times on the same workspace results in different outputs.
Given your example: imagine calling bazel run //src:foo
which inserts
#define true false
#define false true
at the top of the src/foo.cc
. What happens if you call bazel run //src:foo
again?
The long answer: https://docs.bazel.build/versions/master/rule-challenges.html#assumption-aim-for-correctness-throughput-ease-of-use-latency
Here's more information on the output directory: https://docs.bazel.build/versions/master/output_directories.html#documentation-of-the-current-bazel-output-directory-layout
There could be a workaround to use genrule. Below is an example that I use genrule to copy a file to the .git folder.
genrule(
name = "precommit",
srcs = glob(["git/**"]),
outs = ["precommit.txt"],
# folder contain this BUILD.bazel file is tool which will be symbol linked, we use cd -P to get to the physical path
cmd = "echo 'setup pre-commit.sh' > $(OUTS) && cd -P tools && ./path/to/your-script.sh",
local = 1, # required
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With