Доступ к файлам времени выполнения в приложении, созданном с помощью Bazel

Я пытаюсь создать приложение C ++ с помощью Bazel, для которого во время выполнения требуется несколько файлов. Я использую атрибут data правила сборки, чтобы включить эти файлы в цель сборки:

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

Проблема в том, что Bazel помещает файлы выполнения по странному пути, в каталог, зависящий от системы сборки (<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>/)?


person shybovycha    schedule 17.04.2018    source источник


Ответы (3)


Есть ли какой-либо разумный (или гибкий, если хотите) способ ссылаться на файлы запуска, кроме жесткого кодирования этих путей, как этот

Еще нет. Но мы над этим работаем.

См. https://github.com/bazelbuild/bazel/issues/4460 для дизайна. док и прогресс.

person László    schedule 17.04.2018

В дополнение к ответу Ласло на проектную документацию вы можете попробовать следующее:

  1. Используйте атрибут args, чтобы сообщить двоичному файлу, где находятся файлы. Это работает, только если вы запускаете двоичный файл через bazel run, и требует, чтобы двоичный файл понимал эти флаги.

  2. Создайте манифест с использованием общего правила, содержащего пути к нужным файлам. Манифест будет находиться в известном месте, чтобы вы могли его прочитать во время выполнения.

Здесь вы можете увидеть несколько примеров (они для 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 не упаковывает исполняемые файлы для двоичных файлов.)

person ahumesky    schedule 17.04.2018

Похоже, Bazel 0.15 добавил поддержку того, что называется _ 1_, который позволяет зацикливать файлы времени выполнения, добавляя a, используя этот класс в коде:

  1. Положитесь на эту библиотеку runfiles из вашего правила сборки:

    cc_binary(
      name = "my_binary",
      ...
      deps = ["@bazel_tools//tools/cpp/runfiles"],
    )
    
  2. Включите библиотеку runfiles.

    #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");
    
      // ...
    }
    
person shybovycha    schedule 08.02.2019