在使用Bazel构建的应用程序中访问运行时文件

时间:2018-04-17 10:17:02

标签: c++ build bazel build-system

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

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

问题是Bazel将runfiles置于一个奇怪的路径,依赖于构建系统的目录(<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>/)?

3 个答案:

答案 0 :(得分:1)

  

是否存在任何理智(或灵活,如果您愿意)的方式来引用运行文件,而不是硬编码这些路径

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

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

答案 1 :(得分:1)

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

  1. 使用args属性告诉二进制文件所在的位置。这只适用于通过bazel run运行二进制文件,并要求二进制文件理解这些标志。

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

  3. 你可以在这里看到一些例子(它们是针对java的,但对于cc规则应该是类似的):

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

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

答案 2 :(得分:0)

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

  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");
    
      // ...
    }