diff --git a/.bazelrc b/.bazelrc index c9bbf70ea993..8d36fa8e4f1c 100644 --- a/.bazelrc +++ b/.bazelrc @@ -56,6 +56,11 @@ build --action_env=BAZEL_VOLATILE_DIRTY --host_action_env=BAZEL_VOLATILE_DIRTY build --test_summary=terse +# Enforce explicit toolchain selection +# This flag causes the enforcement rule to run on every build, checking that +# a toolchain has been explicitly selected via --config=gcc or --config=clang +build --//tools/build_config:enforce_toolchain + # TODO(keith): Remove once these 2 are the default build --incompatible_config_setting_private_default_visibility build --incompatible_enforce_config_setting_visibility @@ -122,12 +127,14 @@ common:clang-common --action_env=CXX=clang++ --host_action_env=CXX=clang++ common:clang --config=clang-common common:clang --config=libc++ common:clang --action_env=LDFLAGS="-fuse-ld=lld" +common:clang --//tools/build_config:toolchain_identifier=clang # Use gold linker for gcc compiler. build:gcc --config=libstdc++ build:gcc --test_env=HEAPCHECK= build:gcc --action_env=BAZEL_COMPILER=gcc build:gcc --action_env=CC=gcc --action_env=CXX=g++ +build:gcc --//tools/build_config:toolchain_identifier=gcc # This is to work around a bug in GCC that makes debug-types-section # option not play well with fission: # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110885 diff --git a/tools/build_config/BUILD b/tools/build_config/BUILD new file mode 100644 index 000000000000..3c31d75142a1 --- /dev/null +++ b/tools/build_config/BUILD @@ -0,0 +1,16 @@ +load("@bazel_skylib//rules:common_settings.bzl", "string_flag") +load(":defs.bzl", "toolchain_enforcement") + +licenses(["notice"]) # Apache 2 + +string_flag( + name = "toolchain_identifier", + build_setting_default = "", + visibility = ["//visibility:public"], +) + +toolchain_enforcement( + name = "enforce_toolchain", + toolchain_identifier = ":toolchain_identifier", + visibility = ["//visibility:public"], +) diff --git a/tools/build_config/defs.bzl b/tools/build_config/defs.bzl new file mode 100644 index 000000000000..e8865e384158 --- /dev/null +++ b/tools/build_config/defs.bzl @@ -0,0 +1,57 @@ +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") + +ERR_MSG_TOOLCHAIN = """ +╔═══════════════════════════════════════════════════════════════════════════════╗ +║ C++ Toolchain Selection Required ║ +╚═══════════════════════════════════════════════════════════════════════════════╝ + +ERROR: No C++ toolchain has been selected for this build. + +Automatic C++ toolchain detection is disabled in this repository. +You must explicitly specify a toolchain using one of the following options: + + • For GCC: bazel build --config=gcc + • For Clang: bazel build --config=clang + +You can also set a default in your user.bazelrc file: + build --config=gcc + +For more information, see the Envoy developer documentation. +""" + +DOC_TOOLCHAIN = """ +Rule that enforces explicit C++ toolchain selection. + +This rule reads the toolchain_identifier build setting and fails the build +if no toolchain has been explicitly selected (i.e., the value is empty). + +This rule must be invoked as part of the build process (via +--//tools/build_config:enforce_toolchain in .bazelrc) to provide enforcement. +It does not produce any build artifacts. +""" + +def _toolchain_enforcement_impl(ctx): + """Implementation of the toolchain enforcement rule. + + This rule checks if a C++ toolchain has been explicitly selected. + If not, it fails with a helpful error message. + """ + toolchain_id = ctx.attr.toolchain_identifier[BuildSettingInfo].value + + if toolchain_id == "": + fail(ERR_MSG_TOOLCHAIN) + + # Return an empty default info provider - this rule doesn't produce any outputs + return [DefaultInfo()] + +toolchain_enforcement = rule( + implementation = _toolchain_enforcement_impl, + attrs = { + "toolchain_identifier": attr.label( + providers = [BuildSettingInfo], + mandatory = True, + doc = "The toolchain_identifier build setting to check", + ), + }, + doc = DOC_TOOLCHAIN, +)