Make feature names constants.

Armando mentioned something that made me think of this again; I'm still not sure if this is worth implementing (every new feature will require editing a widely-loaded constants file). We might as well discuss this to see if it's worth it.

b/339328480 suggests implementing something to ensure that a string constant can't be passed directly. I'm unsure if that's a good idea (we could add a wrapper around is_enabled that checks this)

TODO: feature names in errors, feature names looked up in other data structures, cc_helper_internal (pending a refactor of that file to deal with loading issues).

Startblock:
  * // Put other blockers before this line to avoid churning.
  * has lgtm
  * is approved
  * and then
  * all comments are resolved
  * and then
  *[] allows unknown commit
PiperOrigin-RevId: 981490892
Change-Id: Ic97c46d4ef6f1d2c68168bbeb270484c2be686a9
diff --git a/cc/common/BUILD b/cc/common/BUILD
index 2cc8af4..97755ad 100644
--- a/cc/common/BUILD
+++ b/cc/common/BUILD
@@ -38,6 +38,7 @@
     ],
     visibility = ["//visibility:public"],
     deps = [
+        ":feature_names_bzl",
         "//cc/private:cc_internal_bzl",
         "//cc/private:paths_bzl",
         "//cc/private/rules_impl:native_cc_common_bzl",
@@ -131,3 +132,9 @@
         "cc_shared_library_info.bzl",
     ],
 )]
+
+bzl_library(
+    name = "feature_names_bzl",
+    srcs = ["feature_names.bzl"],
+    visibility = ["//visibility:public"],
+)
diff --git a/cc/common/cc_helper.bzl b/cc/common/cc_helper.bzl
index 303188d..c849c6c 100644
--- a/cc/common/cc_helper.bzl
+++ b/cc/common/cc_helper.bzl
@@ -15,6 +15,7 @@
 
 load("//cc:action_names.bzl", "ACTION_NAMES")
 load("//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_TYPE")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:paths.bzl", "is_path_absolute")
 load("//cc/private/rules_impl:objc_common.bzl", "objc_common")
 load(":cc_common.bzl", "cc_common")
@@ -286,7 +287,7 @@
 
 def _dll_hash_suffix(ctx, feature_configuration, cpp_config):
     if cpp_config.dynamic_mode() != "OFF":
-        if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows"):
+        if feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS):
             if not hasattr(ctx.attr, "win_def_file") or ctx.file.win_def_file == None:
                 # Note: ctx.label.workspace_name strips leading @,
                 # which is different from the native behavior.
@@ -407,8 +408,8 @@
         return _gen_empty_def_file(ctx)
 
 def _should_generate_def_file(ctx, feature_configuration):
-    windows_export_all_symbols_enabled = cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "windows_export_all_symbols")
-    no_windows_export_all_symbols_enabled = cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "no_windows_export_all_symbols")
+    windows_export_all_symbols_enabled = feature_configuration.is_enabled(feature_names.WINDOWS_EXPORT_ALL_SYMBOLS)
+    no_windows_export_all_symbols_enabled = feature_configuration.is_enabled(feature_names.NO_WINDOWS_EXPORT_ALL_SYMBOLS)
     return windows_export_all_symbols_enabled and (not no_windows_export_all_symbols_enabled) and (ctx.attr.win_def_file == None)
 
 def _generate_def_file(ctx, def_parser, object_files, dll_name, cc_toolchain, feature_configuration):
@@ -573,7 +574,7 @@
     return linker_inputs
 
 def _create_strip_action(ctx, cc_toolchain, cpp_config, input, output, feature_configuration):
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "no_stripping"):
+    if feature_configuration.is_enabled(feature_names.NO_STRIPPING):
         ctx.actions.symlink(
             output = output,
             target_file = input,
@@ -813,7 +814,7 @@
     return ctx.fragments.cpp.force_pic() or (
         cc_toolchain.needs_pic_for_dynamic_libraries(feature_configuration = feature_configuration) and (
             ctx.var["COMPILATION_MODE"] != "opt" or
-            cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "prefer_pic_for_opt_binaries")
+            feature_configuration.is_enabled(feature_names.PREFER_PIC_FOR_OPT_BINARIES)
         )
     )
 
@@ -885,11 +886,10 @@
         return
     if not ctx.fragments.cpp.experimental_cpp_modules():
         fail("requires --experimental_cpp_modules", attr = "module_interfaces")
-    if not cc_common.is_enabled(
-        feature_configuration = feature_configuration,
-        feature_name = "cpp_modules",
+    if not feature_configuration.is_enabled(
+        feature_names.CPP_MODULES,
     ):
-        fail("to use C++ modules, the feature cpp_modules must be enabled")
+        fail("to use C++ modules, the feature {} must be enabled".format(feature_names.CPP_MODULES))
 
 def _expand_make_variables_for_copts(ctx, tokenization, unexpanded_tokens, additional_make_variable_substitutions):
     tokens = []
@@ -982,7 +982,7 @@
 
     # If we wanted to include command-line specified flags, we could add
     # ctx.fragments.cpp.copts (and cxxopts/conlyopts) here.
-    tokenization = not (cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "no_copts_tokenization") or "no_copts_tokenization" in requested_features)
+    tokenization = not (feature_configuration.is_enabled(feature_names.NO_COPTS_TOKENIZATION) or feature_names.NO_COPTS_TOKENIZATION in requested_features)
     expanded_attribute_copts = _expand_make_variables_for_copts(ctx, tokenization, attribute_copts, additional_make_variable_substitutions)
 
     _verify_no_disallowed_copts(
diff --git a/cc/common/feature_names.bzl b/cc/common/feature_names.bzl
new file mode 100644
index 0000000..f27e069
--- /dev/null
+++ b/cc/common/feature_names.bzl
@@ -0,0 +1,81 @@
+"""Names of features used in rules_cc starlark code."""
+
+feature_names = struct(
+    ARCHIVE_PARAM_FILE = "archive_param_file",
+    AUTOFDO = "autofdo",
+    CLANG_TRACE = "clang_trace",
+    COMPILE_ALL_MODULES = "compile_all_modules",
+    COPY_DYNAMIC_LIBRARIES_TO_BINARY = "copy_dynamic_libraries_to_binary",
+    COVERAGE = "coverage",
+    CPP_LINK_PATH_MAPPING = "cpp_link_path_mapping",
+    CPP_MODULES = "cpp_modules",
+    CS_FDO_INSTRUMENT = "cs_fdo_instrument",
+    CS_FDO_OPTIMIZE = "cs_fdo_optimize",
+    DEAD_STRIP = "dead_strip",
+    DISABLE_WHOLE_ARCHIVE_FOR_STATIC_LIB = "disable_whole_archive_for_static_lib",
+    DISABLE_CPP_LINK_PATH_MAPPING = "disable_cpp_link_path_mapping",
+    ENABLE_AFDO_THINLTO = "enable_afdo_thinlto",
+    ENABLE_AUTOFDO_MEMPROF_OPTIMIZE = "enable_autofdo_memprof_optimize",
+    ENABLE_FDO_MEMPROF_OPTIMIZE = "enable_fdo_memprof_optimize",
+    ENABLE_FDO_SPLIT_FUNCTIONS = "enable_fdo_split_functions",
+    ENABLE_FDO_THINLTO = "enable_fdo_thinlto",
+    ENABLE_FSAFDO = "enable_fsafdo",
+    ENABLE_XBINARYFDO_THINLTO = "enable_xbinaryfdo_thinlto",
+    EXCLUDE_PRIVATE_HEADERS_IN_MODULE_MAPS = "exclude_private_headers_in_module_maps",
+    EXTERNAL_INCLUDE_PATHS = "external_include_paths",
+    FDO_INSTRUMENT = "fdo_instrument",
+    FDO_OPTIMIZE = "fdo_optimize",
+    FDO_PREFETCH_HINTS = "fdo_prefetch_hints",
+    FSAFDO = "fsafdo",
+    FORCE_NO_WHOLE_ARCHIVE = "force_no_whole_archive",
+    GCC_QUOTING_FOR_PARAM_FILES = "gcc_quoting_for_param_files",
+    GENERATE_DSYM_FILE = "generate_dsym_file",
+    GENERATE_LINKMAP = "generate_linkmap",
+    GENERATE_MODULE_MAP = "generate_module_map",
+    GENERATE_PDB_FILE = "generate_pdb_file",
+    GENERATE_SUBMODULES = "generate_submodules",
+    HAS_CONFIGURED_LINKER_PATH = "has_configured_linker_path",
+    HEADER_MODULE_CODEGEN = "header_module_codegen",
+    HEADER_MODULES = "header_modules",
+    MEMPROF_OPTIMIZE = "memprof_optimize",
+    MODULE_MAP_HOME_CWD = "module_map_home_cwd",
+    MODULE_MAP_WITHOUT_EXTERN_MODULE = "module_map_without_extern_module",
+    MODULE_MAPS = "module_maps",
+    NO_COPTS_TOKENIZATION = "no_copts_tokenization",
+    NO_DOTD_FILE = "no_dotd_file",
+    NO_GENERATE_DEBUG_SYMBOLS = "no_generate_debug_symbols",
+    NO_STRIPPING = "no_stripping",
+    NO_USE_LTO_INDEXING_BITCODE_FILE = "no_use_lto_indexing_bitcode_file",
+    NO_WINDOWS_EXPORT_ALL_SYMBOLS = "no_windows_export_all_symbols",
+    ONLY_DOTH_HEADERS_IN_MODULE_MAPS = "only_doth_headers_in_module_maps",
+    PARSE_HEADERS = "parse_headers",
+    PARSE_SHOWINCLUDES = "parse_showincludes",
+    PER_OBJECT_DEBUG_INFO = "per_object_debug_info",
+    PIC = "pic",
+    PREFER_PIC_FOR_OPT_BINARIES = "prefer_pic_for_opt_binaries",
+    PROPELLER_OPTIMIZE = "propeller_optimize",
+    PROPELLER_OPTIMIZE_THINLTO_COMPILE_ACTIONS = "propeller_optimize_thinlto_compile_actions",
+    SANITIZE_PWD = "sanitize_pwd",
+    SERIALIZED_DIAGNOSTICS_FILE = "serialized_diagnostics_file",
+    SET_SONAME = "set_soname",
+    SHORTEN_VIRTUAL_INCLUDES = "shorten_virtual_includes",
+    SKIP_VIRTUAL_INCLUDES = "skip_virtual_includes",
+    SPLIT_FUNCTIONS = "split_functions",
+    STATIC_LINK_CPP_RUNTIMES = "static_link_cpp_runtimes",
+    SUPPORTS_DYNAMIC_LINKER = "supports_dynamic_linker",
+    SUPPORTS_INTERFACE_SHARED_LIBRARIES = "supports_interface_shared_libraries",
+    SUPPORTS_PIC = "supports_pic",
+    SUPPORTS_START_END_LIB = "supports_start_end_lib",
+    SYMBOL_CHECK = "symbol_check",
+    TARGETS_WINDOWS = "targets_windows",
+    THIN_LTO = "thin_lto",
+    THIN_LTO_ALL_LINKSTATIC_USE_SHARED_NONLTO_BACKENDS = "thin_lto_all_linkstatic_use_shared_nonlto_backends",
+    THIN_LTO_LINKSTATIC_TESTS_USE_SHARED_NONLTO_BACKENDS = "thin_lto_linkstatic_tests_use_shared_nonlto_backends",
+    USE_HEADER_MODULES = "use_header_modules",
+    USE_LTO_NATIVE_OBJECT_DIRECTORY = "use_lto_native_object_directory",
+    VALIDATES_LAYERING_CHECK_IN_TEXTUAL_HDRS = "validates_layering_check_in_textual_hdrs",
+    WARN_BACKREFS_DEFINED = "warn_backrefs_defined",
+    WINDOWS_EXPORT_ALL_SYMBOLS = "windows_export_all_symbols",
+    WINDOWS_QUOTING_FOR_PARAM_FILES = "windows_quoting_for_param_files",
+    XBINARYFDO = "xbinaryfdo",
+)
diff --git a/cc/private/compile/BUILD b/cc/private/compile/BUILD
index 0ec49c7..fd55a2e 100644
--- a/cc/private/compile/BUILD
+++ b/cc/private/compile/BUILD
@@ -20,6 +20,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//cc:action_names_bzl",
+        "//cc/common:feature_names_bzl",
         "//cc/common:semantics_bzl",
         "//cc/private:cc_internal_bzl",
         "//cc/private/rules_impl:native_cc_common_bzl",
diff --git a/cc/private/compile/cc_compilation_helper.bzl b/cc/private/compile/cc_compilation_helper.bzl
index 5dc19cc..25e5734 100644
--- a/cc/private/compile/cc_compilation_helper.bzl
+++ b/cc/private/compile/cc_compilation_helper.bzl
@@ -20,6 +20,7 @@
     "package_source_root",
     "repository_exec_path",
 )
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", "STRIP_INCLUDE_PREFIX_APPLIES_TO_TEXTUAL_HEADERS", "USE_EXEC_ROOT_FOR_VIRTUAL_INCLUDES_SYMLINKS")
 load("//cc/private:cc_info.bzl", "create_compilation_context", "create_module_map", "get_module_map_name", "module_map_name_for_label")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
@@ -48,9 +49,6 @@
 
     return relative_path
 
-def _enabled(feature_configuration, feature_name):
-    return feature_configuration.is_enabled(feature_name)
-
 def _compute_public_headers(
         actions,
         config,
@@ -200,7 +198,7 @@
     )
 
 def _generates_header_module(feature_configuration, public_headers, private_headers, generate_action):
-    return _enabled(feature_configuration, "header_modules") and \
+    return feature_configuration.is_enabled(feature_names.HEADER_MODULES) and \
            (public_headers or private_headers) and \
            generate_action
 
@@ -458,9 +456,9 @@
     gen_include_dir = _include_dir(genfiles_dir, repo_path, sibling_repo_layout)
     bin_include_dir = _include_dir(binfiles_dir, repo_path, sibling_repo_layout)
     quote_include_dirs_for_context = [repo_path, gen_include_dir, bin_include_dir] + quote_include_dirs
-    external = repo_name != "" and _enabled(feature_configuration, "external_include_paths")
-    shorten_virtual_includes = _enabled(feature_configuration, "shorten_virtual_includes")
-    skip_virtual_includes = _enabled(feature_configuration, "skip_virtual_includes")
+    external = repo_name != "" and feature_configuration.is_enabled(feature_names.EXTERNAL_INCLUDE_PATHS)
+    shorten_virtual_includes = feature_configuration.is_enabled(feature_names.SHORTEN_VIRTUAL_INCLUDES)
+    skip_virtual_includes = feature_configuration.is_enabled(feature_names.SKIP_VIRTUAL_INCLUDES)
     external_include_dirs = []
     declared_include_srcs = []
 
@@ -542,7 +540,7 @@
     generates_pic_header_module = _generates_header_module(feature_configuration, public_headers_artifacts, private_headers_artifacts, generate_pic_action)
     generates_no_pic_header_module = _generates_header_module(feature_configuration, public_headers_artifacts, private_headers_artifacts, generate_no_pic_action)
     if separate_module_headers:
-        if not (_enabled(feature_configuration, "module_maps") and
+        if not (feature_configuration.is_enabled(feature_names.MODULE_MAPS) and
                 generate_module_map and
                 (generates_pic_header_module or generates_no_pic_header_module)):
             fail("Should use separate headers only when building modules: " + label.name)
@@ -565,7 +563,7 @@
     separate_pic_module = None
     pic_header_module = None
     header_module = None
-    if _enabled(feature_configuration, "module_maps"):
+    if feature_configuration.is_enabled(feature_names.MODULE_MAPS):
         if not module_map:
             file = actions.declare_file(label.name + ".cppmap")
 
@@ -582,10 +580,10 @@
         # 2. We create the module map so that libraries depending on us will include the headers
         #    textually (compiled is false).
         if generate_module_map:
-            compiled = _enabled(feature_configuration, "header_modules") or \
-                       _enabled(feature_configuration, "compile_all_modules")
+            compiled = feature_configuration.is_enabled(feature_names.HEADER_MODULES) or \
+                       feature_configuration.is_enabled(feature_names.COMPILE_ALL_MODULES)
 
-            if _enabled(feature_configuration, "only_doth_headers_in_module_maps"):
+            if feature_configuration.is_enabled(feature_names.ONLY_DOTH_HEADERS_IN_MODULE_MAPS):
                 public_headers_for_module_map_action = [header for header in public_headers.module_map_headers if (header.is_directory or header.extension == "h")]
                 textual_headers_for_module_map_action = [header for header in textual_headers.module_map_headers if (header.is_directory or header.extension == "h")]
             else:
@@ -593,7 +591,7 @@
                 textual_headers_for_module_map_action = textual_headers.module_map_headers
 
             private_headers_for_module_map_action = private_headers_artifacts
-            if _enabled(feature_configuration, "exclude_private_headers_in_module_maps"):
+            if feature_configuration.is_enabled(feature_names.EXCLUDE_PRIVATE_HEADERS_IN_MODULE_MAPS):
                 private_headers_for_module_map_action = []
             dependency_module_maps = _collect_module_maps(deps + implementation_deps, cc_toolchain_compilation_context, additional_cpp_module_maps)
             _create_module_map_action(
@@ -607,9 +605,9 @@
                 private_headers = private_headers_for_module_map_action,
                 additional_exported_headers = additional_exported_headers,
                 compiled_module = compiled,
-                module_map_home_is_cwd = _enabled(feature_configuration, "module_map_home_cwd"),
-                generate_submodules = _enabled(feature_configuration, "generate_submodules"),
-                extern_dependencies = not _enabled(feature_configuration, "module_map_without_extern_module"),
+                module_map_home_is_cwd = feature_configuration.is_enabled(feature_names.MODULE_MAP_HOME_CWD),
+                generate_submodules = feature_configuration.is_enabled(feature_names.GENERATE_SUBMODULES),
+                extern_dependencies = not feature_configuration.is_enabled(feature_names.MODULE_MAP_WITHOUT_EXTERN_MODULE),
             )
 
         if generates_pic_header_module:
@@ -720,13 +718,13 @@
         enabled_in_config = cpp_configuration.objc_should_generate_dotd_files()
     return (
         enabled_in_config and
-        not feature_configuration.is_enabled("parse_showincludes") and
-        not feature_configuration.is_enabled("no_dotd_file")
+        not feature_configuration.is_enabled(feature_names.PARSE_SHOWINCLUDES) and
+        not feature_configuration.is_enabled(feature_names.NO_DOTD_FILE)
     )
 
 # buildifier: disable=function-docstring
 def serialized_diagnostics_file_enabled(feature_configuration):
-    return feature_configuration.is_enabled("serialized_diagnostics_file")
+    return feature_configuration.is_enabled(feature_names.SERIALIZED_DIAGNOSTICS_FILE)
 
 cc_compilation_helper = struct(
     init_cc_compilation_context = _init_cc_compilation_context,
diff --git a/cc/private/compile/compile.bzl b/cc/private/compile/compile.bzl
index 5ea1727..37c6f6e 100644
--- a/cc/private/compile/compile.bzl
+++ b/cc/private/compile/compile.bzl
@@ -30,6 +30,7 @@
     _use_pic_for_dynamic_libs = "use_pic_for_dynamic_libs",
     artifact_category = "artifact_category_names",
 )
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", _starlark_cc_semantics = "semantics")
 load(
     "//cc/private:cc_info.bzl",
@@ -244,8 +245,8 @@
     if not generate_pic_action and not generate_no_pic_action:
         fail("Either PIC or no PIC actions have to be created.")
 
-    if module_interfaces and not feature_configuration.is_enabled("cpp_modules"):
-        fail("to use C++20 Modules, the feature cpp_modules must be enabled")
+    if module_interfaces and not feature_configuration.is_enabled(feature_names.CPP_MODULES):
+        fail("to use C++20 Modules, the feature {} must be enabled".format(feature_names.CPP_MODULES))
 
     language_normalized = "c++" if language == None else language
     language_normalized = language_normalized.replace("+", "p").upper()
@@ -257,8 +258,8 @@
 
     compilation_unit_sources = {}
     module_interfaces_sources = {}
-    if (feature_configuration.is_enabled("parse_headers") and
-        not feature_configuration.is_enabled("header_modules")):
+    if (feature_configuration.is_enabled(feature_names.PARSE_HEADERS) and
+        not feature_configuration.is_enabled(feature_names.HEADER_MODULES)):
         public_hdrs_with_labels = _to_file_label_tuple_list(public_hdrs, label)
         _add_suitable_headers_to_compilation_unit_sources(
             compilation_unit_sources,
@@ -321,7 +322,7 @@
         fail("Compilation context for implementation deps was not created")
     cc_compilation_context = implementation_deps_context if implementation_compilation_contexts else public_compilation_context
 
-    if feature_configuration.is_enabled("header_modules") and not public_compilation_context._module_map:
+    if feature_configuration.is_enabled(feature_names.HEADER_MODULES) and not public_compilation_context._module_map:
         fail("All cc rules must support module maps.")
 
     common_compile_build_variables = setup_common_compile_build_variables(
@@ -395,7 +396,7 @@
         objects = compilation_outputs_dict["lto_compilation_context"],
     )
     compilation_outputs = create_compilation_outputs_internal(**compilation_outputs_dict)
-    if feature_configuration.is_enabled("cpp_modules"):
+    if feature_configuration.is_enabled(feature_names.CPP_MODULES):
         public_compilation_context = create_cc_compilation_context_with_cpp20_modules(
             cc_compilation_context = public_compilation_context,
             cpp_module_files = compilation_outputs.cpp_module_files,
@@ -504,7 +505,7 @@
         public_headers):
     """Returns whether we want to provide header modules for the current target."""
     return (
-        feature_configuration.is_enabled("header_modules") and
+        feature_configuration.is_enabled(feature_names.HEADER_MODULES) and
         (private_headers or public_headers)
     )
 
@@ -779,7 +780,8 @@
         source_artifact = cpp_source.file
         output_name = output_name_map[source_artifact]
         source_label = cpp_source.label
-        bitcode_output = feature_configuration.is_enabled("thin_lto") and (("." + source_artifact.extension) in LTO_SOURCE_EXTENSIONS)
+        bitcode_output = feature_configuration.is_enabled(feature_names.THIN_LTO) and (("." + source_artifact.extension) in LTO_SOURCE_EXTENSIONS)
+
         module_file = source_to_module_file_map[source_artifact]
         if use_pic:
             output_name_base = _cc_internal.get_artifact_name_for_category(
@@ -874,7 +876,7 @@
         source_artifact = cpp_source.file
         output_name = output_name_map[source_artifact]
         source_label = cpp_source.label
-        bitcode_output = feature_configuration.is_enabled("thin_lto") and (("." + source_artifact.extension) in LTO_SOURCE_EXTENSIONS)
+        bitcode_output = feature_configuration.is_enabled(feature_names.THIN_LTO) and (("." + source_artifact.extension) in LTO_SOURCE_EXTENSIONS)
 
         if use_pic:
             output_name_base = _cc_internal.get_artifact_name_for_category(
@@ -1121,14 +1123,14 @@
     file. It takes into account coverage, and PIC, in addition to using the settings specified on
     the current object. This method should only be called once.
     """
-    if generate_pic_action and not feature_configuration.is_enabled("pic") and not feature_configuration.is_enabled("supports_pic"):
+    if generate_pic_action and not feature_configuration.is_enabled(feature_names.PIC) and not feature_configuration.is_enabled(feature_names.SUPPORTS_PIC):
         fail("PIC compilation is requested but the toolchain does not support it " +
-             "(feature named 'supports_pic' is not enabled)")
+             "(feature named '{}' is not enabled)".format(feature_names.SUPPORTS_PIC))
 
     enable_dotd_files = dotd_files_enabled(language, action_construction_context.fragments.cpp, feature_configuration)
 
     # If C++20 modules are enabled, delegate to the module-aware implementation and return early.
-    if feature_configuration.is_enabled("cpp_modules"):
+    if feature_configuration.is_enabled(feature_names.CPP_MODULES):
         _create_cc_compile_actions_with_cpp20_module(
             actions = actions,
             action_construction_context = action_construction_context,
@@ -1217,7 +1219,7 @@
                 progress_message_prefix = progress_message_prefix,
             )
             modules = modules + separate_modules
-        if feature_configuration.is_enabled("header_module_codegen"):
+        if feature_configuration.is_enabled(feature_names.HEADER_MODULE_CODEGEN):
             for module in modules:
                 _create_module_codegen_action(
                     action_construction_context = action_construction_context,
@@ -1254,7 +1256,7 @@
             continue
 
         output_name = output_name_map[source_file]
-        bitcode_output = feature_configuration.is_enabled("thin_lto") and (("." + source_file.extension) in LTO_SOURCE_EXTENSIONS)
+        bitcode_output = feature_configuration.is_enabled(feature_names.THIN_LTO) and (("." + source_file.extension) in LTO_SOURCE_EXTENSIONS)
 
         if not _cc_internal.is_tree_artifact(source_file):
             compiled_basenames.add(_basename_without_extension(source_file))
@@ -1320,7 +1322,7 @@
         source_label = cpp_source.label
         if source_type != CPP_SOURCE_TYPE_HEADER or _cc_internal.is_tree_artifact(source_file):
             continue
-        if (feature_configuration.is_enabled("validates_layering_check_in_textual_hdrs") and
+        if (feature_configuration.is_enabled(feature_names.VALIDATES_LAYERING_CHECK_IN_TEXTUAL_HDRS) and
             _basename_without_extension(source_file) in compiled_basenames):
             continue
 
@@ -1605,7 +1607,7 @@
     _is_assembly = "." + source_artifact.extension in (extensions.ASSEMBLER + extensions.ASSEMBLER_WITH_C_PREPROCESSOR)
     trace_file = _maybe_declare_trace_file(
         ctx = action_construction_context,
-        enable_trace = feature_configuration.is_enabled("clang_trace") and not _is_assembly,
+        enable_trace = feature_configuration.is_enabled(feature_names.CLANG_TRACE) and not _is_assembly,
         object_file = object_file,
     )
 
@@ -1620,7 +1622,7 @@
         )
 
     lto_indexing_file = None
-    if bitcode_output and not feature_configuration.is_enabled("no_use_lto_indexing_bitcode_file"):
+    if bitcode_output and not feature_configuration.is_enabled(feature_names.NO_USE_LTO_INDEXING_BITCODE_FILE):
         lto_indexing_file_name = paths.replace_extension(
             paths.basename(object_file.path),
             extensions.LTO_INDEXING_OBJECT_FILE[0],
@@ -1979,12 +1981,12 @@
             ),
         )
 
-    bitcode_output = (feature_configuration.is_enabled("thin_lto") and
+    bitcode_output = (feature_configuration.is_enabled(feature_names.THIN_LTO) and
                       paths.split_extension(module.basename)[-1] in LTO_SOURCE_EXTENSIONS)
 
     # TODO(tejohnson): Add support for ThinLTO if needed.
     if bitcode_output:
-        fail("bitcode output not currently supported for feature header_module_codegen")
+        fail("bitcode output not currently supported for feature {}".format(feature_names.HEADER_MODULE_CODEGEN))
 
     complete_copts = get_copts(
         language = language,
@@ -2022,7 +2024,7 @@
         )
 
     diagnostics_file = None
-    if feature_configuration.is_enabled("serialized_diagnostics_file"):
+    if feature_configuration.is_enabled(feature_names.SERIALIZED_DIAGNOSTICS_FILE):
         diagnostics_file = _get_compile_output_file(
             ctx = action_construction_context,
             label = label,
@@ -2175,7 +2177,7 @@
     extension = "." + source_file.extension if source_file.extension else ""
     header_discover_required = extension not in (extensions.ASSEMBLER + extensions.CPP_MODULE)
     use_header_modules = (
-        feature_configuration.is_enabled("use_header_modules") and
+        feature_configuration.is_enabled(feature_names.USE_HEADER_MODULES) and
         extension in extensions.CC_SOURCE + extensions.CC_HEADER + extensions.CPP_MODULE_MAP
     )
     return header_discover_required and not use_header_modules
@@ -2279,7 +2281,7 @@
         feature_configuration,
         configuration):
     diagnostics_file = None
-    if feature_configuration.is_enabled("serialized_diagnostics_file"):
+    if feature_configuration.is_enabled(feature_names.SERIALIZED_DIAGNOSTICS_FILE):
         base_name = output_name
         if category != artifact_category.OBJECT_FILE and category != artifact_category.PROCESSED_HEADER:
             base_name = _cc_internal.get_artifact_name_for_category(
diff --git a/cc/private/compile/compile_action_templates.bzl b/cc/private/compile/compile_action_templates.bzl
index 94d65cd..1744c75 100644
--- a/cc/private/compile/compile_action_templates.bzl
+++ b/cc/private/compile/compile_action_templates.bzl
@@ -20,6 +20,7 @@
     "CPP_SOURCE_TYPE_SOURCE",
     artifact_category = "artifact_category_names",
 )
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", cc_semantics = "semantics")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/compile:cc_compilation_helper.bzl", "dotd_files_enabled", "serialized_diagnostics_file_enabled")
@@ -96,7 +97,7 @@
             language = language,
         )
     else:  # CPP_SOURCE_TYPE_SOURCE
-        lto_output_enabled = feature_configuration.is_enabled("thin_lto")
+        lto_output_enabled = feature_configuration.is_enabled(feature_names.THIN_LTO)
         if generate_no_pic_action:
             _create_compile_action_template(
                 action_construction_context = action_construction_context,
diff --git a/cc/private/compile/compile_build_variables.bzl b/cc/private/compile/compile_build_variables.bzl
index 7ca6959..9b690f6 100644
--- a/cc/private/compile/compile_build_variables.bzl
+++ b/cc/private/compile/compile_build_variables.bzl
@@ -16,6 +16,7 @@
 """
 
 load("//cc/common:cc_helper_internal.bzl", "extensions", "get_fdo_build_stamp", "get_linkstamp_stamps", _PRIVATE_STARLARKIFICATION_ALLOWLIST = "PRIVATE_STARLARKIFICATION_ALLOWLIST")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_info.bzl", "get_module_map_name")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/rules_impl:native_cc_common.bzl", _cc_common_internal = "native_cc_common")
@@ -147,9 +148,9 @@
         strip_opts = []
     if input_file == _UNBOUND:
         input_file = None
-    if (use_pic and not feature_configuration.is_enabled("pic") and not feature_configuration.is_enabled("supports_pic")):
+    if (use_pic and not feature_configuration.is_enabled(feature_names.PIC) and not feature_configuration.is_enabled(feature_names.SUPPORTS_PIC)):
         fail("PIC compilation is requested but the toolchain does not support it " +
-             "(feature named 'supports_pic' is not enabled)")
+             "(feature named '{}' is not enabled)".format(feature_names.SUPPORTS_PIC))
 
     cpp_configuration = cc_toolchain._cpp_configuration
     fdo_context = cc_toolchain._fdo_context
@@ -207,7 +208,7 @@
         defines = cc_compilation_context.defines,
         local_defines = cc_compilation_context.local_defines,
         external_include_dirs = cc_compilation_context.external_includes,
-        cpp_module_map = cc_compilation_context._module_map if feature_configuration.is_enabled("module_maps") else None,
+        cpp_module_map = cc_compilation_context._module_map if feature_configuration.is_enabled(feature_names.MODULE_MAPS) else None,
         direct_module_maps = cc_compilation_context._direct_module_maps,
     )
     return _cc_internal.combine_cc_toolchain_variables(cc_toolchain._build_variables, common_vars)
@@ -237,7 +238,7 @@
         result[_VARS.MODULE_MAP_FILE] = cpp_module_map.file
         result[_VARS.DEPENDENT_MODULE_MAP_FILES] = direct_module_maps
 
-    if feature_configuration.is_enabled("use_header_modules"):
+    if feature_configuration.is_enabled(feature_names.USE_HEADER_MODULES):
         result[_VARS.MODULE_FILES] = ()
     if feature_configuration.is_requested("system_include_paths"):
         result[_VARS.INCLUDE_PATHS] = include_dirs
@@ -446,9 +447,9 @@
         cs_fdo_instrument):
     """Populates FDO build variables."""
     variables = {}
-    if feature_configuration.is_enabled("fdo_instrument"):
+    if feature_configuration.is_enabled(feature_names.FDO_INSTRUMENT):
         variables["fdo_instrument_path"] = fdo_instrument
-    if feature_configuration.is_enabled("cs_fdo_instrument"):
+    if feature_configuration.is_enabled(feature_names.CS_FDO_INSTRUMENT):
         variables["cs_fdo_instrument_path"] = cs_fdo_instrument
 
     if not (getattr(fdo_context, "branch_fdo_profile", None) or
@@ -480,10 +481,10 @@
     if (branch_fdo_profile and
         auxiliary_fdo_inputs_list and
         (
-            feature_configuration.is_enabled("autofdo") or
-            feature_configuration.is_enabled("xbinaryfdo") or
+            feature_configuration.is_enabled(feature_names.AUTOFDO) or
+            feature_configuration.is_enabled(feature_names.XBINARYFDO) or
             (
-                feature_configuration.is_enabled("fdo_optimize") and
+                feature_configuration.is_enabled(feature_names.FDO_OPTIMIZE) and
                 branch_fdo_profile.branch_fdo_mode in ("llvm_fdo", "llvm_cs_fdo")
             )
         )):
@@ -537,8 +538,8 @@
         return False
 
     # Don't pass Propeller input files if they have no effect (i.e. for ThinLTO).
-    return (not feature_configuration.is_enabled("thin_lto") or
-            feature_configuration.is_enabled("propeller_optimize_thinlto_compile_actions"))
+    return (not feature_configuration.is_enabled(feature_names.THIN_LTO) or
+            feature_configuration.is_enabled(feature_names.PROPELLER_OPTIMIZE_THINLTO_COMPILE_ACTIONS))
 
 def get_linkstamp_compile_variables(
         source_file,
diff --git a/cc/private/link/BUILD b/cc/private/link/BUILD
index 9fd374a..00b3347 100644
--- a/cc/private/link/BUILD
+++ b/cc/private/link/BUILD
@@ -20,6 +20,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//cc:action_names_bzl",
+        "//cc/common:feature_names_bzl",
         "//cc/common:semantics_bzl",
         "//cc/private:cc_internal_bzl",
         "//cc/private/compile:compile_bzl",
diff --git a/cc/private/link/cc_linking_helper.bzl b/cc/private/link/cc_linking_helper.bzl
index ef12dae..808a34f 100644
--- a/cc/private/link/cc_linking_helper.bzl
+++ b/cc/private/link/cc_linking_helper.bzl
@@ -24,6 +24,7 @@
     _use_pic_for_dynamic_libs = "use_pic_for_dynamic_libs",
     artifact_category = "artifact_category_names",
 )
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/compile:cc_compilation_outputs.bzl", "EMPTY_COMPILATION_OUTPUTS")
 load("//cc/private/link:cpp_link_action.bzl", "link_action")
@@ -225,7 +226,7 @@
             )
 
     if static_link_type == LINK_TARGET_TYPE.ALWAYS_LINK_STATIC_LIBRARY and \
-       feature_configuration.is_enabled("disable_whole_archive_for_static_lib"):
+       feature_configuration.is_enabled(feature_names.DISABLE_WHOLE_ARCHIVE_FOR_STATIC_LIB):
         fail("Attribute alwayslink: alwayslink should not be True for a target" +
              " with the disable_whole_archive_for_static_lib feature enabled.")
 
@@ -235,7 +236,7 @@
             **(dynamic_library | static_library |
                dict(
                    _disable_whole_archive =
-                       feature_configuration.is_enabled("disable_whole_archive_for_static_lib"),
+                       feature_configuration.is_enabled(feature_names.DISABLE_WHOLE_ARCHIVE_FOR_STATIC_LIB),
                    alwayslink = alwayslink,
                    _contains_objects = True,
                ))
@@ -286,14 +287,14 @@
     # Should interface shared objects should be used in the build implied by the given
     # cpp_config and toolchain.
     emit_interface_shared_libraries = emit_interface_shared_libraries and (
-        feature_configuration.is_enabled("supports_interface_shared_libraries") and
+        feature_configuration.is_enabled(feature_names.SUPPORTS_INTERFACE_SHARED_LIBRARIES) and
         cc_toolchain._cpp_configuration.interface_shared_objects()
     )
     if emit_interface_shared_libraries:
         so_interface, _ = _get_linked_artifact(actions, name, LINK_TARGET_TYPE.INTERFACE_DYNAMIC_LIBRARY, cc_toolchain)
 
         # TODO(b/28946988): Remove this hard-coded flag.
-        if not feature_configuration.is_enabled("targets_windows") and not feature_configuration.is_enabled("set_soname"):
+        if not feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS) and not feature_configuration.is_enabled(feature_names.SET_SONAME):
             link_action_kwargs["linkopts"].append("-Wl,-soname=" + dynamic_library_soname(
                 actions,
                 # Must match https://github.com/bazelbuild/bazel/blob/795af54db5c348af5ca8b2961a982b399206ea20/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java#L169.
@@ -339,7 +340,7 @@
 
     impl_library_link_artifact = None
     if dynamic_link_type == LINK_TARGET_TYPE.DYNAMIC_LIBRARY and not neverlink and \
-       not feature_configuration.is_enabled("copy_dynamic_libraries_to_binary"):
+       not feature_configuration.is_enabled(feature_names.COPY_DYNAMIC_LIBRARIES_TO_BINARY):
         impl_library_link_artifact = dynamic_library_symlink(
             actions,
             linker_output,
@@ -393,7 +394,7 @@
 
     # On Windows, we cannot build a shared library with symbols unresolved, so here we
     # dynamically link to all its dependencies, even for LINK_TARGET_TYPE.NODEPS_DYNAMIC_LIBRARY.
-    should_link_transitively = (feature_configuration.is_enabled("targets_windows") or
+    should_link_transitively = (feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS) or
                                 dynamic_link_type != LINK_TARGET_TYPE.NODEPS_DYNAMIC_LIBRARY)
     if not should_link_transitively:
         return [], [], [], []  # libraries_to_link, linkstamps, linkopts, non_code_inputs
@@ -425,7 +426,7 @@
     additional_object_files = []
     allow_lto_indexing = False
 
-    if not feature_configuration.is_enabled("thin_lto"):
+    if not feature_configuration.is_enabled(feature_names.THIN_LTO):
         return all_lto_artifacts, allow_lto_indexing, thinlto_param_file, additional_object_files
 
     lto_compilation_context = compilation_outputs._lto_compilation_context
@@ -433,7 +434,7 @@
 
     # TODO(b/338618120): deduplicate prefer_static_lib, prefer_pic_libs computed in finalize_link_action as well
     prefer_static_libs = linking_mode == LINKING_MODE.STATIC or \
-                         not feature_configuration.is_enabled("supports_dynamic_linker")
+                         not feature_configuration.is_enabled(feature_names.SUPPORTS_DYNAMIC_LINKER)
     prefer_pic_libs = is_dynamic_library(link_type)
 
     static_libraries_to_link = []
@@ -453,8 +454,8 @@
                 break
 
     if has_lto_bitcode_inputs:
-        if not feature_configuration.is_enabled("supports_start_end_lib"):
-            fail("When using LTO. The feature supports_start_end_lib must be enabled.")
+        if not feature_configuration.is_enabled(feature_names.SUPPORTS_START_END_LIB):
+            fail("When using LTO. The feature {} must be enabled.".format(feature_names.SUPPORTS_START_END_LIB))
 
         all_lto_artifacts, allow_lto_indexing, thinlto_param_file, thinlto_merged_object_file = \
             create_lto_artifacts_and_lto_indexing_action(
@@ -484,7 +485,7 @@
     library_to_link = {}
     if dynamic_library:
         library_to_link = dict(_library_identifier = dynamic_library.library_identifier)
-        if neverlink or feature_configuration.is_enabled("copy_dynamic_libraries_to_binary"):
+        if neverlink or feature_configuration.is_enabled(feature_names.COPY_DYNAMIC_LIBRARIES_TO_BINARY):
             if interface_library:
                 library_to_link["interface_library"] = interface_library.file
             library_to_link["dynamic_library"] = dynamic_library.file
diff --git a/cc/private/link/collect_solib_dirs.bzl b/cc/private/link/collect_solib_dirs.bzl
index a7edc0f..a414d28 100644
--- a/cc/private/link/collect_solib_dirs.bzl
+++ b/cc/private/link/collect_solib_dirs.bzl
@@ -15,6 +15,7 @@
 
 load("@bazel_skylib//lib:paths.bzl", "paths")
 load("//cc/common:cc_helper_internal.bzl", "is_shared_library")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private/link:target_types.bzl", "LINKING_MODE", "LINK_TARGET_TYPE", "is_dynamic_library")
 
 # TODO(b/338618120): Refine the signature of collect_solib_dirs. Large objects are passed in
@@ -178,13 +179,13 @@
     include_solib_dir, include_toolchain_libraries_solib_dir = False, False
     linked_libraries_paths = {}  # :dict[str, str]
 
-    dont_copy_dynamic_libraries_to_binary = not feature_configuration.is_enabled("copy_dynamic_libraries_to_binary")
+    dont_copy_dynamic_libraries_to_binary = not feature_configuration.is_enabled(feature_names.COPY_DYNAMIC_LIBRARIES_TO_BINARY)
 
     # On Windows, dynamic library (dll) cannot be linked directly when using toolchains that
     # support interface library (eg. MSVC). If the user is doing so, it is only to be referenced
     # in other places (such as copy_dynamic_libraries_to_binary); skip adding it.
-    windows_shared_libraries = (feature_configuration.is_enabled("targets_windows") and
-                                feature_configuration.is_enabled("supports_interface_shared_libraries"))
+    windows_shared_libraries = (feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS) and
+                                feature_configuration.is_enabled(feature_names.SUPPORTS_INTERFACE_SHARED_LIBRARIES))
     solib_dir_split = reversed(solib_dir.split("/"))
 
     for library in libraries:
diff --git a/cc/private/link/create_libraries_to_link_values.bzl b/cc/private/link/create_libraries_to_link_values.bzl
index 7b4c38b..f5ccb2b 100644
--- a/cc/private/link/create_libraries_to_link_values.bzl
+++ b/cc/private/link/create_libraries_to_link_values.bzl
@@ -14,6 +14,7 @@
 """Goes over LibraryToLinks and produces LibraryToLinkValue-s."""
 
 load("//cc/common:cc_helper_internal.bzl", "is_shared_library", "is_versioned_shared_library", "root_relative_path")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 
 # Types of LibraryToLinkValues
@@ -137,8 +138,8 @@
 
     # For dynamic libraries
     windows_with_interface_shared_libraries = (
-        feature_configuration.is_enabled("targets_windows") and
-        feature_configuration.is_enabled("supports_interface_shared_libraries")
+        feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS) and
+        feature_configuration.is_enabled(feature_names.SUPPORTS_INTERFACE_SHARED_LIBRARIES)
     )
 
     for library in libraries:
diff --git a/cc/private/link/create_library_to_link.bzl b/cc/private/link/create_library_to_link.bzl
index baaa411..098dee6 100644
--- a/cc/private/link/create_library_to_link.bzl
+++ b/cc/private/link/create_library_to_link.bzl
@@ -17,6 +17,7 @@
 
 load("@bazel_skylib//lib:paths.bzl", "paths")
 load("//cc/common:cc_helper_internal.bzl", "is_versioned_shared_library", "path_contains_up_level_references")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/compile:lto_compilation_context.bzl", _EMPTY_LTO = "EMPTY_LTO_COMPILATION_CONTEXT")
 load("//cc/private/link:dynamic_library_symlink.bzl", "dynamic_library_symlink", "dynamic_library_symlink2")
@@ -236,7 +237,7 @@
             fail("If you pass 'dynamic_library', you must also pass a 'cc_toolchain'")
         if not feature_configuration:
             fail("If you pass 'dynamic_library', you must also pass a 'feature_configuration'")
-        if not feature_configuration.is_enabled("targets_windows"):
+        if not feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS):
             resolved_symlink_dynamic_library = dynamic_library
             if dynamic_library_symlink_path:
                 if dynamic_library.short_path.startswith("_solib_"):
@@ -251,7 +252,7 @@
             fail("If you pass 'interface_library', you must also pass a 'cc_toolchain'")
         if not feature_configuration:
             fail("If you pass 'interface_library', you must also pass a 'feature_configuration'")
-        if not feature_configuration.is_enabled("targets_windows"):
+        if not feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS):
             resolved_symlink_interface_library = interface_library
             if interface_library_symlink_path:
                 if interface_library.short_path.startswith("_solib_"):
diff --git a/cc/private/link/finalize_link_action.bzl b/cc/private/link/finalize_link_action.bzl
index a6ec53d..1beb150 100644
--- a/cc/private/link/finalize_link_action.bzl
+++ b/cc/private/link/finalize_link_action.bzl
@@ -14,6 +14,7 @@
 """Common functions that create C++ link and LTO indexing action."""
 
 load("@bazel_features//:features.bzl", "bazel_features")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", "semantics")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/compile:linkstamp_compile.bzl", "register_linkstamp_compile_action")
@@ -112,7 +113,7 @@
     must_keep_debug = any([lib._must_keep_debug for lib in libraries_to_link])
 
     toolchain_libraries_solib_dir = ""
-    if feature_configuration.is_enabled("static_link_cpp_runtimes"):
+    if feature_configuration.is_enabled(feature_names.STATIC_LINK_CPP_RUNTIMES):
         toolchain_libraries_solib_dir = cc_toolchain.dynamic_runtime_solib_dir
 
     solib_dir = output.root.path + "/" + cc_toolchain._solib_dir
@@ -120,7 +121,7 @@
     expanded_linker_artifacts = []
     lto_map = dict(lto_mapping)  # copy map, because following functions pop from it
 
-    if feature_configuration.is_enabled("use_lto_native_object_directory"):
+    if feature_configuration.is_enabled(feature_names.USE_LTO_NATIVE_OBJECT_DIRECTORY):
         shared_non_lto_obj_root_prefix = "shared.nonlto-obj"
     else:
         shared_non_lto_obj_root_prefix = "shared.nonlto"
@@ -136,11 +137,11 @@
 
     # TODO(b/331164666): Remove CppHelper.getArchiveType
     use_start_end_lib = (cc_toolchain._cpp_configuration.start_end_lib() and
-                         feature_configuration.is_enabled("supports_start_end_lib"))
+                         feature_configuration.is_enabled(feature_names.SUPPORTS_START_END_LIB))
 
     # TODO(b/338618120): deduplicate prefer_static_lib, prefer_pic_libs
     prefer_static_libs = linking_mode == LINKING_MODE.STATIC or \
-                         not feature_configuration.is_enabled("supports_dynamic_linker")
+                         not feature_configuration.is_enabled(feature_names.SUPPORTS_DYNAMIC_LINKER)
 
     # TODO(b/412540147): We select PIC libraries iff creating a dynamic library. Match PIC flags.
     prefer_pic_libs = is_dynamic_library(link_type)
@@ -222,8 +223,8 @@
     # TODO(b/62693279): Cleanup once internal crosstools specify ifso building correctly.
     should_use_link_dynamic_library_tool = (
         is_dynamic_library(link_type) and
-        feature_configuration.is_enabled("supports_interface_shared_libraries") and
-        not feature_configuration.is_enabled("has_configured_linker_path")
+        feature_configuration.is_enabled(feature_names.SUPPORTS_INTERFACE_SHARED_LIBRARIES) and
+        not feature_configuration.is_enabled(feature_names.HAS_CONFIGURED_LINKER_PATH)
     )
     if should_use_link_dynamic_library_tool:
         tool_path = cc_toolchain._link_dynamic_library_tool.path
@@ -254,7 +255,7 @@
     if linkstamp_map:
         # A different value from use_pic
         needs_pic = (cc_toolchain._cpp_configuration.force_pic() or
-                     (is_dynamic_library(link_type) and feature_configuration.is_enabled("supports_pic")))
+                     (is_dynamic_library(link_type) and feature_configuration.is_enabled(feature_names.SUPPORTS_PIC)))
 
         for linkstamp, artifact in linkstamp_map.items():
             register_linkstamp_compile_action(
@@ -339,9 +340,9 @@
         feature_configuration,
         interface_output,
     ):
-        if feature_configuration.is_enabled("gcc_quoting_for_param_files"):
+        if feature_configuration.is_enabled(feature_names.GCC_QUOTING_FOR_PARAM_FILES):
             parameter_file_type = "GCC_QUOTED"
-        elif feature_configuration.is_enabled("windows_quoting_for_param_files"):
+        elif feature_configuration.is_enabled(feature_names.WINDOWS_QUOTING_FOR_PARAM_FILES):
             parameter_file_type = "WINDOWS"
         else:
             parameter_file_type = "UNQUOTED"
@@ -359,9 +360,9 @@
     # for using separate mnemonic for the two different activities, but that would require a lot
     # of updates to configurations and rules that reference the CppLink mnemonic.
     # A target or toolchain may also be incompatible with path mapping.
-    if (mnemonic == "CppLink" and feature_configuration.is_requested("cpp_link_path_mapping") and
-        not feature_configuration.is_enabled("disable_cpp_link_path_mapping") and
-        not feature_configuration.is_enabled("thin_lto")):
+    if (mnemonic == "CppLink" and feature_configuration.is_requested(feature_names.CPP_LINK_PATH_MAPPING) and
+        not feature_configuration.is_enabled(feature_names.DISABLE_CPP_LINK_PATH_MAPPING) and
+        not feature_configuration.is_enabled(feature_names.THIN_LTO)):
         execution_info["supports-path-mapping"] = ""
 
     build_variables = _cc_internal.cc_toolchain_variables(vars = build_variables)
@@ -381,7 +382,7 @@
         action_name = action_name,
         variables = build_variables,
     )
-    if not feature_configuration.is_enabled("sanitize_pwd") and "requires_darwin" not in execution_info:
+    if not feature_configuration.is_enabled(feature_names.SANITIZE_PWD) and "requires_darwin" not in execution_info:
         # Legacy behavior: prevents gcc from writing the unpredictable (and often
         # irrelevant) value of getcwd() into the debug info.
         # New toolchains should use the sanitize_pwd feature instead.
@@ -429,14 +430,14 @@
         # outputs.
         if interface_output:
             # On Windows, We can always split the command line when building DLL.
-            return feature_configuration.is_enabled("targets_windows")
+            return feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS)
         else:
             return True
     elif link_type.linker_or_archiver == USE_LINKER:
         return True
     elif link_type.linker_or_archiver == USE_ARCHIVER:
         # A feature to control whether to use param files for archiving commands.
-        return feature_configuration.is_enabled("archive_param_file")
+        return feature_configuration.is_enabled(feature_names.ARCHIVE_PARAM_FILE)
 
     # This should be unreachable:
     return False
@@ -453,7 +454,7 @@
         # is not needed).
         return False
 
-    if feature_configuration.is_requested("force_no_whole_archive"):
+    if feature_configuration.is_requested(feature_names.FORCE_NO_WHOLE_ARCHIVE):
         return False
 
     if cpp_config.incompatible_remove_legacy_whole_archive():
diff --git a/cc/private/link/link.bzl b/cc/private/link/link.bzl
index 3a29cb4..822506f 100644
--- a/cc/private/link/link.bzl
+++ b/cc/private/link/link.bzl
@@ -17,6 +17,7 @@
 Used for C++ transitive linking.
 """
 
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/compile:cc_compilation_outputs.bzl", "EMPTY_COMPILATION_OUTPUTS")
 load("//cc/private/link:cc_linking_helper.bzl", "create_cc_link_actions")
@@ -190,5 +191,5 @@
         main_output,  # linker_output_artifact
         emit_interface_shared_libraries = dynamic_link_type == LINK_TARGET_TYPE.DYNAMIC_LIBRARY and
                                           (emit_interface_shared_library or
-                                           feature_configuration.is_enabled("targets_windows")),
+                                           feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS)),
     )
diff --git a/cc/private/link/link_build_variables.bzl b/cc/private/link/link_build_variables.bzl
index 5743354..51c4337 100644
--- a/cc/private/link/link_build_variables.bzl
+++ b/cc/private/link/link_build_variables.bzl
@@ -27,6 +27,7 @@
 """
 
 load("//cc/common:cc_helper_internal.bzl", "get_relative_path", "should_create_per_object_debug_info", artifact_category = "artifact_category_names")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 
 # Enum covering all build variables we create for all various C++ linking actions
@@ -142,7 +143,7 @@
     """
 
     # LINT.ThenChange(https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java)
-    if feature_configuration.is_enabled("fdo_instrument"):
+    if feature_configuration.is_enabled(feature_names.FDO_INSTRUMENT):
         fail("FDO instrumentation not supported")
 
     # Normalize input values, so that we don't set Nones on CcToolchainVariables
@@ -246,15 +247,15 @@
         # formatting of param file path from the specification.
         vars[LINK_BUILD_VARIABLES.LINKER_PARAM_FILE] = param_file
 
-    if feature_configuration.is_enabled("fdo_instrument"):
+    if feature_configuration.is_enabled(feature_names.FDO_INSTRUMENT):
         if getattr(cc_toolchain._fdo_context, "branch_fdo_profile", None):
-            fail("Can't use --feature=fdo_instrument together with --fdo_profile")
+            fail("Can't use --feature={} together with --fdo_profile".format(feature_names.FDO_INSTRUMENT))
         if not cpp_config.fdo_instrument():
-            fail("When using --feature=fdo_instrument, you need to set --fdo_instrument as well")
+            fail("When using --feature={}, you need to set --fdo_instrument as well".format(feature_names.FDO_INSTRUMENT))
         vars[LINK_BUILD_VARIABLES.FDO_INSTRUMENT_PATH] = cpp_config.fdo_instrument()
-    elif feature_configuration.is_enabled("cs_fdo_instrument"):
+    elif feature_configuration.is_enabled(feature_names.CS_FDO_INSTRUMENT):
         if not cpp_config.cs_fdo_instrument():
-            fail("When using --feature=cs_fdo_instrument, you need to set --cs_fdo_instrument as well")
+            fail("When using --feature={}, you need to set --cs_fdo_instrument as well".format(feature_names.CS_FDO_INSTRUMENT))
         vars[LINK_BUILD_VARIABLES.CS_FDO_INSTRUMENT_PATH] = cpp_config.cs_fdo_instrument()
 
     # For now, silently ignore linkopts if this is a static library
@@ -309,7 +310,7 @@
     fdo_context = cc_toolchain._fdo_context
     if (not cc_toolchain._is_tool_configuration and
         fdo_context and
-        feature_configuration.is_enabled("propeller_optimize") and
+        feature_configuration.is_enabled(feature_names.PROPELLER_OPTIMIZE) and
         fdo_context.propeller_optimize_info and
         fdo_context.propeller_optimize_info.ld_profile):
         vars[LINK_BUILD_VARIABLES.PROPELLER_OPTIMIZE_LD_PATH] = fdo_context.propeller_optimize_info.ld_profile
@@ -376,7 +377,7 @@
             ";" + get_relative_path(bin_directory_path, lto_output_root_prefix) + "/"
         )
 
-    if not feature_configuration.is_enabled("no_use_lto_indexing_bitcode_file"):
+    if not feature_configuration.is_enabled(feature_names.NO_USE_LTO_INDEXING_BITCODE_FILE):
         object_file_extension = _cc_internal.get_artifact_name_extension_for_category(
             cc_toolchain,
             artifact_category.OBJECT_FILE,
diff --git a/cc/private/link/lto_backends.bzl b/cc/private/link/lto_backends.bzl
index 2cef9da..db8e948 100644
--- a/cc/private/link/lto_backends.bzl
+++ b/cc/private/link/lto_backends.bzl
@@ -32,6 +32,7 @@
 
 load("@bazel_skylib//lib:paths.bzl", "paths")
 load("//cc/common:cc_helper_internal.bzl", "should_create_per_object_debug_info")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/rules_impl:native_cc_common.bzl", _cc_common_internal = "native_cc_common")
 
@@ -226,7 +227,7 @@
         return {}
 
     lto_output_root_prefix = "shared.nonlto"
-    if feature_configuration.is_enabled("use_lto_native_object_directory"):
+    if feature_configuration.is_enabled(feature_names.USE_LTO_NATIVE_OBJECT_DIRECTORY):
         lto_obj_root_prefix = "shared.nonlto-obj"
     else:
         lto_obj_root_prefix = "shared.nonlto"
@@ -282,7 +283,7 @@
     )
 
     # Add the context sensitive instrument path to the backend.
-    if feature_configuration.is_enabled("cs_fdo_instrument"):
+    if feature_configuration.is_enabled(feature_names.CS_FDO_INSTRUMENT):
         build_variables["cs_fdo_instrument_path"] = cc_toolchain._cpp_configuration.cs_fdo_instrument()
 
     build_variables = _cc_internal.combine_cc_toolchain_variables(
@@ -430,9 +431,9 @@
     if propeller_optimize_info != None and propeller_optimize_info.ld_profile != None:
         build_variables["propeller_optimize_ld_path"] = propeller_optimize_info.ld_profile
         additional_inputs.append(propeller_optimize_info.ld_profile)
-    if not feature_configuration.is_enabled("autofdo") and \
-       not feature_configuration.is_enabled("cs_fdo_optimize") and \
-       not feature_configuration.is_enabled("xbinaryfdo"):
+    if not feature_configuration.is_enabled(feature_names.AUTOFDO) and \
+       not feature_configuration.is_enabled(feature_names.CS_FDO_OPTIMIZE) and \
+       not feature_configuration.is_enabled(feature_names.XBINARYFDO):
         return
 
     branch_fdo_profile = getattr(fdo_context, "branch_fdo_profile", None)
@@ -509,7 +510,7 @@
     else:
         # An empty input indicates not to perform cross-module optimization.
         build_variables["thinlto_index"] = (
-            "NUL" if feature_configuration.is_enabled("targets_windows") else "/dev/null"
+            "NUL" if feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS) else "/dev/null"
         )
 
     # The output from the LTO backend step is a native object file.
diff --git a/cc/private/link/lto_indexing_action.bzl b/cc/private/link/lto_indexing_action.bzl
index fe4a232..fd3d7b9 100644
--- a/cc/private/link/lto_indexing_action.bzl
+++ b/cc/private/link/lto_indexing_action.bzl
@@ -15,6 +15,7 @@
 
 load("@bazel_features//:features.bzl", "bazel_features")
 load("//cc/common:cc_helper_internal.bzl", "root_relative_path", artifact_category = "artifact_category_names")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
 load("//cc/private/compile:lto_compilation_context.bzl", "get_minimized_bitcode_or_self")
 load("//cc/private/link:finalize_link_action.bzl", "finalize_link_action")
@@ -77,12 +78,12 @@
         all_lto_artifacts, allow_lto_indexing, thinlto_param_file, thinlto_merged_object_file
 
     """
-    if not feature_configuration.is_enabled("supports_start_end_lib"):
+    if not feature_configuration.is_enabled(feature_names.SUPPORTS_START_END_LIB):
         fail("When using LTO. The feature supports_start_end_lib must be enabled.")
     can_include_any_link_static_in_lto_indexing = \
-        not feature_configuration.is_enabled("thin_lto_all_linkstatic_use_shared_nonlto_backends")
+        not feature_configuration.is_enabled(feature_names.THIN_LTO_ALL_LINKSTATIC_USE_SHARED_NONLTO_BACKENDS)
     can_include_any_link_static_test_target_in_lto_indexing = \
-        not feature_configuration.is_enabled("thin_lto_linkstatic_tests_use_shared_nonlto_backends")
+        not feature_configuration.is_enabled(feature_names.THIN_LTO_LINKSTATIC_TESTS_USE_SHARED_NONLTO_BACKENDS)
     include_link_static_in_lto_indexing = can_include_any_link_static_in_lto_indexing and (
         can_include_any_link_static_test_target_in_lto_indexing or not test_only_target
     )
@@ -92,7 +93,7 @@
 
     lto_output_root_prefix = root_relative_path(output) + ".lto" if allow_lto_indexing else "shared.nonlto"
     lto_obj_root_prefix = lto_output_root_prefix
-    if feature_configuration.is_enabled("use_lto_native_object_directory"):
+    if feature_configuration.is_enabled(feature_names.USE_LTO_NATIVE_OBJECT_DIRECTORY):
         lto_obj_root_prefix = lto_output_root_prefix + "-obj"
     object_file_inputs = compilation_outputs.pic_objects if use_pic else compilation_outputs.objects
 
diff --git a/cc/private/rules_impl/cc_binary_impl.bzl b/cc/private/rules_impl/cc_binary_impl.bzl
index f375c82..622862b 100644
--- a/cc/private/rules_impl/cc_binary_impl.bzl
+++ b/cc/private/rules_impl/cc_binary_impl.bzl
@@ -21,6 +21,7 @@
 load("//cc/common:cc_helper.bzl", "artifact_category", "cc_helper", "linker_mode")
 load("//cc/common:cc_info.bzl", "CcInfo")
 load("//cc/common:debug_package_info.bzl", "DebugPackageInfo")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", "semantics")
 load("//cc/private:graph_node_info.bzl", "GraphNodeInfo")
 load(":cc_shared_library_impl.bzl", "add_unused_dynamic_deps", "build_exports_map_from_only_dynamic_deps", "build_link_once_static_libs_map", "merge_cc_shared_library_infos", "separate_static_and_dynamic_link_libraries", "sort_linker_inputs", "throw_linked_but_not_exported_errors")
@@ -273,7 +274,7 @@
     # Unlike Unix on Windows every dynamic dependency must be linked to the
     # main binary, even indirect ones that are dependencies of direct
     # dynamic dependencies of this binary.
-    link_indirect_deps = cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows")
+    link_indirect_deps = feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS)
     linker_inputs_count += add_unused_dynamic_deps(ctx, unused_dynamic_linker_inputs, _add_linker_input_to_dict, topologically_sorted_labels, link_indirect_deps)
 
     throw_linked_but_not_exported_errors(linked_statically_but_not_exported)
@@ -549,7 +550,7 @@
     # Allows the dynamic library generated for code of test targets to be linked separately.
     link_compile_output_separately = ctx.attr._is_test and linking_mode == linker_mode.LINKING_DYNAMIC and cpp_config.dynamic_mode() == "DEFAULT" and ("dynamic_link_test_srcs" in features)
 
-    is_windows_enabled = cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows")
+    is_windows_enabled = feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS)
 
     # When linking the object files directly into the resulting binary, we do not need
     # library-level link outputs; thus, we do not let CcCompilationHelper produce link outputs
@@ -613,14 +614,14 @@
     # On Windows, if GENERATE_PDB_FILE feature is enabled
     # then a pdb file will be built along with the executable.
     pdb_file = None
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "generate_pdb_file"):
+    if feature_configuration.is_enabled(feature_names.GENERATE_PDB_FILE):
         pdb_file = ctx.actions.declare_file(_strip_extension(binary) + ".pdb", sibling = binary)
         additional_linker_outputs.append(pdb_file)
 
     # On macOS, if cpp_config.apple_generate_dsym is enabled
     # then a .dSYM file will be built along with the executable.
     dsym_file = None
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "generate_dsym_file"):
+    if feature_configuration.is_enabled(feature_names.GENERATE_DSYM_FILE):
         dsym_file = ctx.actions.declare_directory(
             "{name}.dSYM".format(
                 name = target_name,
@@ -631,7 +632,7 @@
         additional_linker_outputs.append(dsym_file)
 
     linkmap = None
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "generate_linkmap"):
+    if feature_configuration.is_enabled(feature_names.GENERATE_LINKMAP):
         linkmap = ctx.actions.declare_file(binary.basename + ".map", sibling = binary)
         additional_linker_outputs.append(linkmap)
 
@@ -730,7 +731,7 @@
     # If the binary is linked dynamically and COPY_DYNAMIC_LIBRARIES_TO_BINARY is enabled, collect
     # all the dynamic libraries we need at runtime. Then copy these libraries next to the binary.
     copied_runtime_dynamic_libraries = None
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "copy_dynamic_libraries_to_binary"):
+    if feature_configuration.is_enabled(feature_names.COPY_DYNAMIC_LIBRARIES_TO_BINARY):
         linker_inputs = deps_cc_linking_context.linker_inputs.to_list()
         libraries = []
         for linker_input in linker_inputs:
@@ -745,7 +746,7 @@
 
     files_to_build = depset(files_to_build_list)
     transitive_artifacts_list = [files_to_build, runtime_libraries_extra]
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "copy_dynamic_libraries_to_binary"):
+    if feature_configuration.is_enabled(feature_names.COPY_DYNAMIC_LIBRARIES_TO_BINARY):
         transitive_artifacts_list.append(copied_runtime_dynamic_libraries)
     transitive_artifacts = depset(transitive = transitive_artifacts_list)
 
diff --git a/cc/private/rules_impl/cc_import.bzl b/cc/private/rules_impl/cc_import.bzl
index dc03822..b9a3f96 100644
--- a/cc/private/rules_impl/cc_import.bzl
+++ b/cc/private/rules_impl/cc_import.bzl
@@ -22,6 +22,7 @@
 load("//cc/common:cc_common.bzl", "cc_common")
 load("//cc/common:cc_helper.bzl", "cc_helper")
 load("//cc/common:cc_info.bzl", "CcInfo")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", "semantics")
 
 CPP_LINK_STATIC_LIBRARY_ACTION_NAME = "c++-link-static-library"
@@ -145,7 +146,7 @@
         )
 
         link_flags = []
-        if static_library and cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "warn_backrefs_defined"):
+        if static_library and feature_configuration.is_enabled(feature_names.WARN_BACKREFS_DEFINED):
             link_flags.append(
                 "-Wl,--warn-backrefs-exclude=*{}*".format(static_library.short_path),
             )
diff --git a/cc/private/rules_impl/cc_library_impl.bzl b/cc/private/rules_impl/cc_library_impl.bzl
index 0393a2e..98536c9 100755
--- a/cc/private/rules_impl/cc_library_impl.bzl
+++ b/cc/private/rules_impl/cc_library_impl.bzl
@@ -18,6 +18,7 @@
 load("//cc/common:cc_common.bzl", "cc_common")
 load("//cc/common:cc_helper.bzl", "cc_helper")
 load("//cc/common:cc_info.bzl", "CcInfo")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", "semantics")
 load(":function_providing_rule.bzl", "wrap_starlark_function")
 
@@ -91,17 +92,13 @@
         compilation_outputs = [precompiled_objects, srcs_compilation_outputs],
     )
 
-    supports_dynamic_linker = cc_common.is_enabled(
-        feature_configuration = feature_configuration,
-        feature_name = "supports_dynamic_linker",
-    )
+    supports_dynamic_linker = feature_configuration.is_enabled(feature_names.SUPPORTS_DYNAMIC_LINKER)
 
     create_dynamic_library = (not ctx.attr.linkstatic and
                               supports_dynamic_linker and
                               (not cc_helper.is_compilation_outputs_empty(compilation_outputs) or
-                               cc_common.is_enabled(
-                                   feature_configuration = feature_configuration,
-                                   feature_name = "header_module_codegen",
+                               feature_configuration.is_enabled(
+                                   feature_names.HEADER_MODULE_CODEGEN,
                                )))
 
     output_group_builder = {}
@@ -135,7 +132,7 @@
         dll_name_suffix = ""
         additional_inputs = _filter_linker_scripts(ctx.files.deps) + ctx.files.additional_linker_inputs
         link_variables = {}
-        is_windows_enabled = cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows")
+        is_windows_enabled = feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS)
         if is_windows_enabled:
             dll_name_suffix = cc_helper.dll_hash_suffix(ctx, feature_configuration, ctx.fragments.cpp)
             generated_def_file = None
@@ -236,9 +233,8 @@
         if artifacts_to_build.pic_static_library != None:
             files_builder.append(artifacts_to_build.pic_static_library)
 
-        if not cc_common.is_enabled(
-            feature_configuration = feature_configuration,
-            feature_name = "targets_windows",
+        if not feature_configuration.is_enabled(
+            feature_names.TARGETS_WINDOWS,
         ):
             if artifacts_to_build.resolved_symlink_dynamic_library != None:
                 files_builder.append(artifacts_to_build.resolved_symlink_dynamic_library)
diff --git a/cc/private/rules_impl/cc_shared_library_impl.bzl b/cc/private/rules_impl/cc_shared_library_impl.bzl
index f5d3d0b..b241381 100644
--- a/cc/private/rules_impl/cc_shared_library_impl.bzl
+++ b/cc/private/rules_impl/cc_shared_library_impl.bzl
@@ -20,6 +20,7 @@
 load("//cc/common:cc_helper.bzl", "cc_helper")
 load("//cc/common:cc_info.bzl", "CcInfo")
 load("//cc/common:cc_shared_library_info.bzl", "CcSharedLibraryInfo")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", "semantics")
 load("//cc/private:graph_node_info.bzl", "GraphNodeInfo")
 load(":function_providing_rule.bzl", "wrap_starlark_function")
@@ -616,7 +617,7 @@
     feature_configuration = cc_common.configure_features(
         ctx = ctx,
         cc_toolchain = cc_toolchain,
-        requested_features = ctx.features + ["force_no_whole_archive"],
+        requested_features = ctx.features + [feature_names.FORCE_NO_WHOLE_ARCHIVE],
         unsupported_features = ctx.disabled_features,
     )
 
@@ -670,7 +671,7 @@
     additional_output_groups = {}
 
     pdb_file = None
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "generate_pdb_file"):
+    if feature_configuration.is_enabled(feature_names.GENERATE_PDB_FILE):
         if ctx.attr.shared_lib_name:
             pdb_file = ctx.actions.declare_file(paths.replace_extension(ctx.attr.shared_lib_name, ".pdb"))
         else:
@@ -678,7 +679,7 @@
         additional_outputs.append(pdb_file)
         additional_output_groups["pdb_file"] = depset([pdb_file])
 
-    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows"):
+    if feature_configuration.is_enabled(feature_names.TARGETS_WINDOWS):
         object_files = []
         for linker_input in linking_context.linker_inputs.to_list():
             for library in linker_input.libraries:
diff --git a/cc/private/rules_impl/cc_static_library.bzl b/cc/private/rules_impl/cc_static_library.bzl
index 41de852..041da2a 100644
--- a/cc/private/rules_impl/cc_static_library.bzl
+++ b/cc/private/rules_impl/cc_static_library.bzl
@@ -19,6 +19,7 @@
 load("//cc/common:cc_common.bzl", "cc_common")
 load("//cc/common:cc_helper.bzl", "artifact_category")
 load("//cc/common:cc_info.bzl", "CcInfo")
+load("//cc/common:feature_names.bzl", "feature_names")
 
 def _declare_static_library(*, name, actions, cc_toolchain):
     basename = paths.basename(name)
@@ -70,9 +71,8 @@
     args.add_all(command_line)
     args.add_all(objects)
 
-    if cc_common.is_enabled(
-        feature_configuration = feature_configuration,
-        feature_name = "archive_param_file",
+    if feature_configuration.is_enabled(
+        feature_names.ARCHIVE_PARAM_FILE,
     ):
         # TODO: The flag file arg should come from the toolchain instead.
         args.use_param_file("@%s", use_always = True)
@@ -185,7 +185,7 @@
     feature_configuration = cc_common.configure_features(
         ctx = ctx,
         cc_toolchain = cc_toolchain,
-        requested_features = ctx.features + ["symbol_check"],
+        requested_features = ctx.features + [feature_names.SYMBOL_CHECK],
         unsupported_features = ctx.disabled_features,
     )
 
diff --git a/cc/private/rules_impl/cc_toolchain_info.bzl b/cc/private/rules_impl/cc_toolchain_info.bzl
index 27cbf74..8524c27 100644
--- a/cc/private/rules_impl/cc_toolchain_info.bzl
+++ b/cc/private/rules_impl/cc_toolchain_info.bzl
@@ -15,14 +15,16 @@
 Definition of CcToolchainInfo provider.
 """
 
+load("//cc/common:feature_names.bzl", "feature_names")
+
 visibility(["//cc/..."])
 
 def _needs_pic_for_dynamic_libraries(*, feature_configuration):
-    return feature_configuration.is_enabled("supports_pic")
+    return feature_configuration.is_enabled(feature_names.SUPPORTS_PIC)
 
 def _static_runtime_lib(static_runtime_lib):
     def static_runtime_lib_func(*, feature_configuration):
-        if feature_configuration.is_enabled("static_link_cpp_runtimes"):
+        if feature_configuration.is_enabled(feature_names.STATIC_LINK_CPP_RUNTIMES):
             if static_runtime_lib == None:
                 fail("Toolchain supports embedded runtimes, but didn't provide static_runtime_lib attribute.")
             return static_runtime_lib
@@ -32,7 +34,7 @@
 
 def _dynamic_runtime_lib(dynamic_runtime_lib):
     def dynamic_runtime_lib_func(*, feature_configuration):
-        if feature_configuration.is_enabled("static_link_cpp_runtimes"):
+        if feature_configuration.is_enabled(feature_names.STATIC_LINK_CPP_RUNTIMES):
             if dynamic_runtime_lib == None:
                 fail("Toolchain supports embedded runtimes, but didn't provide dynamic_runtime_lib attribute.")
             return dynamic_runtime_lib
diff --git a/cc/private/rules_impl/objc_compilation_support.bzl b/cc/private/rules_impl/objc_compilation_support.bzl
index 82f95d8..599b741 100644
--- a/cc/private/rules_impl/objc_compilation_support.bzl
+++ b/cc/private/rules_impl/objc_compilation_support.bzl
@@ -17,6 +17,7 @@
 load("//cc:build_settings.bzl", "cc")
 load("//cc/common:cc_common.bzl", "cc_common")
 load("//cc/common:cc_helper.bzl", "cc_helper")
+load("//cc/common:feature_names.bzl", "feature_names")
 load(":objc_common.bzl", "objc_common")
 load(":objc_compilation_artifacts_info.bzl", "CompilationArtifactsInfo")
 load(":objc_intermediate_artifacts.bzl", "create_intermediate_artifacts")
@@ -136,7 +137,7 @@
     disabled_features.extend(common_variables.extra_disabled_features)
 
     if not support_parse_headers:
-        disabled_features.append("parse_headers")
+        disabled_features.append(feature_names.PARSE_HEADERS)
 
     return cc_common.configure_features(
         ctx = common_variables.ctx,
@@ -309,9 +310,8 @@
         support_parse_headers = True,
     )
 
-    generate_module_map = cc_common.is_enabled(
-        feature_configuration = feature_configuration,
-        feature_name = "module_maps",
+    generate_module_map = feature_configuration.is_enabled(
+        feature_names.MODULE_MAPS,
     )
     module_map = None
     if generate_module_map:
diff --git a/cc/private/toolchain_config/BUILD b/cc/private/toolchain_config/BUILD
index f763ad4..196113c 100644
--- a/cc/private/toolchain_config/BUILD
+++ b/cc/private/toolchain_config/BUILD
@@ -21,6 +21,7 @@
     deps = [
         "//cc:action_names_bzl",
         "//cc:cc_toolchain_config_lib_bzl",
+        "//cc/common:feature_names_bzl",
         "//cc/common:semantics_bzl",
         "//cc/private:cc_internal_bzl",
         "@bazel_skylib//lib:paths",
diff --git a/cc/private/toolchain_config/configure_features.bzl b/cc/private/toolchain_config/configure_features.bzl
index 3be7314..1d68fae 100644
--- a/cc/private/toolchain_config/configure_features.bzl
+++ b/cc/private/toolchain_config/configure_features.bzl
@@ -14,6 +14,7 @@
 """Helper functions for C++ feature configuration."""
 
 load("//cc:action_names.bzl", "ACTION_NAMES")
+load("//cc/common:feature_names.bzl", "feature_names")
 load("//cc/common:semantics.bzl", cc_semantics = "semantics")
 
 ALL_COMPILE_ACTIONS = [
@@ -114,30 +115,30 @@
     if not cc_toolchain._supports_header_parsing:
         # TODO(b/159096411): Remove once supports_header_parsing has been removed from the
         # cc_toolchain rule.
-        all_unsupported_features_set.add("parse_headers")
+        all_unsupported_features_set.add(feature_names.PARSE_HEADERS)
 
     if (language != "objc" and
         language != "objcpp" and
         cc_toolchain._cc_info.compilation_context._module_map == None):
-        all_unsupported_features_set.add("module_maps")
+        all_unsupported_features_set.add(feature_names.MODULE_MAPS)
 
     if cpp_configuration.force_pic():
-        if "supports_pic" in all_unsupported_features_set:
+        if feature_names.SUPPORTS_PIC in all_unsupported_features_set:
             fail("PIC compilation is requested but the toolchain does not support it " +
-                 "(feature named 'supports_pic' is not enabled)")
-        all_requested_features_set.add("supports_pic")
+                 "(feature named '{}' is not enabled)".format(feature_names.SUPPORTS_PIC))
+        all_requested_features_set.add(feature_names.SUPPORTS_PIC)
 
     if cpp_configuration.apple_generate_dsym:
-        all_requested_features_set.add("generate_dsym_file")
+        all_requested_features_set.add(feature_names.GENERATE_DSYM_FILE)
     else:
-        all_requested_features_set.add("no_generate_debug_symbols")
+        all_requested_features_set.add(feature_names.NO_GENERATE_DEBUG_SYMBOLS)
 
     if language == "objc" or language == "objcpp":
         all_requested_features_set.add("lang_objc")
         if cpp_configuration.objc_generate_linkmap:
-            all_requested_features_set.add("generate_linkmap")
+            all_requested_features_set.add(feature_names.GENERATE_LINKMAP)
         if cpp_configuration.objc_should_strip_binary:
-            all_requested_features_set.add("dead_strip")
+            all_requested_features_set.add(feature_names.DEAD_STRIP)
 
     all_features = [cpp_configuration.compilation_mode()]
     all_features.extend(DEFAULT_ACTION_CONFIGS)
@@ -156,11 +157,11 @@
     if ctx.configuration.coverage_enabled:
         all_features.extend(_get_coverage_features(cpp_configuration))
 
-    if "fdo_instrument" not in all_unsupported_features_set:
+    if feature_names.FDO_INSTRUMENT not in all_unsupported_features_set:
         if cpp_configuration.fdo_instrument() != None:
-            all_features.append("fdo_instrument")
+            all_features.append(feature_names.FDO_INSTRUMENT)
         elif cpp_configuration.cs_fdo_instrument() != None:
-            all_features.append("cs_fdo_instrument")
+            all_features.append(feature_names.CS_FDO_INSTRUMENT)
 
     fdo_context = cc_toolchain._fdo_context
     branch_fdo_provider = getattr(fdo_context, "branch_fdo_profile", None)
@@ -174,40 +175,40 @@
     if branch_fdo_provider != None and cpp_configuration.compilation_mode() == "opt":
         if ((branch_fdo_provider.branch_fdo_mode == "llvm_fdo" or
              branch_fdo_provider.branch_fdo_mode == "llvm_cs_fdo") and
-            "fdo_optimize" not in all_unsupported_features_set):
-            all_features.append("fdo_optimize")
-            if "memprof_optimize" not in all_unsupported_features_set:
-                all_features.append("enable_fdo_memprof_optimize")
-            if "thin_lto" not in all_unsupported_features_set:
-                all_features.append("enable_fdo_thinlto")
-            if ("split_functions" not in all_unsupported_features_set and
+            feature_names.FDO_OPTIMIZE not in all_unsupported_features_set):
+            all_features.append(feature_names.FDO_OPTIMIZE)
+            if feature_names.MEMPROF_OPTIMIZE not in all_unsupported_features_set:
+                all_features.append(feature_names.ENABLE_FDO_MEMPROF_OPTIMIZE)
+            if feature_names.THIN_LTO not in all_unsupported_features_set:
+                all_features.append(feature_names.ENABLE_FDO_THINLTO)
+            if (feature_names.SPLIT_FUNCTIONS not in all_unsupported_features_set and
                 not enable_propeller_optimize):
-                all_features.append("enable_fdo_split_functions")
+                all_features.append(feature_names.ENABLE_FDO_SPLIT_FUNCTIONS)
 
         if branch_fdo_provider.branch_fdo_mode == "llvm_cs_fdo":
-            all_features.append("cs_fdo_optimize")
+            all_features.append(feature_names.CS_FDO_OPTIMIZE)
 
         if branch_fdo_provider.branch_fdo_mode == "auto_fdo":
-            all_features.append("autofdo")
-            if "memprof_optimize" not in all_unsupported_features_set:
-                all_features.append("enable_autofdo_memprof_optimize")
-            if "thin_lto" not in all_unsupported_features_set:
-                all_features.append("enable_afdo_thinlto")
-            if "fsafdo" not in all_unsupported_features_set:
-                all_features.append("enable_fsafdo")
-                if "split_functions" not in all_unsupported_features_set:
-                    all_features.append("enable_fdo_split_functions")
+            all_features.append(feature_names.AUTOFDO)
+            if feature_names.MEMPROF_OPTIMIZE not in all_unsupported_features_set:
+                all_features.append(feature_names.ENABLE_AUTOFDO_MEMPROF_OPTIMIZE)
+            if feature_names.THIN_LTO not in all_unsupported_features_set:
+                all_features.append(feature_names.ENABLE_AFDO_THINLTO)
+            if feature_names.FSAFDO not in all_unsupported_features_set:
+                all_features.append(feature_names.ENABLE_FSAFDO)
+                if feature_names.SPLIT_FUNCTIONS not in all_unsupported_features_set:
+                    all_features.append(feature_names.ENABLE_FDO_SPLIT_FUNCTIONS)
 
         if branch_fdo_provider.branch_fdo_mode == "xbinary_fdo":
-            all_features.append("xbinaryfdo")
-            if "thin_lto" not in all_unsupported_features_set:
-                all_features.append("enable_xbinaryfdo_thinlto")
+            all_features.append(feature_names.XBINARYFDO)
+            if feature_names.THIN_LTO not in all_unsupported_features_set:
+                all_features.append(feature_names.ENABLE_XBINARYFDO_THINLTO)
 
     if cpp_configuration._fdo_prefetch_hints_label != None:
-        all_features.append("fdo_prefetch_hints")
+        all_features.append(feature_names.FDO_PREFETCH_HINTS)
 
     if enable_propeller_optimize:
-        all_features.append("propeller_optimize")
+        all_features.append(feature_names.PROPELLER_OPTIMIZE)
 
     for feature in all_features:
         if feature not in all_unsupported_features_set:
@@ -224,9 +225,9 @@
                 .format(cc_toolchain._toolchain_label, feature))
 
     if (cpp_configuration.force_pic() and
-        not feature_configuration.is_enabled("pic") and
-        not feature_configuration.is_enabled("supports_pic")):
+        not feature_configuration.is_enabled(feature_names.PIC) and
+        not feature_configuration.is_enabled(feature_names.SUPPORTS_PIC)):
         fail("PIC compilation is requested but the toolchain does not support it " +
-             "(feature named 'supports_pic' is not enabled)")
+             "(feature named '{}' is not enabled)".format(feature_names.SUPPORTS_PIC))
 
     return feature_configuration
diff --git a/tests/cc/testutil/toolchains/BUILD b/tests/cc/testutil/toolchains/BUILD
index b6999e1..b2df787 100644
--- a/tests/cc/testutil/toolchains/BUILD
+++ b/tests/cc/testutil/toolchains/BUILD
@@ -1,3 +1,4 @@
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
 load("@bazel_skylib//rules:common_settings.bzl", "string_flag", "string_list_flag")
 load("//cc:cc_library.bzl", "cc_library")
 load("//cc/toolchains:cc_toolchain.bzl", "cc_toolchain")
@@ -10,6 +11,14 @@
     "//tools/build_defs/cc/tests:__subpackages__",
 ])
 
+bzl_library(
+    name = "features",
+    srcs = ["features.bzl"],
+    deps = [
+        "//cc/common:feature_names_bzl",
+    ],
+)
+
 platform(
     name = "linux_x86_64",
     constraint_values = [
diff --git a/tests/cc/testutil/toolchains/features.bzl b/tests/cc/testutil/toolchains/features.bzl
index 6ded051..d610e2e 100644
--- a/tests/cc/testutil/toolchains/features.bzl
+++ b/tests/cc/testutil/toolchains/features.bzl
@@ -1,117 +1,120 @@
 """Defined mock toolchain features."""
 
+# Load features used elsewhere in rules_cc if possible.
+load("//cc/common:feature_names.bzl", "feature_names")
+
 FEATURE_NAMES = struct(
-    cpp_modules = "cpp_modules",
-    generate_pdb_file = "generate_pdb_file",
-    no_legacy_features = "no_legacy_features",
-    do_not_split_linking_cmdline = "do_not_split_linking_cmdline",
-    supports_dynamic_linker = "supports_dynamic_linker",
-    supports_interface_shared_libraries = "supports_interface_shared_libraries",
-    pic = "pic",
-    define_with_space = "define_with_space",
-    parse_headers = "parse_headers",
-    layering_check = "layering_check",
-    header_modules = "header_modules",
-    header_module_compile = "header_module_compile",
-    header_module_codegen = "header_module_codegen",
-    module_maps = "module_maps",
-    use_header_modules = "use_header_modules",
-    module_map_home_cwd = "module_map_home_cwd",
-    env_feature = "env_feature",
-    static_env_feature = "static_env_feature",
-    host = "host",
-    nonhost = "nonhost",
-    user_compile_flags = "user_compile_flags",
-    thin_lto = "thin_lto",
-    no_use_lto_indexing_bitcode_file = "no_use_lto_indexing_bitcode_file",
-    use_lto_native_object_directory = "use_lto_native_object_directory",
-    thin_lto_linkstatic_tests_use_shared_nonlto_backends = "thin_lto_linkstatic_tests_use_shared_nonlto_backends",
-    thin_lto_all_linkstatic_use_shared_nonlto_backends = "thin_lto_all_linkstatic_use_shared_nonlto_backends",
-    enable_afdo_thinlto = "enable_afdo_thinlto",
-    autofdo_implicit_thinlto = "autofdo_implicit_thinlto",
-    enable_fdo_thinlto = "enable_fdo_thinlto",
-    xbinaryfdo_implicit_thinlto = "xbinaryfdo_implicit_thinlto",
-    enable_xbinaryfdo_thinlto = "enable_xbinaryfdo_thinlto",
-    native_deps_link = "native_deps_link",
-    java_launcher_link = "java_launcher_link",
-    py_launcher_link = "py_launcher_link",
-    autofdo = "autofdo",
-    is_cc_fake_binary = "is_cc_fake_binary",
-    xbinaryfdo = "xbinaryfdo",
-    fdo_optimize = "fdo_optimize",
-    fdo_implicit_thinlto = "fdo_implicit_thinlto",
-    split_functions = "split_functions",
-    enable_fdo_split_functions = "enable_fdo_split_functions",
-    fdo_split_functions = "fdo_split_functions",
-    memprof_optimize = "memprof_optimize",
-    enable_fdo_memprof_optimize = "enable_fdo_memprof_optimize",
-    fdo_implicit_memprof_optimize = "fdo_implicit_memprof_optimize",
-    enable_autofdo_memprof_optimize = "enable_autofdo_memprof_optimize",
-    autofdo_implicit_memprof_optimize = "autofdo_implicit_memprof_optimize",
-    fdo_instrument = "fdo_instrument",
-    fsafdo = "fsafdo",
-    implicit_fsafdo = "implicit_fsafdo",
-    enable_fsafdo = "enable_fsafdo",
-    supports_pic = "supports_pic",
-    prefer_pic_for_opt_binaries = "prefer_pic_for_opt_binaries",
-    copy_dynamic_libraries_to_binary = "copy_dynamic_libraries_to_binary",
-    per_object_debug_info = "per_object_debug_info",
-    supports_start_end_lib = "supports_start_end_lib",
-    targets_windows = "targets_windows",
-    windows_export_all_symbols = "windows_export_all_symbols",
-    static_link_cpp_runtimes = "static_link_cpp_runtimes",
-    simple_compile_feature = "simple_compile_feature",
-    simple_link_feature = "simple_link_feature",
-    link_env = "link_env",
-    dynamic_linking_mode = "dynamic_linking_mode",
-    static_linking_mode = "static_linking_mode",
-    archive_param_file = "archive_param_file",
-    compiler_param_file = "compiler_param_file",
-    gcc_quoting_for_param_files = "gcc_quoting_for_param_files",
-    objcopy_embed_flags = "objcopy_embed_flags",
-    ld_embed_flags = "ld_embed_flags",
-    opt = "opt",
-    fastbuild = "fastbuild",
-    dbg = "dbg",
-    fission_flags_for_lto_backend = "fission_flags_for_lto_backend",
-    min_os_version_flag = "min_os_version_flag",
-    include_directories = "include_directories",
-    external_include_paths = "external_include_paths",
     absolute_path_directories = "absolute_path_directories",
-    from_package = "from_package",
+    archive_param_file = feature_names.ARCHIVE_PARAM_FILE,
+    autofdo = feature_names.AUTOFDO,
+    autofdo_implicit_memprof_optimize = "autofdo_implicit_memprof_optimize",
+    autofdo_implicit_thinlto = "autofdo_implicit_thinlto",
     change_tool = "change_tool",
-    module_map_without_extern_module = "module_map_without_extern_module",
-    generate_submodules = "generate_submodules",
-    foo = "foo_feature",
     check_additional_variables = "check_additional_variables_feature",
-    library_search_directories = "library_search_directories",
-    runtime_library_search_directories = "runtime_library_search_directories",
-    uses_ifso_variables = "uses_ifso_variables",
-    def_feature = "def",
-    strip_debug_symbols = "strip_debug_symbols",
-    disable_pbh = "disable_pbh",
-    optional_cc_flags_feature = "optional_cc_flags_feature",
+    compiler_param_file = "compiler_param_file",
+    copy_dynamic_libraries_to_binary = feature_names.COPY_DYNAMIC_LIBRARIES_TO_BINARY,
     cpp_compile_with_requirements = "cpp_compile_with_requirements",
-    no_copts_tokenization = "no_copts_tokenization",
-    generate_linkmap = "generate_linkmap",
-    shorten_virtual_includes = "shorten_virtual_includes",
-    preprocessor_defines = "preprocessor_defines",
-    skip_virtual_includes = "skip_virtual_includes",
-    no_dotd_file = "no_dotd_file",
-    llvm_profdata_env = "llvm_profdata_env",
+    cpp_modules = feature_names.CPP_MODULES,
+    dbg = "dbg",
+    debug_variables = "debug_variables",
+    def_feature = "def",
+    define_with_space = "define_with_space",
+    disable_cpp_link_path_mapping = feature_names.DISABLE_CPP_LINK_PATH_MAPPING,
+    disable_pbh = "disable_pbh",
+    do_not_split_linking_cmdline = "do_not_split_linking_cmdline",
+    dwp_env = "dwp_env",
+    dynamic_linking_mode = "dynamic_linking_mode",
+    enable_afdo_thinlto = feature_names.ENABLE_AFDO_THINLTO,
+    enable_autofdo_memprof_optimize = feature_names.ENABLE_AUTOFDO_MEMPROF_OPTIMIZE,
+    enable_fdo_memprof_optimize = feature_names.ENABLE_FDO_MEMPROF_OPTIMIZE,
+    enable_fdo_split_functions = feature_names.ENABLE_FDO_SPLIT_FUNCTIONS,
+    enable_fdo_thinlto = feature_names.ENABLE_FDO_THINLTO,
+    enable_fsafdo = feature_names.ENABLE_FSAFDO,
+    enable_xbinaryfdo_thinlto = feature_names.ENABLE_XBINARYFDO_THINLTO,
+    env_feature = "env_feature",
+    external_include_paths = feature_names.EXTERNAL_INCLUDE_PATHS,
+    fastbuild = "fastbuild",
+    fdo_implicit_memprof_optimize = "fdo_implicit_memprof_optimize",
+    fdo_implicit_thinlto = "fdo_implicit_thinlto",
+    fdo_instrument = feature_names.FDO_INSTRUMENT,
+    fdo_optimize = feature_names.FDO_OPTIMIZE,
+    fdo_prefetch_hints = "fdo_prefetch_hints",
+    fdo_split_functions = "fdo_split_functions",
+    fission_flags_for_lto_backend = "fission_flags_for_lto_backend",
+    foo = "foo_feature",
     force_pic_flags = "force_pic_flags",
+    from_package = "from_package",
+    fsafdo = feature_names.FSAFDO,
+    gcc_quoting_for_param_files = feature_names.GCC_QUOTING_FOR_PARAM_FILES,
+    generate_linkmap = feature_names.GENERATE_LINKMAP,
+    generate_pdb_file = feature_names.GENERATE_PDB_FILE,
+    generate_submodules = feature_names.GENERATE_SUBMODULES,
+    header_module_codegen = feature_names.HEADER_MODULE_CODEGEN,
+    header_module_compile = "header_module_compile",
+    header_modules = feature_names.HEADER_MODULES,
+    host = "host",
+    implicit_fsafdo = "implicit_fsafdo",
+    include_directories = "include_directories",
+    is_cc_fake_binary = "is_cc_fake_binary",
+    java_launcher_link = "java_launcher_link",
+    layering_check = "layering_check",
+    ld_embed_flags = "ld_embed_flags",
     libraries_to_link = "libraries_to_link",
+    library_search_directories = "library_search_directories",
+    link_env = "link_env",
+    llvm_profdata_env = "llvm_profdata_env",
+    memprof_optimize = feature_names.MEMPROF_OPTIMIZE,
+    min_os_version_flag = "min_os_version_flag",
+    module_map_home_cwd = feature_names.MODULE_MAP_HOME_CWD,
+    module_map_without_extern_module = feature_names.MODULE_MAP_WITHOUT_EXTERN_MODULE,
+    module_maps = feature_names.MODULE_MAPS,
+    native_deps_link = "native_deps_link",
+    no_copts_tokenization = feature_names.NO_COPTS_TOKENIZATION,
+    no_dotd_file = "no_dotd_file",
+    no_legacy_features = "no_legacy_features",
+    no_use_lto_indexing_bitcode_file = feature_names.NO_USE_LTO_INDEXING_BITCODE_FILE,
+    nonhost = "nonhost",
+    objcopy_embed_flags = "objcopy_embed_flags",
+    opt = "opt",
+    optional_cc_flags_feature = "optional_cc_flags_feature",
+    parse_headers = feature_names.PARSE_HEADERS,
+    per_object_debug_info = feature_names.PER_OBJECT_DEBUG_INFO,
+    pic = feature_names.PIC,
+    prefer_pic_for_opt_binaries = feature_names.PREFER_PIC_FOR_OPT_BINARIES,
+    preprocessor_defines = "preprocessor_defines",
     propeller_optimize = "propeller_optimize",
     propeller_optimize_thinlto_compile_actions = "propeller_optimize_thinlto_compile_actions",
-    fdo_prefetch_hints = "fdo_prefetch_hints",
-    uses_output_execpath = "uses_output_execpath",
+    py_launcher_link = "py_launcher_link",
+    runtime_library_search_directories = "runtime_library_search_directories",
+    shorten_virtual_includes = feature_names.SHORTEN_VIRTUAL_INCLUDES,
+    simple_compile_feature = "simple_compile_feature",
+    simple_link_feature = "simple_link_feature",
+    skip_virtual_includes = feature_names.SKIP_VIRTUAL_INCLUDES,
+    split_functions = feature_names.SPLIT_FUNCTIONS,
+    static_env_feature = "static_env_feature",
+    static_link_cpp_runtimes = feature_names.STATIC_LINK_CPP_RUNTIMES,
+    static_linking_mode = "static_linking_mode",
+    strip_debug_symbols = "strip_debug_symbols",
+    supports_dynamic_linker = feature_names.SUPPORTS_DYNAMIC_LINKER,
+    supports_interface_shared_libraries = feature_names.SUPPORTS_INTERFACE_SHARED_LIBRARIES,
+    supports_pic = feature_names.SUPPORTS_PIC,
+    supports_start_end_lib = feature_names.SUPPORTS_START_END_LIB,
+    targets_windows = feature_names.TARGETS_WINDOWS,
+    thin_lto = feature_names.THIN_LTO,
+    thin_lto_all_linkstatic_use_shared_nonlto_backends = feature_names.THIN_LTO_ALL_LINKSTATIC_USE_SHARED_NONLTO_BACKENDS,
+    thin_lto_linkstatic_tests_use_shared_nonlto_backends = feature_names.THIN_LTO_LINKSTATIC_TESTS_USE_SHARED_NONLTO_BACKENDS,
+    use_header_modules = feature_names.USE_HEADER_MODULES,
+    use_lto_native_object_directory = feature_names.USE_LTO_NATIVE_OBJECT_DIRECTORY,
+    user_compile_flags = "user_compile_flags",
+    uses_ifso_variables = "uses_ifso_variables",
     uses_is_cc_test = "uses_is_cc_test",
-    uses_strip_debug_symbols = "uses_strip_debug_symbols",
-    debug_variables = "debug_variables",
     uses_is_using_fission = "uses_is_using_fission",
+    uses_output_execpath = "uses_output_execpath",
+    uses_strip_debug_symbols = "uses_strip_debug_symbols",
     uses_sysroot = "uses_sysroot",
     uses_user_link_flags = "uses_user_link_flags",
     uses_whole_archive = "uses_whole_archive",
-    dwp_env = "dwp_env",
-    disable_cpp_link_path_mapping = "disable_cpp_link_path_mapping",
+    windows_export_all_symbols = "windows_export_all_symbols",
+    xbinaryfdo = feature_names.XBINARYFDO,
+    xbinaryfdo_implicit_thinlto = "xbinaryfdo_implicit_thinlto",
 )