bazelbuild / bazelbuild/bazel-skylib
Unexpected visibility limitations with config_setting visibility
- Dominant language
- Starlark
- Stars
- 444
- Forks
- 202
- PR merge metrics
- No merged PRs in 30d
Description
As of https://github.com/bazelbuild/bazel/issues/12932, using `selects.config_setting_group` produces unexpected results because of how it uses an underlying alias to surface the settings. For example if you have:
```bzl
load("@bazel_skylib//lib:selects.bzl", "selects")
config_setting(
name = "dbg_build",
values = {"compilation_mode": "dbg"},
visibility = ["//visibility:public"],
)
config_setting(
name = "some_define",
values = {"define": "some_define=true"},
visibility = ["//visibility:private"],
)
selects.config_setting_group(
name = "public_setting",
match_any = [
":dbg_build",
":some_define",
],
visibility = ["//visibility:public"],
)
```
And from another package you depend on this with:
```bzl
cc_library(
name = "foo",
srcs = ["foo.cc"] + select({
"//:public_setting": [],
"//conditions:default": [],
}),
)
```
You see this error:
```
ERROR: /private/tmp/config_setting_repro/package/BUILD:1:11: in cc_library rule //package:foo: target '//:some_define' is not visible from target '//package:foo'. Check the visibility declaration of the former target if you think the dependency is legitimate
ERROR: /private/tmp/config_setting_repro/package/BUILD:1:11: Analysis of target '//package:foo' failed
ERROR: Analysis of target '//package:foo' failed; build aborted:
INFO: Elapsed time: 0.059s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded, 3 targets configured)
```
The macro generates:
```bzl
# /private/tmp/config_setting_repro/BUILD:3:15
config_setting(
name = "dbg_build",
values = {"compilation_mode": "dbg"},
visibility = ["//visibility:public"],
)
# Rule dbg_build instantiated at (most recent call last):
# /private/tmp/config_setting_repro/BUILD:3:15 in
# /private/tmp/config_setting_repro/BUILD:15:29
alias(
name = "public_setting",
actual = select({
"//:dbg_build": "//:dbg_build",
"//conditions:default": "//:some_define",
}),
generator_function = "_config_setting_group",
generator_location = "/private/tmp/config_setting_repro/BUILD:15:29",
generator_name = "public_setting",
visibility = ["//visibility:public"],
)
# Rule public_setting instantiated at (most recent call last):
# /private/tmp/config_setting_repro/BUILD:15:29 in
# /private/var/tmp/_bazel_ksmiley/e6a33c534f9680bff2cf4f056c41ed7e/external/bazel_skylib/lib/selects.bzl:125:33 in _config_setting_group
# /private/var/tmp/_bazel_ksmiley/e6a33c534f9680bff2cf4f056c41ed7e/external/bazel_skylib/lib/selects.bzl:178:21 in _config_setting_or_group
# /private/tmp/config_setting_repro/BUILD:9:15
config_setting(
name = "some_define",
values = {"define": "some_define=true"},
visibility = ["//visibility:private"],
)
# Rule some_define instantiated at (most recent call last):
# /private/tmp/config_setting_repro/BUILD:9:15 in
```
So this makes sense, since aliases propagate visibility, but I think it's a bit unexpected in this case. Maybe there's another solution to how this could be written to allow having private settings.
Contributor guide
Research direction
Reproduce the visibility error from the BUILD-file example, then read selects.bzl around _config_setting_group and _config_setting_or_group at the reported lines 125 and 178. Trace how the generated alias and its selected targets are checked across packages. Done means the reported configuration behaves as intended without incorrectly exposing or rejecting private settings, with coverage for the reproduction.
Written by the indexing model from the issue text.
Assessment
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100