Skip to content

default_constraint_value should not add a constraint to toolchains #8778

@jayconrod

Description

@jayconrod

Description of the problem / feature request:

This issue came up when analyzing bazel-contrib/rules_go#2115. Two toolchains are needed to build a target: a Go toolchain, and a Docker toolchain. The target platform is @io_bazel_rules_go//go/toolchain:linux_amd64, which has the following constraints:

  • @bazel_tools//platforms:linux
  • @bazel_tools//platforms:x86_64
  • @io_bazel_rules_go//go/toolchain:cgo_off (the constraint setting is cgo_constraint in the same package)
  • @io_bazel_rules_go//go/toolchain:not_darwin (the constraint setting is darwin_constraint in the same package)

cgo_constraint and darwin_constraint have default_constraint_value set to cgo_on and is_darwin, respectively. This is so that when the default target platform is used, these values can be used in select statements. In particular, cgo_on is used to add an additional dependency on a target that requests a C/C++ toolchain.

The problem is that Bazel rejects all registered Docker toolchains for the target platform. These toolchains don't specify any constraints related to cgo_constraint or darwin_constraint, since those settings are irrelevant to Docker. It appears that because of the default_constraint_value attribute in the definition of these settings, the Docker toolchains implicitly require cgo_on and is_darwin. Because of this, Docker toolchains cannot be used:

INFO: ToolchainResolution: Looking for toolchain of type @io_bazel_rules_docker//toolchains/docker:toolchain_type...
INFO: ToolchainResolution:   Considering toolchain @docker_config//:toolchain...
INFO: ToolchainResolution:     Toolchain constraint @io_bazel_rules_go//go/toolchain:darwin_constraint has value @io_bazel_rules_go//go/toolchain:is_darwin, which does not match value @io_bazel_rules_go//go/toolchain:not_darwin from the target platform @io_bazel_rules_go//go/toolchain:linux_amd64
INFO: ToolchainResolution:     Toolchain constraint @io_bazel_rules_go//go/toolchain:cgo_constraint has value @io_bazel_rules_go//go/toolchain:cgo_on, which does not match value @io_bazel_rules_go//go/toolchain:cgo_off from the target platform @io_bazel_rules_go//go/toolchain:linux_amd64
INFO: ToolchainResolution:   Rejected toolchain @docker_config//:toolchain, because of target platform mismatch

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

This can be reproduced in a standalone example:

WORKSPACE

workspace(name = "toolchain_test")

register_toolchains(
    "//:go_toolchain_linux_amd64",
    "//:docker_toolchain_linux_amd64",
)

BUILD.bazel

load("//:def.bzl", "go_toolchain", "go_image", "docker_toolchain")

platform(
    name = "linux_amd64",
    constraint_values = [
        "@bazel_tools//platforms:linux",
        "@bazel_tools//platforms:x86_64",
        ":cgo_off",
    ],
)

constraint_setting(
    name = "cgo",
    default_constraint_value = ":cgo_on",
)

constraint_value(
    name = "cgo_on",
    constraint_setting = ":cgo",
)

constraint_value(
    name = "cgo_off",
    constraint_setting = ":cgo",
)

toolchain_type(
    name = "go_toolchain_type",
)

go_toolchain(
    name = "go_toolchain_linux_amd64_impl",
)

toolchain(
    name = "go_toolchain_linux_amd64",
    target_compatible_with = [
        "@bazel_tools//platforms:linux",
        "@bazel_tools//platforms:x86_64",
        ":cgo_off",
    ],
    toolchain = ":go_toolchain_linux_amd64_impl",
    toolchain_type = ":go_toolchain_type",
)

toolchain_type(
    name = "docker_toolchain_type",
)

docker_toolchain(
    name = "docker_toolchain_linux_amd64_impl",
)

toolchain(
    name = "docker_toolchain_linux_amd64",
    target_compatible_with = [
        "@bazel_tools//platforms:linux",
        "@bazel_tools//platforms:x86_64",
    ],
    toolchain = ":docker_toolchain_linux_amd64_impl",
    toolchain_type = ":docker_toolchain_type",
)

go_image(
    name = "x",
)

def.bzl

def _go_toolchain_impl(ctx):
    return [platform_common.ToolchainInfo()]

go_toolchain = rule(
    implementation = _go_toolchain_impl,
)

def _docker_toolchain_impl(ctx):
    return [platform_common.ToolchainInfo()]

docker_toolchain = rule(
    implementation = _docker_toolchain_impl,
)

def _go_image_impl(ctx):
    pass

go_image = rule(
    implementation = _go_image_impl,
    toolchains = [
        "//:go_toolchain_type",
        "//:docker_toolchain_type",
    ],
)

Build with:

bazel build --toolchain_resolution_debug --platforms=//:linux_amd64 //:x
INFO: Invocation ID: 5c4d2935-aadd-4816-aab5-dc3c3ad6f27d
Loading: 
Loading: 0 packages loaded
Analyzing: target //:x (1 packages loaded, 0 targets configured)
INFO: ToolchainResolution: Looking for toolchain of type //:docker_toolchain_type...
INFO: ToolchainResolution: Looking for toolchain of type //:go_toolchain_type...
INFO: ToolchainResolution:   Considering toolchain //:docker_toolchain_linux_amd64_impl...
INFO: ToolchainResolution:   Considering toolchain //:go_toolchain_linux_amd64_impl...
INFO: ToolchainResolution:     Toolchain constraint //:cgo has value //:cgo_on, which does not match value //:cgo_off from the target platform //:linux_amd64
INFO: ToolchainResolution:   Rejected toolchain //:docker_toolchain_linux_amd64_impl, because of target platform mismatch
INFO: ToolchainResolution:   For toolchain type //:go_toolchain_type, possible execution platforms and toolchains: {@bazel_tools//platforms:host_platform -> //:go_toolchain_linux_amd64_impl}
INFO: ToolchainResolution:   No toolchains found
ERROR: While resolving toolchains for target //:x: no matching toolchains found for types //:docker_toolchain_type
ERROR: Analysis of target '//:x' failed; build aborted: no matching toolchains found for types //:docker_toolchain_type
INFO: Elapsed time: 1.838s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (8 packages loaded, 45 targets configured)
FAILED: Build did NOT complete successfully (8 packages loaded, 45 targets configured)

What operating system are you running Bazel on?

macOS 10.14.5

What's the output of bazel info release?

release 0.27.1rc1

Metadata

Metadata

Assignees

Labels

P2We'll consider working on this in future. (Assignee optional)team-Configurabilityplatforms, toolchains, cquery, select(), config transitionstype: bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions