Integrating SDL2 with bazel on macOS
Table of Contents
Bazel#
Came across bazel build system recently at my new job and found it to be quite nice compared to my earlier mainstays CMake and Make. It’s fast and correct, just as their website says. But I also liked it because it’s explicit with very little magic. And it has a powerful query/tools system that allows you to really analyze your builds and dependencies in depth. Though examples in the wild are a bit less since it is a fairly recent entrant compared to its competitors. For a personal side project, I needed to use SDL2 and it was the first time I had to use an external/pre-built library with bazel. This post documents the process I used for my own future reference and may be help some other lost soul like me. Although, the post talks about SDL2 here specifically, the same process can be used for most other external pre-compiled modules.
Download / Install libsdl#
- Download the latest MacOS dmg file from LibSDL
- Double click the downloaded dmg file
- Copy the
SDL2.framework
folder over to/Library/Frameworks
path
Make bazel aware of existence of SDL2#
Update your WORKSPACE
file (resides at the root of your project) with below content. This is important because bazel does all the build steps in a sandbox and one cannot depend on anything outside this sandbox. This step allows bazel to make the content present at this path available to the sandbox as a bazel repository.
new_local_repository(
name = "sdl2",
path = "/Library/Frameworks/SDL2.framework",
build_file = "external/sdl.build",
)
Set up your SDL library to be usable by other modules in your project#
Note the build_file
parameter. This tells bazel how to use this repository. This can be anything according to what you want, the path being relative to the project root. Considering the above example, create a new directory external
in the root of your project and add a new file sdl.BUILD
to it with below content.
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "sdl2",
hdrs = glob(["Headers/*.h"]),
includes = ["Header"], # Optional.
visibility = ["//visibility:public"],
)
This ensures that now your other modules can depend on SDL2 using @sdl2
. The visibility option can be tweaked as per individual needs.
Use SDL2#
Update the BUILD
file of the module where you want to use SDL2 with below contents.
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "some_module",
srcs = [
"some_source.cc",
],
# Optional: copts can be avoided if includes was set in sdl.BUILD
copts = [
"-Iexternal/sdl2/Headers",
],
linkopts = [
"-F/Library/Frameworks",
"-framework SDL2",
],
deps = [
"@sdl2",
],
)
The important portions here are:
copts
: To let bazel know where to search for SDL2 header files. Note that the path here is relative to project root.linkopts
: Need the-F
option to let compiler know where to search for the framework files and-framework
option as usual to link to ZSDL2. The path with-F
can be absolute one. Not sure why this is not restricted by the sandbox. Investigating this currently.deps
: Finally, create the explicit dependency on your sdl2 module by referring to it as@sdl2
By now, the project is ready to be compiled and linked.