diff --git a/cc/common/cc_helper_internal.bzl b/cc/common/cc_helper_internal.bzl index 735e050f2..eb613031e 100644 --- a/cc/common/cc_helper_internal.bzl +++ b/cc/common/cc_helper_internal.bzl @@ -282,8 +282,69 @@ _artifact_categories = [ _ArtifactCategoryInfo("CLIF_OUTPUT_PROTO", "", ".opb"), ] +_ARTIFACT_CATEGORIES_BY_NAME = { + category.name: category + for category in _artifact_categories +} + artifact_category_names = struct(**{ac.name: ac.name for ac in _artifact_categories}) +def artifact_name_pattern_overrides_from_toolchain_config(toolchain_config_info): + """Returns the artifact name pattern overrides in toolchain_config_info. + + Args: + toolchain_config_info: A CcToolchainConfigInfo. + + Returns: + A dict mapping artifact category names to (prefix, extension) tuples. + """ + overrides = {} + for pattern in toolchain_config_info._artifact_name_patterns_DO_NOT_USE: + category = _ARTIFACT_CATEGORIES_BY_NAME[pattern.category_name.upper()] + prefix = pattern.prefix or "" + extension = pattern.extension or "" + if prefix != category.default_prefix or extension != category.default_extension: + overrides[category.name] = (prefix, extension) + return overrides + +def get_artifact_name_for_category(*, cc_toolchain, category, output_name): + """Returns output_name with the artifact name pattern for category applied. + + Args: + cc_toolchain: A CcToolchainInfo. + category: An artifact category name. + output_name: The output path before applying the artifact name pattern. + + Returns: + The output path with the artifact name pattern applied to its basename. + """ + pattern = cc_toolchain._artifact_name_pattern_overrides.get(category) + if pattern == None: + category_info = _ARTIFACT_CATEGORIES_BY_NAME[category] + prefix = category_info.default_prefix + extension = category_info.default_extension + else: + prefix, extension = pattern + + normalized_output_name = paths.normalize(output_name) if output_name else output_name + artifact_name = prefix + paths.basename(normalized_output_name) + extension + return paths.join(paths.dirname(normalized_output_name), artifact_name) + +def get_artifact_name_extension_for_category(*, cc_toolchain, category): + """Returns the cc_toolchain extension for category. + + Args: + cc_toolchain: A CcToolchainInfo. + category: An artifact category name. + + Returns: + The configured or default extension for category. + """ + pattern = cc_toolchain._artifact_name_pattern_overrides.get(category) + if pattern != None: + return pattern[1] + return _ARTIFACT_CATEGORIES_BY_NAME[category].default_extension + output_subdirectories = struct( OBJS = "_objs", PIC_OBJS = "_pic_objs", diff --git a/cc/private/cc_common.bzl b/cc/private/cc_common.bzl index 8db674306..56e8d3d71 100644 --- a/cc/private/cc_common.bzl +++ b/cc/private/cc_common.bzl @@ -15,6 +15,7 @@ load( "//cc/common:cc_helper_internal.bzl", + "get_artifact_name_for_category", _CREATE_COMPILE_ACTION_API_ALLOWLISTED_PACKAGES = "CREATE_COMPILE_ACTION_API_ALLOWLISTED_PACKAGES", _PRIVATE_STARLARKIFICATION_ALLOWLIST = "PRIVATE_STARLARKIFICATION_ALLOWLIST", ) @@ -658,7 +659,7 @@ def _get_cc_native_library_info_provider(): def _get_artifact_name_for_category(*, cc_toolchain, category, output_name): _cc_internal.check_private_api(allowlist = _PRIVATE_STARLARKIFICATION_ALLOWLIST) - return _cc_internal.get_artifact_name_for_category( + return get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = category, output_name = output_name, diff --git a/cc/private/compile/compile.bzl b/cc/private/compile/compile.bzl index d7272e1d2..6be762ce2 100644 --- a/cc/private/compile/compile.bzl +++ b/cc/private/compile/compile.bzl @@ -25,6 +25,7 @@ load( "CPP_SOURCE_TYPE_HEADER", "CPP_SOURCE_TYPE_SOURCE", "extensions", + "get_artifact_name_for_category", "should_create_per_object_debug_info", _use_pic_for_binaries = "use_pic_for_binaries", _use_pic_for_dynamic_libs = "use_pic_for_dynamic_libs", @@ -536,7 +537,7 @@ def _create_scan_deps_action( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.INCLUDED_FILE_LIST, output_name = ddi_output_name, @@ -676,7 +677,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_INFO, output_name = label.name, @@ -693,7 +694,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( source_label = cpp_source.label if use_pic: - output_name_base = _cc_internal.get_artifact_name_for_category( + output_name_base = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.PIC_FILE, output_name = output_name, @@ -706,7 +707,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = output_category, output_name = output_name_base, @@ -717,7 +718,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( # dependencies information are put in .ddi file # the format is https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html - ddi_output_name = _cc_internal.get_artifact_name_for_category( + ddi_output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_DDI, output_name = output_name_base, @@ -769,7 +770,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( bitcode_output = feature_configuration.is_enabled("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( + output_name_base = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.PIC_FILE, output_name = output_name, @@ -785,7 +786,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_MODMAP, output_name = output_name_base, @@ -795,7 +796,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_MODMAP_INPUT, output_name = output_name_base, @@ -865,7 +866,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( bitcode_output = feature_configuration.is_enabled("thin_lto") and (("." + source_artifact.extension) in LTO_SOURCE_EXTENSIONS) if use_pic: - output_name_base = _cc_internal.get_artifact_name_for_category( + output_name_base = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.PIC_FILE, output_name = output_name, @@ -883,7 +884,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_MODMAP, output_name = output_name_base, @@ -893,14 +894,14 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_MODMAP_INPUT, output_name = output_name_base, ), ) - ddi_output_name = _cc_internal.get_artifact_name_for_category( + ddi_output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_DDI, output_name = output_name_base, @@ -937,7 +938,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_MODMAP, output_name = output_name_base, @@ -947,7 +948,7 @@ def _create_cc_compile_actions_with_cpp20_module_helper( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.CPP_MODULES_MODMAP_INPUT, output_name = output_name_base, @@ -1313,7 +1314,7 @@ def _create_cc_compile_actions( _basename_without_extension(source_file) in compiled_basenames): continue - output_name_base = _cc_internal.get_artifact_name_for_category( + output_name_base = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.GENERATED_HEADER, output_name = output_name_map[source_file], @@ -1322,7 +1323,7 @@ def _create_cc_compile_actions( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.PROCESSED_HEADER, output_name = output_name_base, @@ -1332,7 +1333,7 @@ def _create_cc_compile_actions( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.INCLUDED_FILE_LIST, output_name = output_name_base, @@ -1345,7 +1346,7 @@ def _create_cc_compile_actions( action_construction_context, label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.SERIALIZED_DIAGNOSTICS_FILE, output_name = output_name_base, @@ -1546,7 +1547,7 @@ def _create_compile_source_action( progress_message_prefix = None): output_pic_nopic_name = output_name if use_pic: - output_pic_nopic_name = _cc_internal.get_artifact_name_for_category( + output_pic_nopic_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.PIC_FILE, output_name = output_name, @@ -1558,7 +1559,7 @@ def _create_compile_source_action( ctx = action_construction_context, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = output_category, output_name = output_pic_nopic_name, @@ -1785,7 +1786,7 @@ def _create_temps_action( ctx = action_construction_context, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = category, output_name = output_name, @@ -1795,7 +1796,7 @@ def _create_temps_action( ctx = action_construction_context, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.GENERATED_ASSEMBLY, output_name = output_name, @@ -1953,7 +1954,7 @@ def _create_module_codegen_action( ctx = action_construction_context, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.COVERAGE_DATA_FILE, output_name = output_name, @@ -1981,7 +1982,7 @@ def _create_module_codegen_action( ctx = action_construction_context, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.OBJECT_FILE, output_name = output_name, @@ -1995,7 +1996,7 @@ def _create_module_codegen_action( ctx = action_construction_context, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.INCLUDED_FILE_LIST, output_name = output_name, @@ -2008,7 +2009,7 @@ def _create_module_codegen_action( ctx = action_construction_context, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.SERIALIZED_DIAGNOSTICS_FILE, output_name = output_name, @@ -2227,12 +2228,12 @@ def _maybe_declare_dotd_file( if (_use_dotd_file(feature_configuration, source_artifact)): dotd_base_name = output_name if category != artifact_category.OBJECT_FILE and category != artifact_category.PROCESSED_HEADER: - dotd_base_name = _cc_internal.get_artifact_name_for_category( + dotd_base_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = category, output_name = output_name, ) - dotd_name = _cc_internal.get_artifact_name_for_category( + dotd_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.INCLUDED_FILE_LIST, output_name = dotd_base_name, @@ -2257,12 +2258,12 @@ def _maybe_declare_diagnostics_file( if feature_configuration.is_enabled("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( + base_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = category, output_name = output_name, ) - diagnostics_file_name = _cc_internal.get_artifact_name_for_category( + diagnostics_file_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.SERIALIZED_DIAGNOSTICS_FILE, output_name = base_name, @@ -2289,7 +2290,7 @@ def _maybe_declare_gcno_file( ctx = ctx, label = label, configuration = configuration, - output_name = _cc_internal.get_artifact_name_for_category( + output_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.COVERAGE_DATA_FILE, output_name = output_name, diff --git a/cc/private/link/cc_linking_helper.bzl b/cc/private/link/cc_linking_helper.bzl index b668e008a..6c65e1003 100644 --- a/cc/private/link/cc_linking_helper.bzl +++ b/cc/private/link/cc_linking_helper.bzl @@ -18,6 +18,7 @@ A module to create C/C++ link actions in a consistent way. load("@bazel_skylib//lib:paths.bzl", "paths") load( "//cc/common:cc_helper_internal.bzl", + "get_artifact_name_for_category", "root_relative_path", "wrap_with_check_private_api", _use_pic_for_binaries = "use_pic_for_binaries", @@ -512,7 +513,7 @@ def _construct_dynamic_library_to_link( def _get_linked_artifact(actions, name, link_target_type, cc_toolchain, linked_dll_name_suffix = ""): maybe_pic_name = name if link_target_type.is_pic: - maybe_pic_name = _cc_internal.get_artifact_name_for_category( + maybe_pic_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = artifact_category.PIC_FILE, output_name = maybe_pic_name, @@ -521,7 +522,7 @@ def _get_linked_artifact(actions, name, link_target_type, cc_toolchain, linked_d linked_name = maybe_pic_name if link_target_type == LINK_TARGET_TYPE.NODEPS_DYNAMIC_LIBRARY: linked_name += linked_dll_name_suffix - linked_name = _cc_internal.get_artifact_name_for_category( + linked_name = get_artifact_name_for_category( cc_toolchain = cc_toolchain, category = link_target_type.linker_output, output_name = linked_name, diff --git a/cc/private/link/link_build_variables.bzl b/cc/private/link/link_build_variables.bzl index 256fb3d42..d7822efcd 100644 --- a/cc/private/link/link_build_variables.bzl +++ b/cc/private/link/link_build_variables.bzl @@ -26,7 +26,7 @@ and formatting different types of libraries. For an example specification, see `unix_cc_toolchain_config.bzl` """ -load("//cc/common:cc_helper_internal.bzl", "get_relative_path", "should_create_per_object_debug_info", artifact_category = "artifact_category_names") +load("//cc/common:cc_helper_internal.bzl", "get_artifact_name_extension_for_category", "get_relative_path", "should_create_per_object_debug_info", artifact_category = "artifact_category_names") load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal") # Enum covering all build variables we create for all various C++ linking actions @@ -377,9 +377,9 @@ def setup_lto_indexing_variables( ) if not feature_configuration.is_enabled("no_use_lto_indexing_bitcode_file"): - object_file_extension = _cc_internal.get_artifact_name_extension_for_category( - cc_toolchain, - artifact_category.OBJECT_FILE, + object_file_extension = get_artifact_name_extension_for_category( + cc_toolchain = cc_toolchain, + category = artifact_category.OBJECT_FILE, ) # TODO(b/338618120): ".indexing.o" should be coming from Starlark definitions of CppFileTypes diff --git a/cc/private/rules_impl/BUILD b/cc/private/rules_impl/BUILD index 1e11a5b36..1b25a8d70 100644 --- a/cc/private/rules_impl/BUILD +++ b/cc/private/rules_impl/BUILD @@ -148,6 +148,7 @@ bzl_library( "//cc:__subpackages__", "@cc_compatibility_proxy//:__pkg__", ], + deps = ["//cc/common:cc_helper_internal_bzl"], ) bzl_library( diff --git a/cc/private/rules_impl/cc_toolchain_info.bzl b/cc/private/rules_impl/cc_toolchain_info.bzl index 639d29615..2accb8c87 100644 --- a/cc/private/rules_impl/cc_toolchain_info.bzl +++ b/cc/private/rules_impl/cc_toolchain_info.bzl @@ -15,6 +15,8 @@ Definition of CcToolchainInfo provider. """ +load("//cc/common:cc_helper_internal.bzl", "artifact_name_pattern_overrides_from_toolchain_config") + visibility(["//cc/..."]) def _needs_pic_for_dynamic_libraries(*, feature_configuration): @@ -128,6 +130,7 @@ def _create_cc_toolchain_info( _compiler_files = compiler_files, _dwp_files = dwp_files, _builtin_include_files = builtin_include_files, + _artifact_name_pattern_overrides = artifact_name_pattern_overrides_from_toolchain_config(toolchain_config_info), _legacy_cc_flags_make_variable = legacy_cc_flags_make_variable, _additional_make_variables = additional_make_variables, _all_files_including_libc = all_files_including_libc, @@ -219,6 +222,7 @@ CcToolchainInfo, _ = provider( "_compiler_files": "INTERNAL API, DO NOT USE!", "_dwp_files": "INTERNAL API, DO NOT USE!", "_builtin_include_files": "INTERNAL API, DO NOT USE!", + "_artifact_name_pattern_overrides": "INTERNAL API, DO NOT USE!", # TODO(b/65151735): Remove when cc_flags is entirely from features. "_legacy_cc_flags_make_variable": "INTERNAL API, DO NOT USE!", "_additional_make_variables": "INTERNAL API, DO NOT USE!", diff --git a/tests/cc/common/cc_common_test.bzl b/tests/cc/common/cc_common_test.bzl index 678097a8c..5497ff954 100644 --- a/tests/cc/common/cc_common_test.bzl +++ b/tests/cc/common/cc_common_test.bzl @@ -5,10 +5,75 @@ load("@rules_testing//lib:analysis_test.bzl", "test_suite") load("@rules_testing//lib:truth.bzl", "matching") load("@rules_testing//lib:util.bzl", "TestingAspectInfo", "util") load("//cc:cc_library.bzl", "cc_library") +load("//cc/common:cc_helper_internal.bzl", "artifact_name_pattern_overrides_from_toolchain_config", "get_artifact_name_extension_for_category", "get_artifact_name_for_category") load("//cc/common:cc_info.bzl", "CcInfo") load("//tests/cc/testutil:cc_analysis_test.bzl", "cc_analysis_test") load("//tests/cc/testutil:cc_info_subject.bzl", "cc_info_subject") +def _test_get_artifact_name_for_category(env): + default_toolchain = struct(_artifact_name_pattern_overrides = {}) + env.expect.that_str( + get_artifact_name_for_category( + cc_toolchain = default_toolchain, + category = "STATIC_LIBRARY", + output_name = "foo/bar", + ), + ).equals("foo/libbar.a") + env.expect.that_str( + get_artifact_name_extension_for_category( + cc_toolchain = default_toolchain, + category = "OBJECT_FILE", + ), + ).equals(".o") + env.expect.that_str( + get_artifact_name_for_category( + cc_toolchain = default_toolchain, + category = "EXECUTABLE", + output_name = "foo", + ), + ).equals("foo") + env.expect.that_str( + get_artifact_name_for_category( + cc_toolchain = default_toolchain, + category = "STATIC_LIBRARY", + output_name = "foo/baz/../bar", + ), + ).equals("foo/libbar.a") + + toolchain_config = struct( + _artifact_name_patterns_DO_NOT_USE = [ + struct( + category_name = "static_library", + extension = ".lib", + prefix = None, + ), + struct( + category_name = "object_file", + extension = ".o", + prefix = "", + ), + ], + ) + configured_toolchain = struct( + _artifact_name_pattern_overrides = artifact_name_pattern_overrides_from_toolchain_config(toolchain_config), + ) + env.expect.that_str( + get_artifact_name_for_category( + cc_toolchain = configured_toolchain, + category = "STATIC_LIBRARY", + output_name = "foo/bar", + ), + ).equals("foo/bar.lib") + env.expect.that_str( + get_artifact_name_extension_for_category( + cc_toolchain = configured_toolchain, + category = "STATIC_LIBRARY", + ), + ).equals(".lib") + env.expect.that_dict(configured_toolchain._artifact_name_pattern_overrides).contains_exactly({ + "STATIC_LIBRARY": ("", ".lib"), + }) + def _test_same_cc_file_twice(name): util.helper_target( native.filegroup, @@ -508,5 +573,6 @@ def cc_common_tests(name): ]) test_suite( name = name, + basic_tests = [_test_get_artifact_name_for_category], tests = tests, )