Example showing how to use Starlark configuration so a cc_binary
can set custom "features" for cc_library
dependencies to include.
This example has five files:
-
custom_settings/BUILD - This defines a custom Starlark flag called
//custom_settings:mycopts
which defines the set of possible features and stores whatever features thecc_binary
sets.cc_library
uses aselect
to read this flag and set itscopts
accordingly. This file also declares theconfig_setting
s theselect
uses. -
defs.bzl - This defines a custom Starlark rule
transition_rule
which defines an attributeset_features
that sets the desired feature andactual_binary
which declares thecc_binary
this should apply to.Because
cc_binary
is a native (not Starlark-defined) rule, we can't addset_features
directly to it. For Starlark-defined rules, we could omittransition_rule
and just add the functionality directly.transition_rule
applies a Starlark transition called_copt_transition
that reads the value ofset_features
and sets//custom-settings:mycopts
accordingly.Finally, this file declares a macro (also) called
cc_binary
that automates away all this extra abstraction: the new macrocc_binary
simply instantiates atransition_rule
with the desiredset_features
then passes all other attributes directly to the nativecc_binary
. To the end user this makes it look likecc_binary
magically supports a new attribute. -
BUILD - This defines three versions of a
cc_binary
all depending on the samecc_library
: one usesfeature
, the other usesfeature2
, and the third fails to build because it "forgets" to set any feature.
To see it in action, cd to this directory and try the following commands:
$ bazel run :app_with_feature1
...
Running my app!
Building lib with feature 1!
$ bazel run :app_with_feature2
...
Running my app!
Building lib with feature 2!
$ bazel run :app_forgets_to_set_features
ERROR: $(MYWORKSPACE)/cc_binary_selectable_copts/BUILD:32:13: Configurable attribute "copts"
doesn't match this configuration: You must explicitly set which features you want!
This example relies on select
and involves some duplication of values
(e.g. "feature1"
is defined in //custom_settings:mycopts
and //:lib
separately sets "-Dfeature1"
). You could write more Starlark macros to make the
BUILD
API even simpler. For example: not requiring any changes to
cc_library
at all.