bazelbuild / bazelbuild/bazel-skylib

Unexpected visibility limitations with config_setting visibility

Open
#404 5 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.