
Many Bazel attributes support the use of predefined variables
and functions such as @D
for output directory or
$(location //foo:bar)
to get the path to a label. But what
if you want to apply some sort of tranformation to these
variables, or define your own custom make variables? This
blog post explains how.
I was working on integrating some third-paty C software
into my Bazel workspace. The project was relatively simple, so I
decide that rather than call into the third-party project’s
build system usuing rules_foreign_cc
, I would instead
write native cc_library()
build rules.
I started by writing a basic cc_library()
rule:
|
|
And received errors like the following:
external/libexample/src/libexample.c:11:10: fatal error: 'libexample.h' file not found
#include "libexample.h"
^~~~~~~~~~~~
1 error generated.
This error occurs because libexample.h
lives in the include/
directory,
but the compiler flags set by cc_library()
requires all headers contained
within the hdrs
attribute to be included with angle brackets, instead of
quotes. In other words, if the code had performed #include <libexample.h>
instead of #include "libexample.h"
, the library would have compiled fine.
To fix this, I decided to add the appropriate compiler flags using copts
.
I wanted something like the following:
|
|
Unfortunately, the above code, doesn’t work – the $(dirname)
function
doesn’t exist. I did some research and realized that I could solve this
problem by writing my own variable provider. By writing a rule
which returns a platform_common.TemplateVariableInfo
, and referencing
it as a toolchain in cc_library()
, you can define variables that can
then be used in attributes like copts
.
After some time I came up with the following:
|
|
|
|
Problem solved!