Home > Blockchain >  Why can't my programs find resource files when using bazel run //package
Why can't my programs find resource files when using bazel run //package

Time:04-12

I apologise if the title is a bit vague - I didn't know how else to phrase it.

I am quite new to Bazel but one thing that I don't quite understand is why my program fails to find the resource files I specify using the data attribute for the cc_binary rule

For context I am trying to follow Lazy Foo's SDL2 tutorials and I have a directory structure somewhat like this

gltuts
|
 ---lazy-foo-02
|   |
|    ---media
|       |
|        ---hello_world.bmp
|
 ---lazy-foo-03

Here is what my BUILD file looks like inside of the lazy-foo-02 directory

cc_binary(
name = "lazy-foo-02",
  srcs = [
    "main.cpp",
  ],
  data = glob(["media/*"]),
  deps = [
    "//subprojects:sdl2",
  ],
)

When I use the bazel run command (I use bazelisk)

bazelisk run //lazy-foo-02

I get an error saying my hello_world isn't found. I managed to find an executable in bazel-bin (well a symlink to the executable somewhere in the .cache/bazel/... directory structure.

Now the directory where the symlink is located has the media directory and when I execute from this symlink location, it works as expected.

Why would this not work using the bazel run command? Am I missing anything from the BUILD file?

I am happy to provide more information if needed.

Thanks

CodePudding user response:

Use the C runfiles library to find them. Add the dependency in your BUILD file:

cc_binary(
  name = "lazy-foo-02",
  srcs = [
    "main.cpp",
  ],
  data = glob(["media/*"]),
  deps = [
    "//subprojects:sdl2",
    "@bazel_tools//tools/cpp/runfiles",
  ],
)

and then where your code needs to find the file:

#include <string>
#include <memory>
#include "tools/cpp/runfiles/runfiles.h"

using bazel::tools::cpp::runfiles::Runfiles;

int main(int argc, char** argv) {
  std::string error;
  std::unique_ptr<Runfiles> runfiles(
      Runfiles::Create(argv[0], &error));

  if (runfiles == nullptr) {
    return 1  // error handling
  }

  std::string path =
      runfiles->Rlocation("gltuts/lazy-foo-02/media/hello_world.bmp");
}

See the header file for API docs and some notes on how to handle child processes, accessing them without argv[0], etc. @bazel_tools is a special repository name which is automatically provided by bazel itself, so no need for any WORKSPACE changes.

  • Related