diff --git a/cc/toolchains/features/BUILD b/cc/toolchains/features/BUILD new file mode 100644 index 0000000..c9ad527 --- /dev/null +++ b/cc/toolchains/features/BUILD @@ -0,0 +1,98 @@ +load("//cc/toolchains:feature_set.bzl", "cc_feature_set") +load("//cc/toolchains/impl:external_feature.bzl", "cc_external_feature") + +package(default_visibility = ["//visibility:public"]) + +# See https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features + +cc_external_feature( + name = "opt", + feature_name = "opt", + overridable = True, +) + +cc_external_feature( + name = "dbg", + feature_name = "dbg", + overridable = True, +) + +cc_external_feature( + name = "fastbuild", + feature_name = "fastbuild", + overridable = True, +) + +cc_external_feature( + name = "static_linking_mode", + feature_name = "static_linking_mode", + overridable = True, +) + +cc_external_feature( + name = "dynamic_linking_mode", + feature_name = "dynamic_linking_mode", + overridable = True, +) + +cc_external_feature( + name = "per_object_debug_info", + feature_name = "per_object_debug_info", + overridable = True, +) + +cc_external_feature( + name = "supports_start_end_lib", + feature_name = "supports_start_end_lib", + overridable = True, +) + +cc_external_feature( + name = "supports_interface_shared_libraries", + feature_name = "supports_interface_shared_libraries", + overridable = True, +) + +cc_external_feature( + name = "supports_dynamic_linker", + feature_name = "supports_dynamic_linker", + overridable = True, +) + +cc_external_feature( + name = "static_link_cpp_runtimes", + feature_name = "static_link_cpp_runtimes", + overridable = True, +) + +cc_external_feature( + name = "supports_pic", + feature_name = "supports_pic", + overridable = True, +) + +cc_feature_set( + name = "all_non_legacy_builtin_features", + features = [ + ":opt", + ":dbg", + ":fastbuild", + ":static_linking_mode", + ":dynamic_linking_mode", + ":per_object_debug_info", + ":supports_start_end_lib", + ":supports_interface_shared_libraries", + ":supports_dynamic_linker", + ":static_link_cpp_runtimes", + ":supports_pic", + ], + visibility = ["//visibility:private"], +) + +cc_feature_set( + name = "all_builtin_features", + features = [ + ":all_non_legacy_builtin_features", + "//cc/toolchains/features/legacy:all_legacy_builtin_features", + ], +) diff --git a/cc/toolchains/features/legacy/BUILD b/cc/toolchains/features/legacy/BUILD new file mode 100644 index 0000000..60d9613 --- /dev/null +++ b/cc/toolchains/features/legacy/BUILD @@ -0,0 +1,279 @@ +load("//cc/toolchains:feature_set.bzl", "cc_feature_set") +load("//cc/toolchains/impl:external_feature.bzl", "cc_external_feature") + +package(default_visibility = ["//visibility:public"]) + +# See https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features. + +cc_external_feature( + name = "legacy_compile_flags", + feature_name = "legacy_compile_flags", + overridable = True, +) + +cc_external_feature( + name = "default_compile_flags", + feature_name = "default_compile_flags", + overridable = True, +) + +cc_external_feature( + name = "dependency_file", + feature_name = "dependency_file", + overridable = True, +) + +cc_external_feature( + name = "pic", + feature_name = "pic", + overridable = True, +) + +cc_external_feature( + name = "preprocessor_defines", + feature_name = "preprocessor_defines", + overridable = True, +) + +cc_external_feature( + name = "includes", + feature_name = "includes", + overridable = True, +) + +cc_external_feature( + name = "include_paths", + feature_name = "include_paths", + overridable = True, +) + +cc_external_feature( + name = "fdo_instrument", + feature_name = "fdo_instrument", + overridable = True, +) + +cc_external_feature( + name = "fdo_optimize", + feature_name = "fdo_optimize", + overridable = True, +) + +cc_external_feature( + name = "cs_fdo_instrument", + feature_name = "cs_fdo_instrument", + overridable = True, +) + +cc_external_feature( + name = "cs_fdo_optimize", + feature_name = "cs_fdo_optimize", + overridable = True, +) + +cc_external_feature( + name = "fdo_prefetch_hints", + feature_name = "fdo_prefetch_hints", + overridable = True, +) + +cc_external_feature( + name = "autofdo", + feature_name = "autofdo", + overridable = True, +) + +cc_external_feature( + name = "build_interface_libraries", + feature_name = "build_interface_libraries", + overridable = True, +) + +cc_external_feature( + name = "dynamic_library_linker_tool", + feature_name = "dynamic_library_linker_tool", + overridable = True, +) + +cc_external_feature( + name = "shared_flag", + feature_name = "shared_flag", + overridable = True, +) + +cc_external_feature( + name = "linkstamps", + feature_name = "linkstamps", + overridable = True, +) + +cc_external_feature( + name = "output_execpath_flags", + feature_name = "output_execpath_flags", + overridable = True, +) + +cc_external_feature( + name = "runtime_library_search_directories", + feature_name = "runtime_library_search_directories", + overridable = True, +) + +cc_external_feature( + name = "library_search_directories", + feature_name = "library_search_directories", + overridable = True, +) + +cc_external_feature( + name = "archiver_flags", + feature_name = "archiver_flags", + overridable = True, +) + +cc_external_feature( + name = "libraries_to_link", + feature_name = "libraries_to_link", + overridable = True, +) + +cc_external_feature( + name = "force_pic_flags", + feature_name = "force_pic_flags", + overridable = True, +) + +cc_external_feature( + name = "user_link_flags", + feature_name = "user_link_flags", + overridable = True, +) + +cc_external_feature( + name = "legacy_link_flags", + feature_name = "legacy_link_flags", + overridable = True, +) + +cc_external_feature( + name = "static_libgcc", + feature_name = "static_libgcc", + overridable = True, +) + +cc_external_feature( + name = "fission_support", + feature_name = "fission_support", + overridable = True, +) + +cc_external_feature( + name = "strip_debug_symbols", + feature_name = "strip_debug_symbols", + overridable = True, +) + +cc_external_feature( + name = "coverage", + feature_name = "coverage", + overridable = True, +) + +cc_external_feature( + name = "llvm_coverage_map_format", + feature_name = "llvm_coverage_map_format", + overridable = True, +) + +cc_external_feature( + name = "gcc_coverage_map_format", + feature_name = "gcc_coverage_map_format", + overridable = True, +) + +cc_external_feature( + name = "fully_static_link", + feature_name = "fully_static_link", + overridable = True, +) + +cc_external_feature( + name = "user_compile_flags", + feature_name = "user_compile_flags", + overridable = True, +) + +cc_external_feature( + name = "sysroot", + feature_name = "sysroot", + overridable = True, +) + +cc_external_feature( + name = "unfiltered_compile_flags", + feature_name = "unfiltered_compile_flags", + overridable = True, +) + +cc_external_feature( + name = "linker_param_file", + feature_name = "linker_param_file", + overridable = True, +) + +cc_external_feature( + name = "compiler_input_flags", + feature_name = "compiler_input_flags", + overridable = True, +) + +cc_external_feature( + name = "compiler_output_flags", + feature_name = "compiler_output_flags", + overridable = True, +) + +cc_feature_set( + name = "all_legacy_builtin_features", + features = [ + ":legacy_compile_flags", + ":default_compile_flags", + ":dependency_file", + ":pic", + ":preprocessor_defines", + ":includes", + ":include_paths", + ":fdo_instrument", + ":fdo_optimize", + ":cs_fdo_instrument", + ":cs_fdo_optimize", + ":fdo_prefetch_hints", + ":autofdo", + ":build_interface_libraries", + ":dynamic_library_linker_tool", + ":shared_flag", + ":linkstamps", + ":output_execpath_flags", + ":runtime_library_search_directories", + ":library_search_directories", + ":archiver_flags", + ":libraries_to_link", + ":force_pic_flags", + ":user_link_flags", + ":legacy_link_flags", + ":static_libgcc", + ":fission_support", + ":strip_debug_symbols", + ":coverage", + ":llvm_coverage_map_format", + ":gcc_coverage_map_format", + ":fully_static_link", + ":user_compile_flags", + ":sysroot", + ":unfiltered_compile_flags", + ":linker_param_file", + ":compiler_input_flags", + ":compiler_output_flags", + ], + visibility = ["//cc/toolchains/features:__pkg__"], +) diff --git a/cc/toolchains/impl/external_feature.bzl b/cc/toolchains/impl/external_feature.bzl new file mode 100644 index 0000000..0853b32 --- /dev/null +++ b/cc/toolchains/impl/external_feature.bzl @@ -0,0 +1,72 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Implementation of the cc_external_feature rule.""" + +load( + "//cc/toolchains:cc_toolchain_info.bzl", + "ArgsListInfo", + "FeatureConstraintInfo", + "FeatureInfo", + "FeatureSetInfo", +) + +visibility([ + "//cc/toolchains/...", + "//tests/rule_based_toolchain/...", +]) + +def _cc_external_feature_impl(ctx): + feature = FeatureInfo( + label = ctx.label, + name = ctx.attr.feature_name, + enabled = False, + args = ArgsListInfo( + label = ctx.label, + args = (), + files = depset([]), + by_action = (), + ), + implies = depset([]), + requires_any_of = (), + mutually_exclusive = (), + external = True, + overridable = ctx.attr.overridable, + overrides = None, + ) + providers = [ + feature, + FeatureSetInfo(label = ctx.label, features = depset([feature])), + FeatureConstraintInfo( + label = ctx.label, + all_of = depset([feature]), + none_of = depset([]), + ), + ] + return providers + +cc_external_feature = rule( + implementation = _cc_external_feature_impl, + attrs = { + "feature_name": attr.string( + mandatory = True, + doc = "The name of the feature", + ), + "overridable": attr.bool( + doc = "Whether the feature can be overridden", + mandatory = True, + ), + }, + provides = [FeatureInfo, FeatureSetInfo, FeatureConstraintInfo], + doc = "A declaration that a feature with this name is defined elsewhere.", +) diff --git a/tests/rule_based_toolchain/features/BUILD b/tests/rule_based_toolchain/features/BUILD index 701d478..2d0dce7 100644 --- a/tests/rule_based_toolchain/features/BUILD +++ b/tests/rule_based_toolchain/features/BUILD @@ -3,6 +3,7 @@ load("//cc/toolchains:args.bzl", "cc_args") load("//cc/toolchains:feature.bzl", "cc_feature") load("//cc/toolchains:feature_constraint.bzl", "cc_feature_constraint") load("//cc/toolchains:feature_set.bzl", "cc_feature_set") +load("//cc/toolchains/impl:external_feature.bzl", "cc_external_feature") load("//tests/rule_based_toolchain:analysis_test_suite.bzl", "analysis_test_suite") load(":features_test.bzl", "TARGETS", "TESTS") @@ -84,6 +85,21 @@ util.helper_target( none_of = [":implies"], ) +util.helper_target( + cc_external_feature, + name = "builtin_feature", + feature_name = "builtin_feature", + overridable = True, +) + +util.helper_target( + cc_feature, + name = "overrides", + args = [":c_compile"], + enabled = True, + overrides = ":builtin_feature", +) + analysis_test_suite( name = "test_suite", targets = TARGETS, diff --git a/tests/rule_based_toolchain/features/features_test.bzl b/tests/rule_based_toolchain/features/features_test.bzl index b6a7db6..3406bdd 100644 --- a/tests/rule_based_toolchain/features/features_test.bzl +++ b/tests/rule_based_toolchain/features/features_test.bzl @@ -93,6 +93,16 @@ def _feature_constraint_collects_transitive_features_test(env, targets): targets.implies.label, ]) +def _external_feature_is_a_feature_test(env, targets): + env.expect.that_target(targets.builtin_feature).provider( + FeatureInfo, + ).name().equals("builtin_feature") + +def _feature_can_be_overridden_test(env, targets): + overrides = env.expect.that_target(targets.overrides).provider(FeatureInfo) + overrides.name().equals("builtin_feature") + overrides.overrides().some().label().equals(targets.builtin_feature.label) + TARGETS = [ ":c_compile", ":simple", @@ -103,6 +113,8 @@ TARGETS = [ ":mutual_exclusion_feature", ":direct_constraint", ":transitive_constraint", + ":builtin_feature", + ":overrides", ] # @unsorted-dict-items @@ -114,4 +126,6 @@ TESTS = { "feature_set_collects_features_test": _feature_set_collects_features_test, "feature_constraint_collects_direct_features_test": _feature_constraint_collects_direct_features_test, "feature_constraint_collects_transitive_features_test": _feature_constraint_collects_transitive_features_test, + "external_feature_is_a_feature_test": _external_feature_is_a_feature_test, + "feature_can_be_overridden_test": _feature_can_be_overridden_test, }