Problem
I've been developing a game in C++ in my spare time and I've opted to use Bazel
as my build tool since I have never had a ton of luck (or fun) working with make
or cmake
. I also have dependencies in other languages (python
for some of the high level scripting). I'm using glfw
for basic window handling and high level graphics support and that works well enough but now comes the problem. I'm uncertain on how I should handle dependencies like glfw
in a Bazel
world.
For some of my dependencies (like gtest
and fruit
) I can just reference them in my WORKSPACE
file and Bazel
handles them automagically but glfw
hasn't adopted Bazel
. So all of this leads me to ask, what should I do about dependencies that don't use Bazel
inside a Bazel
project?
Current approach
For many of the simpler dependencies I have, I simply created a new_git_repository
entry in my WORKSPACE
file and created a BUILD
file for the library. This works great until you get to really complicated libraries like glfw
that have a number of dependencies on their own.
When building glfw
for a Linux machine running X11
you now have a dependency on X11
which would mean adding X11
to my Bazel
setup. X11
Comes with its own set of dependencies (the X11
libraries like X11Cursor
) and so on.
glfw
also tries to provide basic joystick support which is provided by default in Linux which is great! Except that this is provided by the kernel which means that the kernel is also a dependency of my project. Now I shouldn't need anything more than the kernel headers this still seems like a lot to bring in.
Alternative Options
The reason I took the approach I've taken so far is to make the dependencies required to spin up a machine that can successfully build my game very minimal. In theory they just need a C/C++ compiler, Java 8, and Bazel
and they're off to the races. This is great since it also means I can create a Docker
container that has Bazel
installed and do CI/CD really easily.
I could sacrifice this ease and just say that you need to have libraries like glfw
installed before attempting to compile the game but that brings the whole which version is installed and how is it all configured problem back up that Bazel
is supposed to help solve.
Surely there is a simpler solution and I'm overthinking this?
If the glfw
project has no BUILD
files, then you have the following options:
Build glfw
inside a genrule
.
If glfw
supports some other build system like make
, you could create a genrule
that runs the tool. This approach has obvious drawbacks, like the not-to-be-underestimated impracticality of having to declare all inputs of that genrule
, but it'd be the simplest way of Bazel'izing glfw
.
Pre-build glfw.o
and check it into your source tree.
You can create a cc_library
rule for it, and put the .o
file in the srcs
. Even though this solution is the least flexible of all because you not only restrict the target platform to whatever the .o
was built for, but also make it harder to reproduce the whole build, the benefits are sometimes worth the costs.
I view this approach as a last resort. Even in Bazel's own source code there's one cc_library.srcs
that includes a raw object file, because it was worth it, as the commit message of 92caf38
explains.
Require that glfw
be installed.
You already considered this option. Some people may prefer this to the other approaches.