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.