【问题标题】:Access runtime files in application built with Bazel在使用 Bazel 构建的应用程序中访问运行时文件
【发布时间】:2018-04-17 10:17:02
【问题描述】:

我正在尝试使用 Bazel 构建一个 C++ 应用程序,它在运行时需要许多文件。我使用构建规则的data 属性将这些文件包含在构建目标中:

cc_binary(
  name = "myapp",
  srcs = [
    "main.cpp",
  ],
  data = glob([ "media/**" ], exclude = [ "media/BUILD", "media/.keep" ]),
)

问题在于 Bazel 将运行文件放在一个奇怪的路径下,即 build-system-dependant 目录 (<build target name>.runfiles/__main__/<build target name>/)。

除了像这样对这些路径进行硬编码之外,还有什么健全的(或灵活的,如果你愿意的话)引用运行文件的方法

// "myapp" is the build target name
FILE* f = fopen("myapp/myapp.runfiles/__main__/myapp/media/file.txt", "r");

或从清单中读取路径(这仍然不是更好的选择,因为每个文件都以 __main__/<build target name>/ 为前缀)?

【问题讨论】:

    标签: c++ build bazel build-system


    【解决方案1】:

    看起来 Bazel 0.15 added 支持所谓的 Rlocation,它允许通过在代码中添加一个 using 此类来循环运行时文件:

    1. 依赖于你的构建规则中的这个运行文件库:

      cc_binary(
        name = "my_binary",
        ...
        deps = ["@bazel_tools//tools/cpp/runfiles"],
      )
      
    2. 包括运行文件库。

      #include "tools/cpp/runfiles/runfiles.h"
      using bazel::tools::cpp::runfiles::Runfiles;
      
    3. 创建一个Runfiles 对象并使用Rlocation 查找运行文件路径:

      int main(int argc, char** argv) {
        std::string error;
        std::unique_ptr<Runfiles> runfiles(Runfiles::Create(argv[0], &error));
      
        // Important:
        //   If this is a test, use Runfiles::CreateForTest(&error).
        //   Otherwise, if you don't have the value for argv[0] for whatever
        //   reason, then use Runfiles::Create(&error).
      
        if (runfiles == nullptr) {
          // error handling
        }
      
        std::string path = runfiles->Rlocation("my_workspace/path/to/my/data.txt");
      
        // ...
      }
      

    【讨论】:

    • 这是访问运行文件的现代方式,适用于所有平台,包括 Windows。我创建了github.com/fmeum/rules_runfiles 来自动生成所需的字符串常量。
    【解决方案2】:

    除了像这样对这些路径进行硬编码之外,是否有任何理智(或灵活,如果您愿意)的方式来引用运行文件

    还没有。但我们正在努力。

    有关设计文档和进度,请参阅https://github.com/bazelbuild/bazel/issues/4460

    【讨论】:

      【解决方案3】:

      除了 László 对设计文档的回答之外,您还可以尝试以下几件事:

      1. 使用 args 属性告诉二进制文件文件在哪里。这仅在您通过 bazel run 运行二进制文件时才有效,并且要求二进制文件理解这些标志。

      2. 使用包含所需文件路径的 genrule 创建清单。清单将位于已知位置,因此您可以在运行时读取。

      您可以在此处查看一些示例(它们适用于 java,但对于 cc 规则应该类似):

      https://groups.google.com/d/topic/bazel-discuss/UTeGdXjO_lQ/discussion

      另一种选择是使用 pkg_tar 或类似规则将二进制文件及其运行文件重新打包成您需要的任何结构: https://docs.bazel.build/versions/master/be/pkg.html(据我所知,pkg_tar 不会为二进制文件打包运行文件。)

      【讨论】:

        猜你喜欢
        • 2021-07-24
        • 2022-10-17
        • 2022-08-02
        • 1970-01-01
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 2015-03-13
        • 1970-01-01
        相关资源
        最近更新 更多