Propagating compilation options *up* the dependency chain?

577 views
Skip to first unread message

bla...@google.com

unread,
Jul 25, 2017, 9:34:47 PM7/25/17
to bazel-discuss
The answer is almost certainly "no, that's crazy talk", but is there a way to propagate options/flags/etc to targets that are dependents OF a target? Say I've got three targets

cc_library(
name = "C",
)

cc_library(
name = "B",
deps = [":C"],
)

cc_library(
name = "A",
defines = ["CPU_FREQ=8MHz"],
deps = [":B"],
)

I'd love a way to have both B and C be recompiled with the compiler option -DCPU_FREQ=8MHz. AFAICT there isn't a way of doing this short of creating a new target and having "C" depend on it, which isn't practical when dealing with external dependencies defined in WORKSPACE.

I'm trying this madness because I'm looking to solve two issues:

1) Embedded systems - even if they're the same chip - might need different compile-time defines. For example, you might have two cc_binary targets:

cc_binary(name="Foo", defines=["FEATURE_X"], deps = [":A"])
cc_binary(name="Bar", defines=["FEATURE_Y", "FEATURE_Z"], deps = [":A"])

The libraries A/B/C might have different code paths depending on which features are enabled, and should be compiled once for Foo and once for Bar. You can work around this by creating two parallel dependency cc_library chains "A_feature_x"->"B_feature_x"->"C_feature_x" and "A_feature_y_z"->"B_feature_y_z"->"C_feature_y_z", but that's kinda kludgy and not possible when working with external repos.

2) Unfortunately a lot of embedded SDKs have flat include paths. It would be super helpful to be able to tell these external libraries "Hey look at these headers first" or at least "Prepend this include directory to includes" from the target that depends on them.

Brian Silverman

unread,
Jul 26, 2017, 3:26:46 AM7/26/17
to bla...@google.com, bazel-discuss
I'm pretty sure the answer is no, but I think it is possible to do the "parallel dependency trees with external repositories" thing with most of the kludginess hidden. External repositories can load skylark macros from the main repository (like @//:foo.bzl), so you could write a `all_features_cc_library` macro which creates cc_library rules for the same set of srcs/deps/hdrs/etc for all configuration options that apply to the project, and then external dependencies would do the appropriate ones for the current project.

You could even write a repository rule which generates the .bzl file for a set of feature choices configurable in each top-level project's WORKSPACE and have everything load the all_features_cc_library macro from that repository. I've also gotten a similar effect by putting the rule implementation functions and common attrs in a .bzl file, and then having other .bzl files load those and create rules with another implicit attr added to the common attrs map. That would work for macros too by just passing a hard-coded map of feature options in addition to the other arguments. Something like having an all_features.bzl file in each (top-level) project that looks like this:
load('@common//:all_features_common.bzl', 'do_all_features_cc_library')

def all_features_cc_library(**kwargs):
  do_all_features_cc_library(
    features = {
      'Foo': ['FEATURE_X'],
      'Bar': ['FEATURE_Y', 'FEATURE_Z'],
    },
    **kwargs
  )

That pattern of loading a macro from the main repository which wraps cc_library would solve your include path problem (the macro can prepend includes and/or -I in copts), or you could do it via CROSSTOOL. Seems like most projects with embedded SDKs are going to need a custom CROSSTOOL anyways, which makes a good place to put include flags, but you might not want the SDK available for all targets or something. Features might let you do that, although I've never tried per-target features.


--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/1340d3c7-0ab6-40aa-82a8-f180161adb34%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages