From 8db3aad9e0669627157ea7259774a70b9fe95950 Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Fri, 31 Jul 2026 14:05:46 -0400 Subject: [PATCH] Use File.is_directory for C++ tree artifacts --- cc/private/compile/compile.bzl | 10 +-- .../cc_library_configured_target_tests.bzl | 81 +++++++++++++++++++ 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/cc/private/compile/compile.bzl b/cc/private/compile/compile.bzl index d1ca4ad1f..526e94cc2 100644 --- a/cc/private/compile/compile.bzl +++ b/cc/private/compile/compile.bzl @@ -419,7 +419,7 @@ def _add_suitable_headers_to_compilation_unit_sources( headers_with_labels: A list of (File, Label) tuples of header files. """ for header, label in headers_with_labels: - is_header = "." + header.extension in extensions.CC_HEADER or _cc_internal.is_tree_artifact(header) + is_header = "." + header.extension in extensions.CC_HEADER or header.is_directory is_textual_include = "." + header.extension in extensions.CC_TEXTUAL_INCLUDE if is_header and not is_textual_include: compilation_unit_sources[header] = _CppSourceInfo( @@ -440,7 +440,7 @@ def _add_suitable_srcs_to_compilation_unit_sources( # TODO(b/413333884): If it's a non-source file we ignore it. This is only the case for # precompiled files which should be forbidden in srcs of cc_library|binary and instead be # migrated to cc_import rules. - if "." + source.extension in source_category or _cc_internal.is_tree_artifact(source): + if "." + source.extension in source_category or source.is_directory: compilation_unit_sources[source] = _CppSourceInfo( label = label, source = source, @@ -1239,13 +1239,13 @@ def _create_cc_compile_actions( source_file = cpp_source.file source_type = cpp_source.type source_label = cpp_source.label - if not _cc_internal.is_tree_artifact(source_file) and source_type == CPP_SOURCE_TYPE_HEADER: + if not source_file.is_directory and source_type == CPP_SOURCE_TYPE_HEADER: continue output_name = output_name_map[source_file] bitcode_output = feature_configuration.is_enabled("thin_lto") and (("." + source_file.extension) in LTO_SOURCE_EXTENSIONS) - if not _cc_internal.is_tree_artifact(source_file): + if not source_file.is_directory: compiled_basenames.add(_basename_without_extension(source_file)) _create_pic_nopic_compile_source_actions( action_construction_context = action_construction_context, @@ -1308,7 +1308,7 @@ def _create_cc_compile_actions( source_file = cpp_source.file source_type = cpp_source.type source_label = cpp_source.label - if source_type != CPP_SOURCE_TYPE_HEADER or _cc_internal.is_tree_artifact(source_file): + if source_type != CPP_SOURCE_TYPE_HEADER or source_file.is_directory: continue if (feature_configuration.is_enabled("validates_layering_check_in_textual_hdrs") and _basename_without_extension(source_file) in compiled_basenames): diff --git a/tests/cc/common/cc_library_configured_target_tests.bzl b/tests/cc/common/cc_library_configured_target_tests.bzl index 4b583bf4e..3ba820ee6 100644 --- a/tests/cc/common/cc_library_configured_target_tests.bzl +++ b/tests/cc/common/cc_library_configured_target_tests.bzl @@ -30,6 +30,20 @@ def _cc_dep_with_runfiles_impl(ctx): _cc_dep_with_runfiles = rule(implementation = _cc_dep_with_runfiles_impl) +def _generated_tree_artifact_impl(ctx): + directory = ctx.actions.declare_directory(ctx.label.name) + ctx.actions.run_shell( + outputs = [directory], + arguments = [directory.path, ctx.attr.filename], + command = "mkdir -p \"$1\" && touch \"$1/$2\"", + ) + return [DefaultInfo(files = depset([directory]))] + +_generated_tree_artifact = rule( + implementation = _generated_tree_artifact_impl, + attrs = {"filename": attr.string(mandatory = True)}, +) + def _test_cc_library_data_in_runfiles(name, **kwargs): srcs_runfiles = name + "_srcs_runfiles" deps_runfiles = name + "_deps_runfiles" @@ -126,6 +140,71 @@ def _test_absolute_includes_windows_fail_impl(env, target): ), ) +def _test_generated_tree_artifact_sources(name): + source_tree = name + "_sources" + util.helper_target( + _generated_tree_artifact, + name = source_tree, + filename = "generated.cc", + ) + util.helper_target( + cc_library, + name = name + "_lib", + srcs = [source_tree], + ) + cc_analysis_test( + name = name, + impl = _test_generated_tree_artifact_sources_impl, + target = name + "_lib", + ) + +def _test_generated_tree_artifact_sources_impl(env, target): + compilation_outputs = target[OutputGroupInfo].compilation_outputs.to_list() + env.expect.that_collection(compilation_outputs).contains_predicate( + matching.custom( + "compiled generated source directory", + lambda artifact: artifact.is_directory and artifact.basename.endswith("_sources"), + ), + ) + +def _test_generated_tree_artifact_headers(name): + header_tree = name + "_headers" + util.helper_target( + _generated_tree_artifact, + name = header_tree, + filename = "generated.h", + ) + util.helper_target( + cc_library, + name = name + "_lib", + srcs = ["source.cc"], + hdrs = [header_tree], + ) + cc_analysis_test( + name = name, + impl = _test_generated_tree_artifact_headers_impl, + target = name + "_lib", + test_features = ["parse_headers"], + config_settings = { + "//command_line_option:process_headers_in_dependencies": True, + }, + ) + +def _test_generated_tree_artifact_headers_impl(env, target): + env.expect.that_collection(target[CcInfo].compilation_context.headers.to_list()).contains_predicate( + matching.custom( + "generated header directory", + lambda artifact: artifact.is_directory and artifact.basename.endswith("_headers"), + ), + ) + compilation_outputs = target[OutputGroupInfo].compilation_outputs.to_list() + env.expect.that_collection(compilation_outputs).contains_predicate( + matching.custom( + "processed generated header directory", + lambda artifact: artifact.is_directory and artifact.basename.endswith("_headers"), + ), + ) + def cc_library_configured_target_tests(name): test_suite( name = name, @@ -133,5 +212,7 @@ def cc_library_configured_target_tests(name): _test_cc_library_data_in_runfiles, _test_absolute_includes_fail, _test_absolute_includes_windows_fail, + _test_generated_tree_artifact_sources, + _test_generated_tree_artifact_headers, ] if bazel_features.cc.cc_common_is_in_rules_cc else [], )