Skip to content

Unexpected visibility limitations with config_setting visibility #404

@keith

Description

@keith

As of bazelbuild/bazel#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:

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:

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:

# /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 <toplevel>

# /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 <toplevel>
#   /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 <toplevel>

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions