diff --git a/swift/internal/linking.bzl b/swift/internal/linking.bzl index 6d4336478..04b187b04 100644 --- a/swift/internal/linking.bzl +++ b/swift/internal/linking.bzl @@ -86,16 +86,21 @@ def _register_static_library_link_action( progress_message = "Linking {}".format(output.short_path), ) -def register_libraries_to_link( +def create_linker_input( + *, actions, alwayslink, cc_feature_configuration, + compilation_outputs, is_dynamic, is_static, library_name, objects, - swift_toolchain): - """Declares the requested libraries and registers actions to link them. + owner, + swift_toolchain, + additional_inputs = [], + user_link_flags = []): + """Creates a linker input for a library to link and additional inputs/flags. Args: actions: The object used to register actions. @@ -104,17 +109,26 @@ def register_libraries_to_link( argument is ignored if `is_static` is False. cc_feature_configuration: The C++ feature configuration to use when constructing the action. + compilation_outputs: The compilation outputs from a Swift compile + action, as returned by `swift_common.compile`, or None. is_dynamic: If True, declare and link a dynamic library. is_static: If True, declare and link a static library. library_name: The basename (without extension) of the libraries to declare. objects: A list of `File`s denoting object (`.o`) files that will be linked. + owner: The `Label` of the target that owns this linker input. swift_toolchain: The Swift toolchain provider to use when constructing the action. + additional_inputs: A list of extra `File` inputs passed to the linking + action. + user_link_flags: A list of extra flags to pass to the linking command. Returns: - A `LibraryToLink` object containing the libraries that were created. + A tuple containing two elements: + + 1. A `LinkerInput` object containing the library that was created. + 2. The single `LibraryToLink` object that is inside the linker input. """ dynamic_library = None if is_dynamic: @@ -137,7 +151,7 @@ def register_libraries_to_link( else: static_library = None - return cc_common.create_library_to_link( + library_to_link = cc_common.create_library_to_link( actions = actions, alwayslink = alwayslink, cc_toolchain = swift_toolchain.cc_toolchain_info, @@ -145,6 +159,18 @@ def register_libraries_to_link( pic_static_library = static_library, dynamic_library = dynamic_library, ) + linker_input = cc_common.create_linker_input( + owner = owner, + libraries = depset([library_to_link]), + additional_inputs = depset( + compilation_outputs.linker_inputs + additional_inputs, + ), + user_link_flags = depset( + compilation_outputs.linker_flags + user_link_flags, + ), + ) + + return linker_input, library_to_link def register_link_binary_action( actions, @@ -156,6 +182,7 @@ def register_link_binary_action( name, objects, output_type, + owner, stamp, swift_toolchain, user_link_flags): @@ -178,6 +205,7 @@ def register_link_binary_action( objects: A list of object (.o) files that will be passed to the linker. output_type: A string indicating the output type; "executable" or "dynamic_library". + owner: The `Label` of the target that owns this linker input. stamp: A tri-state value (-1, 0, or 1) that specifies whether link stamping is enabled. See `cc_common.link` for details about the behavior of this argument. @@ -223,7 +251,12 @@ def register_link_binary_action( linking_contexts.append( cc_common.create_linking_context( - user_link_flags = dep_link_flags, + linker_inputs = depset([ + cc_common.create_linker_input( + owner = owner, + user_link_flags = depset(dep_link_flags), + ), + ]), ), ) diff --git a/swift/internal/swift_binary_test.bzl b/swift/internal/swift_binary_test.bzl index 6d0d544d3..cb394f563 100644 --- a/swift/internal/swift_binary_test.bzl +++ b/swift/internal/swift_binary_test.bzl @@ -246,6 +246,7 @@ def _swift_linking_rule_impl( name = ctx.label.name, objects = objects_to_link, output_type = "executable", + owner = ctx.label, stamp = ctx.attr.stamp, swift_toolchain = swift_toolchain, user_link_flags = user_link_flags, diff --git a/swift/internal/swift_grpc_library.bzl b/swift/internal/swift_grpc_library.bzl index c7deaaefd..6be91af5b 100644 --- a/swift/internal/swift_grpc_library.bzl +++ b/swift/internal/swift_grpc_library.bzl @@ -26,7 +26,7 @@ load( "SWIFT_FEATURE_GENERATE_FROM_RAW_PROTO_FILES", "SWIFT_FEATURE_NO_GENERATED_HEADER", ) -load(":linking.bzl", "register_libraries_to_link") +load(":linking.bzl", "create_linker_input") load( ":proto_gen_utils.bzl", "declare_generated_files", @@ -292,16 +292,18 @@ def _swift_grpc_library_impl(ctx): target_name = ctx.label.name, ) - library_to_link = register_libraries_to_link( + linker_input, library_to_link = create_linker_input( actions = ctx.actions, alwayslink = False, cc_feature_configuration = swift_common.cc_feature_configuration( feature_configuration = feature_configuration, ), + compilation_outputs = compilation_outputs, is_dynamic = False, is_static = True, library_name = ctx.label.name, objects = compilation_outputs.object_files, + owner = ctx.label, swift_toolchain = swift_toolchain, ) @@ -319,7 +321,7 @@ def _swift_grpc_library_impl(ctx): create_cc_info( cc_infos = get_providers(compile_deps, CcInfo), compilation_outputs = compilation_outputs, - libraries_to_link = [library_to_link], + linker_inputs = [linker_input], ), deps[0][SwiftProtoInfo], swift_common.create_swift_info( diff --git a/swift/internal/swift_import.bzl b/swift/internal/swift_import.bzl index 7fdfd3f31..079feeb3a 100644 --- a/swift/internal/swift_import.bzl +++ b/swift/internal/swift_import.bzl @@ -38,15 +38,18 @@ def _swift_import_impl(ctx): unsupported_features = ctx.disabled_features, ) - libraries_to_link = [ - cc_common.create_library_to_link( - actions = ctx.actions, - cc_toolchain = cc_toolchain, - feature_configuration = cc_feature_configuration, - static_library = archive, - ) - for archive in archives - ] + linker_input = cc_common.create_linker_input( + owner = ctx.label, + libraries = depset([ + cc_common.create_library_to_link( + actions = ctx.actions, + cc_toolchain = cc_toolchain, + feature_configuration = cc_feature_configuration, + static_library = archive, + ) + for archive in archives + ]), + ) providers = [ DefaultInfo( @@ -59,7 +62,7 @@ def _swift_import_impl(ctx): ), create_cc_info( cc_infos = get_providers(deps, CcInfo), - libraries_to_link = libraries_to_link, + linker_inputs = [linker_input], ), # Propagate an `Objc` provider so that Apple-specific rules like # apple_binary` will link the imported library properly. Typically we'd diff --git a/swift/internal/swift_library.bzl b/swift/internal/swift_library.bzl index 374b5184e..bf7d49644 100644 --- a/swift/internal/swift_library.bzl +++ b/swift/internal/swift_library.bzl @@ -28,7 +28,7 @@ load( "SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION", "SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS", ) -load(":linking.bzl", "register_libraries_to_link") +load(":linking.bzl", "create_linker_input") load(":providers.bzl", "SwiftInfo", "SwiftToolchainInfo") load(":swift_common.bzl", "swift_common") load( @@ -179,17 +179,21 @@ def _swift_library_impl(ctx): else: clang_module = None - library_to_link = register_libraries_to_link( + linker_input, library_to_link = create_linker_input( actions = ctx.actions, + additional_inputs = additional_inputs, alwayslink = ctx.attr.alwayslink, cc_feature_configuration = swift_common.cc_feature_configuration( feature_configuration = feature_configuration, ), + compilation_outputs = compilation_outputs, is_dynamic = False, is_static = True, library_name = ctx.label.name, objects = compilation_outputs.object_files, + owner = ctx.label, swift_toolchain = swift_toolchain, + user_link_flags = linkopts, ) direct_output_files = compact([ @@ -213,14 +217,12 @@ def _swift_library_impl(ctx): compilation_outputs = compilation_outputs, )), create_cc_info( - additional_inputs = additional_inputs, cc_infos = get_providers(deps, CcInfo), compilation_outputs = compilation_outputs, defines = ctx.attr.defines, includes = [ctx.bin_dir.path], - libraries_to_link = [library_to_link], + linker_inputs = [linker_input], private_cc_infos = get_providers(private_deps, CcInfo), - user_link_flags = linkopts, ), coverage_common.instrumented_files_info( ctx, diff --git a/swift/internal/swift_module_alias.bzl b/swift/internal/swift_module_alias.bzl index 55a57bf7c..cff5a9abd 100644 --- a/swift/internal/swift_module_alias.bzl +++ b/swift/internal/swift_module_alias.bzl @@ -21,7 +21,7 @@ load( "output_groups_from_compilation_outputs", ) load(":derived_files.bzl", "derived_files") -load(":linking.bzl", "register_libraries_to_link") +load(":linking.bzl", "create_linker_input") load(":providers.bzl", "SwiftInfo", "SwiftToolchainInfo") load(":swift_common.bzl", "swift_common") load(":utils.bzl", "compact", "create_cc_info", "get_providers") @@ -72,16 +72,18 @@ def _swift_module_alias_impl(ctx): target_name = ctx.label.name, ) - library_to_link = register_libraries_to_link( + linker_input, library_to_link = create_linker_input( actions = ctx.actions, alwayslink = False, cc_feature_configuration = swift_common.cc_feature_configuration( feature_configuration = feature_configuration, ), + compilation_outputs = compilation_outputs, is_dynamic = False, is_static = True, library_name = ctx.label.name, objects = compilation_outputs.object_files, + owner = ctx.label, swift_toolchain = swift_toolchain, ) @@ -105,7 +107,7 @@ def _swift_module_alias_impl(ctx): cc_infos = get_providers(deps, CcInfo), compilation_outputs = compilation_outputs, includes = [ctx.bin_dir.path], - libraries_to_link = [library_to_link], + linker_inputs = [linker_input], ), swift_common.create_swift_info( modules = [ diff --git a/swift/internal/swift_protoc_gen_aspect.bzl b/swift/internal/swift_protoc_gen_aspect.bzl index 9c069f374..8b42e67a2 100644 --- a/swift/internal/swift_protoc_gen_aspect.bzl +++ b/swift/internal/swift_protoc_gen_aspect.bzl @@ -26,7 +26,7 @@ load( "SWIFT_FEATURE_GENERATE_FROM_RAW_PROTO_FILES", "SWIFT_FEATURE_NO_GENERATED_HEADER", ) -load(":linking.bzl", "register_libraries_to_link") +load(":linking.bzl", "create_linker_input") load( ":proto_gen_utils.bzl", "declare_generated_files", @@ -427,12 +427,13 @@ def _swift_protoc_gen_aspect_impl(target, aspect_ctx): target_name = target.label.name, ) - library_to_link = register_libraries_to_link( + linker_input, library_to_link = create_linker_input( actions = aspect_ctx.actions, alwayslink = False, cc_feature_configuration = swift_common.cc_feature_configuration( feature_configuration = feature_configuration, ), + compilation_outputs = compilation_outputs, is_dynamic = False, is_static = True, # Prevent conflicts with C++ protos in the same output directory, @@ -440,6 +441,7 @@ def _swift_protoc_gen_aspect_impl(target, aspect_ctx): # `lib{name}.swift.a` instead. library_name = "{}.swift".format(target.label.name), objects = compilation_outputs.object_files, + owner = target.label, swift_toolchain = swift_toolchain, ) @@ -515,7 +517,7 @@ def _swift_protoc_gen_aspect_impl(target, aspect_ctx): cc_infos = cc_infos, compilation_outputs = compilation_outputs, includes = includes, - libraries_to_link = [library_to_link], + linker_inputs = [linker_input], ), objc_info = objc_info, ), diff --git a/swift/internal/utils.bzl b/swift/internal/utils.bzl index b4e41d85f..4c248ab85 100644 --- a/swift/internal/utils.bzl +++ b/swift/internal/utils.bzl @@ -41,25 +41,20 @@ def collect_cc_libraries( """ libraries = [] - # TODO(https://github.com/bazelbuild/bazel/issues/8118): Remove once flag is - # flipped. - libraries_to_link = cc_info.linking_context.libraries_to_link - if hasattr(libraries_to_link, "to_list"): - libraries_to_link = libraries_to_link.to_list() - - for library in libraries_to_link: - if include_pic_static: - if library.pic_static_library: - libraries.append(library.pic_static_library) - elif library.static_library: + for linker_input in cc_info.linking_context.linker_inputs.to_list(): + for library in linker_input.libraries: + if include_pic_static: + if library.pic_static_library: + libraries.append(library.pic_static_library) + elif library.static_library: + libraries.append(library.static_library) + elif include_static and library.static_library: libraries.append(library.static_library) - elif include_static and library.static_library: - libraries.append(library.static_library) - if include_dynamic and library.dynamic_library: - libraries.append(library.dynamic_library) - if include_interface and library.interface_library: - libraries.append(library.interface_library) + if include_dynamic and library.dynamic_library: + libraries.append(library.dynamic_library) + if include_interface and library.interface_library: + libraries.append(library.interface_library) return libraries @@ -74,19 +69,16 @@ def compact(sequence): return [item for item in sequence if item != None] def create_cc_info( - additional_inputs = [], + *, cc_infos = [], compilation_outputs = None, defines = [], includes = [], - libraries_to_link = [], - private_cc_infos = [], - user_link_flags = []): + linker_inputs = [], + private_cc_infos = []): """Creates a `CcInfo` provider from Swift compilation info and deps. Args: - additional_inputs: A list of additional files that should be passed as - inputs to the final link action. cc_infos: A list of `CcInfo` providers from public dependencies, whose compilation and linking contexts should both be merged into the new provider. @@ -96,32 +88,25 @@ def create_cc_info( context. includes: The list of include paths to insert into the compilation context. - libraries_to_link: A list of `LibraryToLink` objects that represent the - libraries that should be linked into the final binary. + linker_inputs: A list of `LinkerInput` objects that represent the + libraries that should be linked into the final binary as well as any + additional inputs and flags that should be passed to the linker. private_cc_infos: A list of `CcInfo` providers from private (implementation-only) dependencies, whose linking contexts should be merged into the new provider but whose compilation contexts should be excluded. - user_link_flags: A list of flags that should be passed to the final link - action. Returns: A new `CcInfo`. """ - all_additional_inputs = list(additional_inputs) - all_user_link_flags = list(user_link_flags) all_headers = [] if compilation_outputs: - all_additional_inputs.extend(compilation_outputs.linker_inputs) - all_user_link_flags.extend(compilation_outputs.linker_flags) all_headers = compact([compilation_outputs.generated_header]) local_cc_infos = [ CcInfo( linking_context = cc_common.create_linking_context( - additional_inputs = all_additional_inputs, - libraries_to_link = libraries_to_link, - user_link_flags = all_user_link_flags, + linker_inputs = depset(linker_inputs), ), compilation_context = cc_common.create_compilation_context( defines = depset(defines), diff --git a/test/private_deps_tests.bzl b/test/private_deps_tests.bzl index d9b256cb6..a18a6306e 100644 --- a/test/private_deps_tests.bzl +++ b/test/private_deps_tests.bzl @@ -112,7 +112,7 @@ def private_deps_test_suite(): # dependencies, which we need to ignore. "*", ], - field = "linking_context.libraries_to_link.static_library!", + field = "linking_context.linker_inputs.libraries.static_library!", provider = "CcInfo", tags = [name], target_under_test = "@build_bazel_rules_swift//test/fixtures/private_deps:client_cc_deps", diff --git a/test/rules/provider_test.bzl b/test/rules/provider_test.bzl index eba66af58..a6e68cfa3 100644 --- a/test/rules/provider_test.bzl +++ b/test/rules/provider_test.bzl @@ -81,7 +81,16 @@ def _evaluate_field(env, source, field): ) return _EVALUATE_FIELD_FAILED - source = [getattr(item, component, None) for item in source] + # If the elements are lists or depsets, flatten the whole thing into + # a single list. + flattened = [] + for item in source: + item = _normalize_collection(item) + if types.is_list(item): + flattened.extend(item) + else: + flattened.append(item) + source = [getattr(item, component, None) for item in flattened] if filter_nones: source = [item for item in source if item != None] else: