Honor object extensions for ThinLTO merged artifacts (#853) The ThinLTO merged object is hard-coded with an `.o` suffix even when the toolchain configures `.obj` for object files. This leaves clang-cl/MSVC action graphs with `.obj` compilation outputs but a `.o` indexing output and final-link input. Derive the merged artifact suffix from the toolchain's `OBJECT_FILE` artifact category. Unix toolchains keep the default `.o`. Focused analysis coverage configures `.obj` and checks both the indexing output and final-link input. Closes #853 COPYBARA_INTEGRATE_REVIEW=https://github.com/bazelbuild/rules_cc/pull/853 from cerisier:cerisier/thinlto-merged-object-extension 58053078f34d1f025c6d9a97b54ea060c006da37 PiperOrigin-RevId: 968965384 Change-Id: I7868b32b2f0368421029d578da04add3f016ebdc
diff --git a/cc/private/link/lto_indexing_action.bzl b/cc/private/link/lto_indexing_action.bzl index 9e3e791..fe4a232 100644 --- a/cc/private/link/lto_indexing_action.bzl +++ b/cc/private/link/lto_indexing_action.bzl
@@ -14,7 +14,7 @@ """Functions that create LTO indexing action.""" load("@bazel_features//:features.bzl", "bazel_features") -load("//cc/common:cc_helper_internal.bzl", "root_relative_path") +load("//cc/common:cc_helper_internal.bzl", "root_relative_path", artifact_category = "artifact_category_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") @@ -222,8 +222,12 @@ # Create artifact for the merged object file, which is an object file that is created # during the LTO indexing step and needs to be passed to the final link. + object_file_extension = _cc_internal.get_artifact_name_extension_for_category( + cc_toolchain, + artifact_category.OBJECT_FILE, + ) thinlto_merged_object_file = \ - actions.declare_shareable_artifact(root_relative_path(output) + ".lto.merged.o") + actions.declare_shareable_artifact(root_relative_path(output) + ".lto.merged" + object_file_extension) action_outputs = \ ([lto_artifact.imports for lto_artifact in all_lto_artifacts if lto_artifact.index] +
diff --git a/tests/cc/common/cc_binary_thin_lto_tests.bzl b/tests/cc/common/cc_binary_thin_lto_tests.bzl index 5cbb1d1..0d2aa99 100644 --- a/tests/cc/common/cc_binary_thin_lto_tests.bzl +++ b/tests/cc/common/cc_binary_thin_lto_tests.bzl
@@ -176,6 +176,32 @@ ), ) +def _test_thin_lto_merged_object_uses_toolchain_extension(name, **kwargs): + util.helper_target( + cc_binary, + name = name + "/bin", + srcs = ["hello.cc"], + ) + cc_analysis_test( + name = name, + impl = _test_thin_lto_merged_object_uses_toolchain_extension_impl, + target = name + "/bin", + test_features = ["thin_lto", "supports_start_end_lib"], + config_settings = { + str(Label("//tests/cc/testutil/toolchains:object_file_extension")): ".obj", + }, + **kwargs + ) + +def _test_thin_lto_merged_object_uses_toolchain_extension_impl(env, target): + merged_object = target.label.name.split("/")[-1] + ".lto.merged.obj" + + index_action = env.expect.that_target(target).action_named("CppLTOIndexing") + index_action.outputs().contains_predicate(matching.file_basename_equals(merged_object)) + + link_action = env.expect.that_target(target).action_named("CppLink") + link_action.inputs().contains_predicate(matching.file_basename_equals(merged_object)) + def _test_thin_lto_linkshared(name, **kwargs): util.helper_target( cc_library, @@ -2345,6 +2371,7 @@ # These tests fail on Bazel 7 and 8, run only for Bazel 9+. if bazel_features.cc.cc_common_is_in_rules_cc: + tests.append(_test_thin_lto_merged_object_uses_toolchain_extension) tests.append(_test_thin_lto_linkshared) tests.append(_test_thin_lto_backend_env) tests.append(_test_linkstatic_cc_test)
diff --git a/tests/cc/testutil/toolchains/BUILD b/tests/cc/testutil/toolchains/BUILD index 02fea23..45dd6af 100644 --- a/tests/cc/testutil/toolchains/BUILD +++ b/tests/cc/testutil/toolchains/BUILD
@@ -1,4 +1,4 @@ -load("@bazel_skylib//rules:common_settings.bzl", "string_list_flag") +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") load("//cc/toolchains:cc_toolchain_alias.bzl", "cc_toolchain_alias") @@ -42,6 +42,11 @@ build_setting_default = [], ) +string_flag( + name = "object_file_extension", + build_setting_default = "", +) + # "everything" is a filegroup that the implementation of --grte_top (more specifically, the # LibcTopLabelConverter in # third_party/bazel/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java)
diff --git a/tests/cc/testutil/toolchains/cc_toolchain_config.bzl b/tests/cc/testutil/toolchains/cc_toolchain_config.bzl index 50fefe6..894e0fb 100644 --- a/tests/cc/testutil/toolchains/cc_toolchain_config.bzl +++ b/tests/cc/testutil/toolchains/cc_toolchain_config.bzl
@@ -2053,6 +2053,9 @@ for category, values in ctx.attr.artifact_name_patterns.items(): artifact_name_patterns.append(_get_artifact_name_pattern(category, values[0], values[1])) + object_file_extension = ctx.attr._object_file_extension[BuildSettingInfo].value + if object_file_extension: + artifact_name_patterns.append(_get_artifact_name_pattern("object_file", "", object_file_extension)) action_configs = [] @@ -2145,6 +2148,7 @@ "make_variables": attr.string_dict(), "_with_features": attr.label(default = Label("//tests/cc/testutil/toolchains:with_features")), "_with_action_configs": attr.label(default = Label("//tests/cc/testutil/toolchains:with_action_configs")), + "_object_file_extension": attr.label(default = Label("//tests/cc/testutil/toolchains:object_file_extension")), }, provides = [CcToolchainConfigInfo], executable = True,