How to write files to current directory instead of bazel-out

大憨熊 提交于 2019-11-27 18:59:01

问题


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/...?


回答1:


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




回答2:


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

)




回答3:


If you're passing the name of the output file in when running, you can simply use absolute paths. To make this easier, you can use the realpath utility if you're in linux. If you're on a mac, it is included in brew install coreutils. Then running it looks something like:

bazel run my_app_dir:binary_target -- --output_file=`realpath relative/path/to.output


来源:https://stackoverflow.com/questions/47764221/how-to-write-files-to-current-directory-instead-of-bazel-out

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!