Implicit dependencies when default overidden

94 views
Skip to first unread message

Matthew Green

unread,
Jun 4, 2021, 1:05:37 PM6/4/21
to bazel-dev
Hi,

I originally posted this on bazel-discuss but it didn't get much traction, and I guess it is more of a bazel design question anyway.

I'm writing a rule that takes an attribute with a default, but can be overridden by users.

The implicit dependency on the default is always present even on rule instances where the default is overriden. How can I avoid this?

e.g. the toy example

myobj = rule(
  implementation = _myobj_impl,
  attrs = {
    ...
    "default_deps": attr.label_list(
       doc = "Default dependencies",
       default = [Label("//def:deps")],
    ),
    ...
  }
)

myobj(
  name = "has_impl_dep",
  default_deps = [],
  ...
)

In this case the example rule instance ":has_impl_dep" _still_ has an implicit dependency on //def:deps, _even though_ the default value is overridden in by the instance.

I would have expect the implicit dependency not to be present on rule instances that override the default, but it is. Is this behaviour intentional?

Thanks,
Matt

Alex Humesky

unread,
Jun 4, 2021, 3:30:38 PM6/4/21
to Matthew Green, bazel-dev
So it seems there are 4 cases:
1. attribute is not set
2. attribute is set to None
3. attribute is set to empty list
4. attribute is set to some non-empty list (and the elements are different from the default elements)

For 1 and 2, I'm seeing the default value being used,
for 3 I'm seeing nothing being used,
and for 4 I'm seeing the values from the given list.

Is there some difference in the test setup below? Could the dependency be coming from some other place? Maybe from some dependency further down in the target's dependencies?

== defs.bzl ====================

def _impl(ctx):
  print(ctx.attr.deps)
  return []

myrule = rule(
  implementation = _impl,
  attrs = {
    "deps": attr.label_list(default = [Label("//:dep")])
  }
)


== build ======================

load(":defs.bzl", "myrule")

myrule(
  name = "notset",
)

myrule(
  name = "none",
  deps = None,
)

myrule(
  name = "empty_list",
  deps = [],
)

myrule(
  name = "set_to_other_dep",
  deps = ["other_dep"],
)

genrule(
  name = "dep",
  outs = ["dep.out"],
  cmd = "echo dep > $@",
)

genrule(
  name = "other_dep",
  outs = ["dep2.out"],
  cmd = "echo dep2 > $@",
)


== output =================================

$ bazel query "deps(notset)" --notool_deps
//:notset
//:dep
Loading: 0 packages loaded

$ bazel query "deps(none)" --notool_deps
//:none
//:dep
Loading: 0 packages loaded

$ bazel query "deps(empty_list)" --notool_deps
//:empty_list
Loading: 0 packages loaded

$ bazel query "deps(set_to_other_dep)" --notool_deps
//:set_to_other_dep
//:other_dep
Loading: 0 packages loaded




--
You received this message because you are subscribed to the Google Groups "bazel-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-dev/956b809a-2339-47ef-9217-eccf9e83e7f8n%40googlegroups.com.

Matthew Green

unread,
Jun 4, 2021, 7:44:58 PM6/4/21
to bazel-dev
Thanks for the quick reply.

I've just run through my tests again and now I'm not hitting the problem, so it looks like it's behaving as expected.

I think I likely missed an override and was put off by the error message:

ERROR: BUILD:24:24: every rule of type my_obj implicitly depends upon the target '//deps:def', but this target could not be found because of: no such package 'deps': BUILD file not found in any of the following directories. Add a BUILD file to a directory to mark it as a package.
 - /base/hdrs


which doesn't mention overrides, but I appreciate it's pretty good and hard to list all the corner cases!

Thanks again and sorry for the false alarm.

Matt
Reply all
Reply to author
Forward
0 new messages