diff --git a/apple/internal/aspects/swift_dynamic_framework_aspect.bzl b/apple/internal/aspects/swift_dynamic_framework_aspect.bzl new file mode 100644 index 0000000000..1e5bd7758e --- /dev/null +++ b/apple/internal/aspects/swift_dynamic_framework_aspect.bzl @@ -0,0 +1,154 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Aspect implementation for Swift dynamic framework support.""" + +load( + "@build_bazel_rules_swift//swift:swift.bzl", + "SwiftInfo", +) + +SwiftDynamicFrameworkInfo = provider( + fields = { + "module_name": "The module name for the single swift_library dependency.", + "swiftinterfaces": """ +Dictionary of architecture to the generated swiftinterface file for that architecture. +""", + "swiftdocs": """ +Dictionary of architecture to the generated swiftdoc file for that architecture. +""", + "generated_header": """ +The generated Objective-C header for the single swift_library dependency. +""", + "swiftmodules": """ +Dictionary of architecture to the generated swiftmodule file for that architecture. +""", + "modulemap": """ +Generated modulemap for that architecture. +""", + }, + doc = """ +Provider that collects artifacts required to build a Swift-based dynamic framework. +""", +) + +def _swift_target_for_dep(dep): + """Returns the target for which the dependency was compiled. + + This is really hacky, but there's no easy way to acquire the Apple CPU for which the target was + built. One option would be to let this aspect propagate transitively through deps and have + another provider that propagates the CPU, but the model there gets a bit more complicated to + follow. With this approach, we avoid propagating the aspect transitively as well. + + This should be cleaned up when b/141931700 is fixed (adding support for ctx.rule.split_attr). + """ + for action in dep.actions: + if action.mnemonic == "SwiftCompile": + target_found = False + for arg in action.argv: + if target_found: + return arg + if arg == "-target": + target_found = True + fail("error: Expected at least one Swift compilation action for target {}.".format(dep.label)) + +def _swift_arch_for_dep(dep): + """Returns the architecture for which the dependency was built.""" + target = _swift_target_for_dep(dep) + return target.split("-", 1)[0] + +def _modulemap_contents(module_name): + """Returns the contents for the modulemap file for the framework.""" + return """\ +framework module {module_name} {{ + header "{module_name}.h" + requires objc +}} +""".format(module_name = module_name) + +def _swift_dynamic_framework_aspect_impl(target, ctx): + """Aspect implementation for Swift dynamic framework support.""" + + if not hasattr(ctx.rule.attr, "deps"): + return [] + + swiftdeps = [x for x in ctx.rule.attr.deps if SwiftInfo in x] + ccinfos = [x for x in ctx.rule.attr.deps if CcInfo in x] + # If there are no Swift dependencies, return nothing. + if not swiftdeps: + return [] + + if len(swiftdeps) != len(ctx.rule.attr.deps): + fail( + """\ +error: Found a mix of swift_library and other rule dependencies. Swift dynamic frameworks expect a \ +single swift_library dependency.\ +""", + ) + + # Collect all relevant artifacts for Swift dynamic framework generation. + module_name = None + generated_header = None + swiftdocs = {} + swiftmodules = {} + modulemap_file = None + for dep in swiftdeps: + swiftinfo = dep[SwiftInfo] + module_name = swiftinfo.module_name + arch = _swift_arch_for_dep(dep) + + swiftmodule = None + swiftdoc = None + for module in swiftinfo.transitive_modules.to_list(): + if not module.swift: + continue + swiftmodule = module.swift.swiftmodule + swiftdoc = module.swift.swiftdoc + + swiftdocs[arch] = swiftdoc + swiftmodules[arch] = swiftmodule + modulemap_file = ctx.actions.declare_file("{}_file.modulemap".format(module_name)) + ctx.actions.write(modulemap_file, _modulemap_contents(module_name)) + + # Get the generated_header using the CcInfo provider + for dep in ccinfos: + headers = dep[CcInfo].compilation_context.headers.to_list() + if headers: + generated_header = headers.pop(0) + + # Make sure that all dictionaries contain at least one module before returning the provider. + if all([module_name, generated_header, swiftdocs, swiftmodules, modulemap_file]): + return [ + SwiftDynamicFrameworkInfo( + module_name = module_name, + generated_header = generated_header, + swiftdocs = swiftdocs, + swiftmodules = swiftmodules, + modulemap = modulemap_file, + ), + ] + else: + fail( + """\ +error: Could not find all required artifacts and information to build a Swift dynamic framework. \ +Please file an issue with a reproducible error case.\ +""", + ) + +swift_dynamic_framework_aspect = aspect( + implementation = _swift_dynamic_framework_aspect_impl, + doc = """ +Aspect that collects Swift information to construct a dynamic framework that supports Swift. +""", +) diff --git a/apple/internal/ios_rules.bzl b/apple/internal/ios_rules.bzl index 20f038a1e9..f5fd6a7ae7 100644 --- a/apple/internal/ios_rules.bzl +++ b/apple/internal/ios_rules.bzl @@ -70,6 +70,10 @@ load( "@build_bazel_rules_apple//apple/internal/aspects:swift_static_framework_aspect.bzl", "SwiftStaticFrameworkInfo", ) +load( + "@build_bazel_rules_apple//apple/internal/aspects:swift_dynamic_framework_aspect.bzl", + "SwiftDynamicFrameworkInfo", +) load( "@build_bazel_rules_apple//apple:providers.bzl", "IosAppClipBundleInfo", @@ -899,6 +903,185 @@ def _ios_extension_impl(ctx): ), ] + processor_result.providers +def _ios_dynamic_framework_impl(ctx): + """Experimental implementation of ios_dynamic_framework.""" + + binary_target = [deps for deps in ctx.attr.deps if deps.label.name.endswith("swift_runtime_linkopts")][0] + extra_linkopts = [] + if ctx.attr.extension_safe: + extra_linkopts.append("-fapplication-extension") + + link_result = linking_support.register_linking_action( + ctx, + extra_linkopts = extra_linkopts, + ) + binary_artifact = link_result.binary_provider.binary + debug_outputs_provider = link_result.debug_outputs_provider + + actions = ctx.actions + bin_root_path = ctx.bin_dir.path + bundle_id = ctx.attr.bundle_id + bundle_name, bundle_extension = bundling_support.bundle_full_name_from_rule_ctx(ctx) + entitlements = entitlements_support.entitlements( + entitlements_attr = getattr(ctx.attr, "entitlements", None), + entitlements_file = getattr(ctx.file, "entitlements", None), + ) + executable_name = bundling_support.executable_name(ctx) + features = features_support.compute_enabled_features( + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + label = ctx.label + platform_prerequisites = platform_support.platform_prerequisites_from_rule_ctx(ctx) + predeclared_outputs = ctx.outputs + rule_descriptor = rule_support.rule_descriptor(ctx) + rule_executables = ctx.executable + + signed_frameworks = [] + if getattr(ctx.file, "provisioning_profile", None): + signed_frameworks = [ + bundle_name + rule_descriptor.bundle_extension, + ] + + archive_for_embedding = outputs.archive_for_embedding( + actions = actions, + bundle_name = bundle_name, + bundle_extension = bundle_extension, + executable_name = executable_name, + label_name = label.name, + rule_descriptor = rule_descriptor, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + ) + + processor_partials = [ + partials.apple_bundle_info_partial( + actions = actions, + bundle_extension = bundle_extension, + bundle_id = bundle_id, + bundle_name = bundle_name, + executable_name = executable_name, + entitlements = entitlements, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + product_type = rule_descriptor.product_type, + ), + partials.binary_partial( + actions = actions, + binary_artifact = binary_artifact, + executable_name = executable_name, + label_name = label.name, + ), + partials.bitcode_symbols_partial( + actions = actions, + binary_artifact = binary_artifact, + debug_outputs_provider = debug_outputs_provider, + dependency_targets = ctx.attr.frameworks, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + ), + partials.clang_rt_dylibs_partial( + actions = actions, + binary_artifact = binary_artifact, + clangrttool = ctx.executable._clangrttool, + features = features, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + ), + partials.debug_symbols_partial( + actions = actions, + bin_root_path = bin_root_path, + bundle_extension = bundle_extension, + bundle_name = bundle_name, + debug_dependencies = ctx.attr.frameworks, + debug_outputs_provider = debug_outputs_provider, + dsym_info_plist_template = ctx.file._dsym_info_plist_template, + executable_name = executable_name, + platform_prerequisites = platform_prerequisites, + rule_label = label, + ), + partials.embedded_bundles_partial( + frameworks = [archive_for_embedding], + embeddable_targets = ctx.attr.frameworks, + platform_prerequisites = platform_prerequisites, + signed_frameworks = depset(signed_frameworks), + ), + partials.extension_safe_validation_partial( + is_extension_safe = ctx.attr.extension_safe, + rule_label = label, + targets_to_validate = ctx.attr.frameworks, + ), + partials.framework_provider_partial( + actions = actions, + bin_root_path = bin_root_path, + binary_provider = link_result.binary_provider, + bundle_name = bundle_name, + rule_label = label, + ), + partials.resources_partial( + actions = actions, + bundle_extension = bundle_extension, + bundle_id = bundle_id, + bundle_name = bundle_name, + environment_plist = ctx.file._environment_plist, + executable_name = executable_name, + launch_storyboard = None, + platform_prerequisites = platform_prerequisites, + plist_attrs = ["infoplists"], + rule_attrs = ctx.attr, + rule_descriptor = rule_descriptor, + rule_executables = rule_executables, + rule_label = label, + targets_to_avoid = ctx.attr.frameworks, + top_level_attrs = ["resources"], + version_keys_required = False, + ), + partials.swift_dylibs_partial( + actions = actions, + binary_artifact = binary_artifact, + dependency_targets = ctx.attr.frameworks, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + swift_stdlib_tool = ctx.executable._swift_stdlib_tool, + ), + partials.swift_dynamic_framework_partial( + actions = actions, + bundle_name = bundle_name, + label_name = label.name, + swift_dynamic_framework_info = binary_target[SwiftDynamicFrameworkInfo], + ), + ] + + processor_result = processor.process( + ctx = ctx, + actions = actions, + bundle_extension = bundle_extension, + bundle_name = bundle_name, + entitlements = entitlements, + executable_name = executable_name, + partials = processor_partials, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + provisioning_profile = getattr(ctx.file, "provisioning_profile", None), + rule_descriptor = rule_descriptor, + rule_executables = rule_executables, + rule_label = label, + ) + + providers = processor_result.providers + + return [ + DefaultInfo(files = processor_result.output_files), + IosFrameworkBundleInfo(), + OutputGroupInfo( + **outputs.merge_output_groups( + link_result.output_groups, + processor_result.output_groups, + ) + ), + ] + providers + def _ios_static_framework_impl(ctx): """Experimental implementation of ios_static_framework.""" @@ -1461,6 +1644,13 @@ ios_framework = rule_factory.create_apple_bundling_rule( doc = "Builds and bundles an iOS Dynamic Framework.", ) +ios_dynamic_framework = rule_factory.create_apple_bundling_rule( + implementation = _ios_dynamic_framework_impl, + platform_type = "ios", + product_type = apple_product_type.framework, + doc = "Builds and bundles an iOS dynamic framework that is consumable by Xcode.", +) + ios_static_framework = rule_factory.create_apple_bundling_rule( implementation = _ios_static_framework_impl, platform_type = "ios", diff --git a/apple/internal/partials.bzl b/apple/internal/partials.bzl index 3d3c47a8f5..3350950698 100644 --- a/apple/internal/partials.bzl +++ b/apple/internal/partials.bzl @@ -86,6 +86,10 @@ load( "@build_bazel_rules_apple//apple/internal/partials:swift_dylibs.bzl", _swift_dylibs_partial = "swift_dylibs_partial", ) +load( + "@build_bazel_rules_apple//apple/internal/partials:swift_dynamic_framework.bzl", + _swift_dynamic_framework_partial = "swift_dynamic_framework_partial", +) load( "@build_bazel_rules_apple//apple/internal/partials:swift_static_framework.bzl", _swift_static_framework_partial = "swift_static_framework_partial", @@ -114,6 +118,7 @@ partials = struct( settings_bundle_partial = _settings_bundle_partial, static_framework_header_modulemap_partial = _static_framework_header_modulemap_partial, swift_dylibs_partial = _swift_dylibs_partial, + swift_dynamic_framework_partial = _swift_dynamic_framework_partial, swift_static_framework_partial = _swift_static_framework_partial, watchos_stub_partial = _watchos_stub_partial, ) diff --git a/apple/internal/partials/swift_dynamic_framework.bzl b/apple/internal/partials/swift_dynamic_framework.bzl new file mode 100644 index 0000000000..b5a880ced6 --- /dev/null +++ b/apple/internal/partials/swift_dynamic_framework.bzl @@ -0,0 +1,120 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Partial implementation for Swift dynamic frameworks.""" + +load( + "@build_bazel_rules_apple//apple/internal:intermediates.bzl", + "intermediates", +) +load( + "@build_bazel_rules_apple//apple/internal:processor.bzl", + "processor", +) +load( + "@bazel_skylib//lib:partial.bzl", + "partial", +) +load( + "@bazel_skylib//lib:paths.bzl", + "paths", +) + +def _get_header_imports(framework_imports): + """Get the header files from the list of framework imports""" + + return [file for file in framework_imports if file.short_path.endswith(".h")] + +# TODO(b/161370390): Remove ctx from the args when ctx is removed from all partials. +def _swift_dynamic_framework_partial_impl( + *, + ctx, + actions, + bundle_name, + label_name, + swift_dynamic_framework_info): + """Implementation for the Swift dynamic framework processing partial.""" + + if bundle_name != swift_dynamic_framework_info.module_name: + fail(""" +error: Found swift_library with module name {} but expected {}. Swift dynamic \ +frameworks expect a single swift_library dependency with `module_name` set to the same \ +`bundle_name` as the dynamic framework target.\ +""".format(swift_dynamic_framework_info.module_name, bundle_name)) + + generated_header = swift_dynamic_framework_info.generated_header + swiftdocs = swift_dynamic_framework_info.swiftdocs + swiftmodules = swift_dynamic_framework_info.swiftmodules + modulemap_file = swift_dynamic_framework_info.modulemap + + bundle_files = [] + modules_parent = paths.join("Modules", "{}.swiftmodule".format(bundle_name)) + + for arch, swiftdoc in swiftdocs.items(): + bundle_doc = intermediates.file(actions, label_name, "{}.swiftdoc".format(arch)) + actions.symlink(target_file = swiftdoc, output = bundle_doc) + bundle_files.append((processor.location.bundle, modules_parent, depset([bundle_doc]))) + + for arch, swiftmodule in swiftmodules.items(): + bundle_doc = intermediates.file(actions, label_name, "{}.swiftmodule".format(arch)) + actions.symlink(target_file = swiftmodule, output = bundle_doc) + bundle_files.append((processor.location.bundle, modules_parent, depset([bundle_doc]))) + + if generated_header: + bundle_header = intermediates.file( + actions, + label_name, + "{}.h".format(bundle_name), + ) + actions.symlink(target_file = generated_header, output = bundle_header) + bundle_files.append((processor.location.bundle, "Headers", depset([bundle_header]))) + + if modulemap_file: + modulemap = intermediates.file(actions, label_name, "module.modulemap") + actions.symlink(target_file = modulemap_file, output = modulemap) + bundle_files.append((processor.location.bundle, "Modules", depset([modulemap]))) + + return struct( + bundle_files = bundle_files, + ) + +def swift_dynamic_framework_partial( + *, + actions, + bundle_name, + label_name, + swift_dynamic_framework_info): + """Constructor for the Swift dynamic framework processing partial. + + This partial collects and bundles the necessary files to construct a Swift based dynamic + framework. + + Args: + actions: The actions provider from `ctx.actions`. + bundle_name: The name of the output bundle. + label_name: Name of the target being built. + swift_dynamic_framework_info: The SwiftDynamicFrameworkInfo provider containing the required + artifacts. + + Returns: + A partial that returns the bundle location of the supporting Swift artifacts needed in a + Swift based dynamic framework. + """ + return partial.make( + _swift_dynamic_framework_partial_impl, + actions = actions, + bundle_name = bundle_name, + label_name = label_name, + swift_dynamic_framework_info = swift_dynamic_framework_info, + ) diff --git a/apple/internal/rule_factory.bzl b/apple/internal/rule_factory.bzl index cbfb4adf35..303f75ed70 100644 --- a/apple/internal/rule_factory.bzl +++ b/apple/internal/rule_factory.bzl @@ -38,6 +38,10 @@ load( "@build_bazel_rules_apple//apple/internal/aspects:swift_static_framework_aspect.bzl", "swift_static_framework_aspect", ) +load( + "@build_bazel_rules_apple//apple/internal/aspects:swift_dynamic_framework_aspect.bzl", + "swift_dynamic_framework_aspect", +) load( "@build_bazel_rules_apple//apple/internal:transition_support.bzl", "transition_support", @@ -297,6 +301,8 @@ def _common_binary_linking_attrs(default_binary_type, deps_cfg, product_type): deps_aspects.append(apple_test_info_aspect) if product_type == apple_product_type.static_framework: deps_aspects.append(swift_static_framework_aspect) + if product_type == apple_product_type.framework: + deps_aspects.append(swift_dynamic_framework_aspect) return dicts.add( _COMMON_ATTRS, @@ -922,6 +928,30 @@ ignored. """, ), }) + elif rule_descriptor.product_type == apple_product_type.framework: + attrs.append({ + "extension_safe": attr.bool( + default = False, + doc = """ + If true, compiles and links this framework with `-application-extension`, restricting the binary to + use only extension-safe APIs. + """, + ), + }) + + if rule_descriptor.requires_deps: + extra_args = {} + attrs.append({ + "frameworks": attr.label_list( + providers = [[AppleBundleInfo, IosFrameworkBundleInfo]], + doc = """ + A list of framework targets (see + [`ios_framework`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-ios.md#ios_framework)) + that this target depends on. + """, + **extra_args + ), + }) return attrs diff --git a/apple/internal/rule_support.bzl b/apple/internal/rule_support.bzl index a17a4c43de..8411f2ba3e 100644 --- a/apple/internal/rule_support.bzl +++ b/apple/internal/rule_support.bzl @@ -649,9 +649,9 @@ _RULE_TYPE_DESCRIPTORS = { # tvos_framework apple_product_type.framework: _describe_rule_type( allowed_device_families = ["tv"], + binary_type = "dylib", bundle_extension = ".framework", bundle_package_type = bundle_package_type.framework, - binary_type = "dylib", codesigning_exceptions = _CODESIGNING_EXCEPTIONS.sign_with_provisioning_profile, deps_cfg = apple_common.multi_arch_split, product_type = apple_product_type.framework, @@ -753,6 +753,22 @@ _RULE_TYPE_DESCRIPTORS = { "@executable_path/../../Frameworks", ], ), + # watchos_framework + apple_product_type.framework: _describe_rule_type( + allowed_device_families = ["watch"], + binary_type = "dylib", + bundle_extension = ".framework", + bundle_package_type = bundle_package_type.framework, + codesigning_exceptions = _CODESIGNING_EXCEPTIONS.sign_with_provisioning_profile, + deps_cfg = apple_common.multi_arch_split, + product_type = apple_product_type.framework, + rpaths = [ + # Framework binaries live in + # Application.app/Frameworks/Framework.framework/Framework + # Frameworks are packaged in Application.app/Frameworks + "@executable_path/Frameworks", + ], + ), }, } diff --git a/apple/internal/tvos_rules.bzl b/apple/internal/tvos_rules.bzl index 8e579e28f9..118fc9b312 100644 --- a/apple/internal/tvos_rules.bzl +++ b/apple/internal/tvos_rules.bzl @@ -14,6 +14,10 @@ """Implementation of tvOS rules.""" +load( + "@build_bazel_rules_apple//apple/internal/aspects:swift_dynamic_framework_aspect.bzl", + "SwiftDynamicFrameworkInfo", +) load( "@build_bazel_rules_apple//apple/internal:apple_product_type.bzl", "apple_product_type", @@ -279,6 +283,173 @@ def _tvos_application_impl(ctx): link_result.binary_provider, ] + processor_result.providers +def _tvos_dynamic_framework_impl(ctx): + """Experimental implementation of tvos_dynamic_framework.""" + + binary_target = [deps for deps in ctx.attr.deps if deps.label.name.endswith("swift_runtime_linkopts")][0] + link_result = linking_support.register_linking_action(ctx) + binary_artifact = link_result.binary_provider.binary + debug_outputs_provider = link_result.debug_outputs_provider + + actions = ctx.actions + bin_root_path = ctx.bin_dir.path + bundle_id = ctx.attr.bundle_id + bundle_name, bundle_extension = bundling_support.bundle_full_name_from_rule_ctx(ctx) + entitlements = entitlements_support.entitlements( + entitlements_attr = getattr(ctx.attr, "entitlements", None), + entitlements_file = getattr(ctx.file, "entitlements", None), + ) + executable_name = bundling_support.executable_name(ctx) + features = features_support.compute_enabled_features( + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + label = ctx.label + platform_prerequisites = platform_support.platform_prerequisites_from_rule_ctx(ctx) + predeclared_outputs = ctx.outputs + rule_descriptor = rule_support.rule_descriptor(ctx) + rule_executables = ctx.executable + + signed_frameworks = [] + if getattr(ctx.file, "provisioning_profile", None): + signed_frameworks = [ + bundle_name + rule_descriptor.bundle_extension, + ] + + archive = outputs.archive( + actions = actions, + bundle_extension = bundle_extension, + bundle_name = bundle_name, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + ) + + processor_partials = [ + partials.apple_bundle_info_partial( + actions = actions, + bundle_extension = bundle_extension, + bundle_id = bundle_id, + bundle_name = bundle_name, + executable_name = executable_name, + entitlements = entitlements, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + product_type = rule_descriptor.product_type, + ), + partials.binary_partial( + actions = actions, + binary_artifact = binary_artifact, + executable_name = executable_name, + label_name = label.name, + ), + partials.bitcode_symbols_partial( + actions = actions, + binary_artifact = binary_artifact, + debug_outputs_provider = debug_outputs_provider, + dependency_targets = ctx.attr.frameworks, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + ), + partials.clang_rt_dylibs_partial( + actions = actions, + binary_artifact = binary_artifact, + clangrttool = ctx.executable._clangrttool, + features = features, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + ), + partials.debug_symbols_partial( + actions = actions, + bin_root_path = bin_root_path, + bundle_extension = bundle_extension, + bundle_name = bundle_name, + debug_dependencies = ctx.attr.frameworks, + debug_outputs_provider = debug_outputs_provider, + dsym_info_plist_template = ctx.file._dsym_info_plist_template, + executable_name = executable_name, + platform_prerequisites = platform_prerequisites, + rule_label = label, + ), + partials.embedded_bundles_partial( + frameworks = [archive], + embeddable_targets = ctx.attr.frameworks, + platform_prerequisites = platform_prerequisites, + signed_frameworks = depset(signed_frameworks), + ), + partials.extension_safe_validation_partial( + is_extension_safe = ctx.attr.extension_safe, + rule_label = label, + targets_to_validate = ctx.attr.frameworks, + ), + partials.framework_provider_partial( + actions = actions, + bin_root_path = bin_root_path, + binary_provider = link_result.binary_provider, + bundle_name = bundle_name, + rule_label = label, + ), + partials.resources_partial( + actions = actions, + bundle_extension = bundle_extension, + bundle_id = bundle_id, + bundle_name = bundle_name, + environment_plist = ctx.file._environment_plist, + executable_name = executable_name, + launch_storyboard = None, + platform_prerequisites = platform_prerequisites, + plist_attrs = ["infoplists"], + rule_attrs = ctx.attr, + rule_descriptor = rule_descriptor, + rule_executables = rule_executables, + rule_label = label, + targets_to_avoid = ctx.attr.frameworks, + top_level_attrs = ["resources"], + version_keys_required = False, + ), + partials.swift_dylibs_partial( + actions = actions, + binary_artifact = binary_artifact, + dependency_targets = ctx.attr.frameworks, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + swift_stdlib_tool = ctx.executable._swift_stdlib_tool, + ), + partials.swift_dynamic_framework_partial( + actions = actions, + bundle_name = bundle_name, + label_name = label.name, + swift_dynamic_framework_info = binary_target[SwiftDynamicFrameworkInfo], + ), + ] + + processor_result = processor.process( + ctx = ctx, + actions = actions, + bundle_extension = bundle_extension, + bundle_name = bundle_name, + entitlements = entitlements, + executable_name = executable_name, + partials = processor_partials, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + provisioning_profile = getattr(ctx.file, "provisioning_profile", None), + rule_descriptor = rule_descriptor, + rule_executables = rule_executables, + rule_label = label, + ) + + return [ + DefaultInfo(files = processor_result.output_files), + OutputGroupInfo( + **outputs.merge_output_groups( + link_result.output_groups, + processor_result.output_groups, + ) + ), + TvosFrameworkBundleInfo(), + ] + processor_result.providers + def _tvos_framework_impl(ctx): """Experimental implementation of tvos_framework.""" link_result = linking_support.register_linking_action(ctx) @@ -712,7 +883,12 @@ tvos_application = rule_factory.create_apple_bundling_rule( product_type = apple_product_type.application, doc = "Builds and bundles a tvOS Application.", ) - +tvos_dynamic_framework = rule_factory.create_apple_bundling_rule( + implementation = _tvos_dynamic_framework_impl, + platform_type = "tvos", + product_type = apple_product_type.framework, + doc = "Builds and bundles a tvOS dynamic framework that is consumable by Xcode.", +) tvos_extension = rule_factory.create_apple_bundling_rule( implementation = _tvos_extension_impl, platform_type = "tvos", diff --git a/apple/internal/watchos_rules.bzl b/apple/internal/watchos_rules.bzl index a69d50c955..c3f616311d 100644 --- a/apple/internal/watchos_rules.bzl +++ b/apple/internal/watchos_rules.bzl @@ -70,7 +70,191 @@ load( "@build_bazel_rules_apple//apple:providers.bzl", "WatchosApplicationBundleInfo", "WatchosExtensionBundleInfo", + "IosFrameworkBundleInfo", ) +load( + "@build_bazel_rules_apple//apple/internal/aspects:swift_dynamic_framework_aspect.bzl", + "SwiftDynamicFrameworkInfo", +) + +def _watchos_dynamic_framework_impl(ctx): + """Experimental implementation of watchos_dynamic_framework.""" + + binary_target = [deps for deps in ctx.attr.deps if deps.label.name.endswith("swift_runtime_linkopts")][0] + extra_linkopts = [] + if ctx.attr.extension_safe: + extra_linkopts.append("-fapplication-extension") + + link_result = linking_support.register_linking_action( + ctx, + extra_linkopts = extra_linkopts, + ) + binary_artifact = link_result.binary_provider.binary + debug_outputs_provider = link_result.debug_outputs_provider + + actions = ctx.actions + bin_root_path = ctx.bin_dir.path + bundle_id = ctx.attr.bundle_id + bundle_name, bundle_extension = bundling_support.bundle_full_name_from_rule_ctx(ctx) + entitlements = entitlements_support.entitlements( + entitlements_attr = getattr(ctx.attr, "entitlements", None), + entitlements_file = getattr(ctx.file, "entitlements", None), + ) + executable_name = bundling_support.executable_name(ctx) + features = features_support.compute_enabled_features( + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + label = ctx.label + platform_prerequisites = platform_support.platform_prerequisites_from_rule_ctx(ctx) + predeclared_outputs = ctx.outputs + rule_descriptor = rule_support.rule_descriptor(ctx) + rule_executables = ctx.executable + + signed_frameworks = [] + if getattr(ctx.file, "provisioning_profile", None): + signed_frameworks = [ + bundle_name + rule_descriptor.bundle_extension, + ] + + archive_for_embedding = outputs.archive_for_embedding( + actions = actions, + bundle_name = bundle_name, + bundle_extension = bundle_extension, + executable_name = executable_name, + label_name = label.name, + rule_descriptor = rule_descriptor, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + ) + + processor_partials = [ + partials.apple_bundle_info_partial( + actions = actions, + bundle_extension = bundle_extension, + bundle_id = bundle_id, + bundle_name = bundle_name, + executable_name = executable_name, + entitlements = entitlements, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + product_type = rule_descriptor.product_type, + ), + partials.binary_partial( + actions = actions, + binary_artifact = binary_artifact, + executable_name = executable_name, + label_name = label.name, + ), + partials.bitcode_symbols_partial( + actions = actions, + binary_artifact = binary_artifact, + debug_outputs_provider = debug_outputs_provider, + dependency_targets = ctx.attr.frameworks, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + ), + partials.clang_rt_dylibs_partial( + actions = actions, + binary_artifact = binary_artifact, + clangrttool = ctx.executable._clangrttool, + features = features, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + ), + partials.debug_symbols_partial( + actions = actions, + bin_root_path = bin_root_path, + bundle_extension = bundle_extension, + bundle_name = bundle_name, + debug_dependencies = ctx.attr.frameworks, + debug_outputs_provider = debug_outputs_provider, + dsym_info_plist_template = ctx.file._dsym_info_plist_template, + executable_name = executable_name, + platform_prerequisites = platform_prerequisites, + rule_label = label, + ), + partials.embedded_bundles_partial( + frameworks = [archive_for_embedding], + embeddable_targets = ctx.attr.frameworks, + platform_prerequisites = platform_prerequisites, + signed_frameworks = depset(signed_frameworks), + ), + partials.extension_safe_validation_partial( + is_extension_safe = ctx.attr.extension_safe, + rule_label = label, + targets_to_validate = ctx.attr.frameworks, + ), + partials.framework_provider_partial( + actions = actions, + bin_root_path = bin_root_path, + binary_provider = link_result.binary_provider, + bundle_name = bundle_name, + rule_label = label, + ), + partials.resources_partial( + actions = actions, + bundle_extension = bundle_extension, + bundle_id = bundle_id, + bundle_name = bundle_name, + environment_plist = ctx.file._environment_plist, + executable_name = executable_name, + launch_storyboard = None, + platform_prerequisites = platform_prerequisites, + plist_attrs = ["infoplists"], + rule_attrs = ctx.attr, + rule_descriptor = rule_descriptor, + rule_executables = rule_executables, + rule_label = label, + targets_to_avoid = ctx.attr.frameworks, + top_level_attrs = ["resources"], + version_keys_required = False, + ), + partials.swift_dylibs_partial( + actions = actions, + binary_artifact = binary_artifact, + dependency_targets = ctx.attr.frameworks, + label_name = label.name, + platform_prerequisites = platform_prerequisites, + swift_stdlib_tool = ctx.executable._swift_stdlib_tool, + ), + partials.swift_dynamic_framework_partial( + actions = actions, + bundle_name = bundle_name, + label_name = label.name, + swift_dynamic_framework_info = binary_target[SwiftDynamicFrameworkInfo], + ), + ] + + processor_result = processor.process( + ctx = ctx, + actions = actions, + bundle_extension = bundle_extension, + bundle_name = bundle_name, + entitlements = entitlements, + executable_name = executable_name, + partials = processor_partials, + platform_prerequisites = platform_prerequisites, + predeclared_outputs = predeclared_outputs, + provisioning_profile = getattr(ctx.file, "provisioning_profile", None), + rule_descriptor = rule_descriptor, + rule_executables = rule_executables, + rule_label = label, + ) + + providers = processor_result.providers + + return [ + DefaultInfo(files = processor_result.output_files), + IosFrameworkBundleInfo(), + OutputGroupInfo( + **outputs.merge_output_groups( + link_result.output_groups, + processor_result.output_groups, + ) + ), + ] + providers def _watchos_application_impl(ctx): """Implementation of watchos_application.""" @@ -443,3 +627,10 @@ watchos_extension = rule_factory.create_apple_bundling_rule( product_type = apple_product_type.watch2_extension, doc = "Builds and bundles an watchOS Extension.", ) + +watchos_dynamic_framework = rule_factory.create_apple_bundling_rule( + implementation = _watchos_dynamic_framework_impl, + platform_type = "watchos", + product_type = apple_product_type.framework, + doc = "Builds and bundles a watchOS dynamic framework that is consumable by Xcode.", +) diff --git a/apple/ios.bzl b/apple/ios.bzl index 64c2647ff3..ae31763b5d 100644 --- a/apple/ios.bzl +++ b/apple/ios.bzl @@ -46,6 +46,7 @@ load( _ios_imessage_application = "ios_imessage_application", _ios_imessage_extension = "ios_imessage_extension", _ios_static_framework = "ios_static_framework", + _ios_dynamic_framework = "ios_dynamic_framework", _ios_sticker_pack_extension = "ios_sticker_pack_extension", ) @@ -125,6 +126,36 @@ def ios_framework(name, **kwargs): **bundling_args ) +def ios_dynamic_framework(name, **kwargs): + # buildifier: disable=function-docstring-args + """Builds and bundles an iOS dynamic framework that is consumable by Xcode.""" + + binary_args = dict(kwargs) + # TODO(b/120861201): The linkopts macro additions here only exist because the Starlark linking + # API does not accept extra linkopts and link inputs. With those, it will be possible to merge + # these workarounds into the rule implementations. + linkopts = binary_args.pop("linkopts", []) + bundle_name = binary_args.get("bundle_name", name) + linkopts += ["-install_name", "@rpath/%s.framework/%s" % (bundle_name, bundle_name)] + binary_args["linkopts"] = linkopts + bundling_args = binary_support.add_entitlements_and_swift_linkopts( + name, + include_entitlements = False, + platform_type = str(apple_common.platform_type.ios), + product_type = apple_product_type.framework, + exported_symbols_lists = binary_args.pop("exported_symbols_lists", None), + **binary_args + ) + + # Remove any kwargs that shouldn't be passed to the underlying rule. + bundling_args.pop("entitlements", None) + + _ios_dynamic_framework( + name = name, + extension_safe = kwargs.get("extension_safe"), + **bundling_args + ) + def ios_static_framework(name, **kwargs): # buildifier: disable=function-docstring-args """Builds and bundles an iOS static framework for third-party distribution.""" diff --git a/apple/tvos.bzl b/apple/tvos.bzl index dbc3620436..7bcce4cf7f 100644 --- a/apple/tvos.bzl +++ b/apple/tvos.bzl @@ -40,6 +40,7 @@ load( load( "@build_bazel_rules_apple//apple/internal:tvos_rules.bzl", _tvos_application = "tvos_application", + _tvos_dynamic_framework = "tvos_dynamic_framework", _tvos_extension = "tvos_extension", _tvos_framework = "tvos_framework", _tvos_static_framework = "tvos_static_framework", @@ -157,6 +158,36 @@ def tvos_ui_test(name, **kwargs): **kwargs ) +def tvos_dynamic_framework(name, **kwargs): + # buildifier: disable=function-docstring-args + """Builds and bundles a tvOS dynamic framework that is consumable by Xcode.""" + + binary_args = dict(kwargs) + # TODO(b/120861201): The linkopts macro additions here only exist because the Starlark linking + # API does not accept extra linkopts and link inputs. With those, it will be possible to merge + # these workarounds into the rule implementations. + linkopts = binary_args.pop("linkopts", []) + bundle_name = binary_args.get("bundle_name", name) + linkopts += ["-install_name", "@rpath/%s.framework/%s" % (bundle_name, bundle_name)] + binary_args["linkopts"] = linkopts + bundling_args = binary_support.add_entitlements_and_swift_linkopts( + name, + include_entitlements = False, + platform_type = str(apple_common.platform_type.watchos), + product_type = apple_product_type.framework, + exported_symbols_lists = binary_args.pop("exported_symbols_lists", None), + **binary_args + ) + + # Remove any kwargs that shouldn't be passed to the underlying rule. + bundling_args.pop("entitlements", None) + + _tvos_dynamic_framework( + name = name, + extension_safe = kwargs.get("extension_safe"), + **bundling_args + ) + tvos_build_test = apple_build_test_rule( doc = """\ Test rule to check that the given library targets (Swift, Objective-C, C++) diff --git a/apple/watchos.bzl b/apple/watchos.bzl index 742253f689..29825e4d02 100644 --- a/apple/watchos.bzl +++ b/apple/watchos.bzl @@ -33,6 +33,7 @@ load( "@build_bazel_rules_apple//apple/internal:watchos_rules.bzl", _watchos_application = "watchos_application", _watchos_extension = "watchos_extension", + _watchos_dynamic_framework = "watchos_dynamic_framework", ) def watchos_application(name, **kwargs): @@ -65,6 +66,36 @@ def watchos_extension(name, **kwargs): **bundling_args ) +def watchos_dynamic_framework(name, **kwargs): + # buildifier: disable=function-docstring-args + """Builds and bundles a watchOS dynamic framework that is consumable by Xcode.""" + + binary_args = dict(kwargs) + # TODO(b/120861201): The linkopts macro additions here only exist because the Starlark linking + # API does not accept extra linkopts and link inputs. With those, it will be possible to merge + # these workarounds into the rule implementations. + linkopts = binary_args.pop("linkopts", []) + bundle_name = binary_args.get("bundle_name", name) + linkopts += ["-install_name", "@rpath/%s.framework/%s" % (bundle_name, bundle_name)] + binary_args["linkopts"] = linkopts + bundling_args = binary_support.add_entitlements_and_swift_linkopts( + name, + include_entitlements = False, + platform_type = str(apple_common.platform_type.watchos), + product_type = apple_product_type.framework, + exported_symbols_lists = binary_args.pop("exported_symbols_lists", None), + **binary_args + ) + + # Remove any kwargs that shouldn't be passed to the underlying rule. + bundling_args.pop("entitlements", None) + + _watchos_dynamic_framework( + name = name, + extension_safe = kwargs.get("extension_safe"), + **bundling_args + ) + watchos_build_test = apple_build_test_rule( doc = """\ Test rule to check that the given library targets (Swift, Objective-C, C++) diff --git a/test/starlark_tests/BUILD b/test/starlark_tests/BUILD index 330742bce4..b11c82d8a6 100644 --- a/test/starlark_tests/BUILD +++ b/test/starlark_tests/BUILD @@ -6,6 +6,7 @@ load(":ios_application_tests.bzl", "ios_application_test_suite") load(":ios_app_clip_tests.bzl", "ios_app_clip_test_suite") load(":ios_extension_tests.bzl", "ios_extension_test_suite") load(":ios_framework_tests.bzl", "ios_framework_test_suite") +load(":ios_dynamic_framework_tests.bzl", "ios_dynamic_framework_test_suite") load(":ios_imessage_application_tests.bzl", "ios_imessage_application_test_suite") load(":ios_sticker_pack_extension_tests.bzl", "ios_sticker_pack_extension_test_suite") load(":ios_ui_test_tests.bzl", "ios_ui_test_test_suite") @@ -22,6 +23,7 @@ load(":macos_ui_test_tests.bzl", "macos_ui_test_test_suite") load(":macos_unit_test_tests.bzl", "macos_unit_test_test_suite") load(":tvos_application_swift_tests.bzl", "tvos_application_swift_test_suite") load(":tvos_application_tests.bzl", "tvos_application_test_suite") +load(":tvos_dynamic_framework_tests.bzl", "tvos_dynamic_framework_test_suite") load(":tvos_extension_tests.bzl", "tvos_extension_test_suite") load(":tvos_framework_tests.bzl", "tvos_framework_test_suite") load(":tvos_static_framework_tests.bzl", "tvos_static_framework_test_suite") @@ -29,6 +31,7 @@ load(":tvos_ui_test_tests.bzl", "tvos_ui_test_test_suite") load(":tvos_unit_test_tests.bzl", "tvos_unit_test_test_suite") load(":watchos_application_swift_tests.bzl", "watchos_application_swift_test_suite") load(":watchos_application_tests.bzl", "watchos_application_test_suite") +load(":watchos_dynamic_framework_tests.bzl", "watchos_dynamic_framework_test_suite") load(":watchos_extension_tests.bzl", "watchos_extension_test_suite") licenses(["notice"]) @@ -47,6 +50,8 @@ ios_extension_test_suite() ios_framework_test_suite() +ios_dynamic_framework_test_suite() + ios_imessage_application_test_suite() ios_sticker_pack_extension_test_suite() @@ -81,6 +86,8 @@ tvos_application_test_suite() tvos_extension_test_suite() +tvos_dynamic_framework_test_suite() + tvos_framework_test_suite() tvos_static_framework_test_suite() @@ -93,6 +100,8 @@ watchos_application_swift_test_suite() watchos_application_test_suite() +watchos_dynamic_framework_test_suite() + watchos_extension_test_suite() test_suite( diff --git a/test/starlark_tests/ios_dynamic_framework_tests.bzl b/test/starlark_tests/ios_dynamic_framework_tests.bzl new file mode 100644 index 0000000000..d61e88576f --- /dev/null +++ b/test/starlark_tests/ios_dynamic_framework_tests.bzl @@ -0,0 +1,166 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""ios_dynamic_framework Starlark tests.""" + +load( + ":rules/common_verification_tests.bzl", + "archive_contents_test", +) +load( + ":rules/infoplist_contents_test.bzl", + "infoplist_contents_test", +) + +def ios_dynamic_framework_test_suite(name = "ios_dynamic_framework"): + """Test suite for ios_dynamic_framework. + + Args: + name: The name prefix for all the nested tests + """ + + archive_contents_test( + name = "{}_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:basic_framework", + binary_test_file = "$BUNDLE_ROOT/BasicFramework", + binary_test_architecture = "x86_64", + macho_load_commands_contain = ["name @rpath/BasicFramework.framework/BasicFramework (offset 24)"], + contains = [ + "$BUNDLE_ROOT/BasicFramework", + "$BUNDLE_ROOT/Headers/BasicFramework.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/BasicFramework.swiftmodule/x86_64.swiftdoc", + "$BUNDLE_ROOT/Modules/BasicFramework.swiftmodule/x86_64.swiftmodule" + ], + tags = [name], + ) + + infoplist_contents_test( + name = "{}_plist_test".format(name), + target_under_test = "//test/starlark_tests/targets_under_test/ios:basic_framework", + expected_values = { + "BuildMachineOSBuild": "*", + "CFBundleExecutable": "BasicFramework", + "CFBundleIdentifier": "com.google.example.framework", + "CFBundleName": "BasicFramework", + "CFBundleSupportedPlatforms:0": "iPhone*", + "DTCompiler": "com.apple.compilers.llvm.clang.1_0", + "DTPlatformBuild": "*", + "DTPlatformName": "iphone*", + "DTPlatformVersion": "*", + "DTSDKBuild": "*", + "DTSDKName": "iphone*", + "DTXcode": "*", + "DTXcodeBuild": "*", + "MinimumOSVersion": "8.0", + "UIDeviceFamily:0": "1", + }, + tags = [name], + ) + + archive_contents_test( + name = "{}_direct_dependency_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:basic_framework_with_direct_dependency", + binary_test_file = "$BUNDLE_ROOT/DirectDependencyTest", + binary_test_architecture = "x86_64", + macho_load_commands_contain = ["name @rpath/DirectDependencyTest.framework/DirectDependencyTest (offset 24)"], + contains = [ + "$BUNDLE_ROOT/DirectDependencyTest", + "$BUNDLE_ROOT/Headers/DirectDependencyTest.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/DirectDependencyTest.swiftmodule/x86_64.swiftdoc", + "$BUNDLE_ROOT/Modules/DirectDependencyTest.swiftmodule/x86_64.swiftmodule" + ], + tags = [name], + ) + + archive_contents_test( + name = "{}_transitive_dependency_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:basic_framework_with_transitive_dependency", + binary_test_file = "$BUNDLE_ROOT/TransitiveDependencyTest", + binary_test_architecture = "x86_64", + macho_load_commands_contain = ["name @rpath/TransitiveDependencyTest.framework/TransitiveDependencyTest (offset 24)"], + contains = [ + "$BUNDLE_ROOT/TransitiveDependencyTest", + "$BUNDLE_ROOT/Headers/TransitiveDependencyTest.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/TransitiveDependencyTest.swiftmodule/x86_64.swiftdoc", + "$BUNDLE_ROOT/Modules/TransitiveDependencyTest.swiftmodule/x86_64.swiftmodule" + ], + tags = [name], + ) + + # Tests that libraries that both apps and frameworks depend only have symbols + # present in the framework. + archive_contents_test( + name = "{}_symbols_from_shared_library_in_framework".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_dynamic_framework_and_resources", + binary_test_architecture = "x86_64", + binary_test_file = "$BUNDLE_ROOT/Frameworks/swift_lib_with_resources.framework/swift_lib_with_resources", + binary_contains_symbols = ["_$s24swift_lib_with_resources16dontCallMeSharedyyF"], + tags = [name], + ) + + archive_contents_test( + name = "{}_symbols_from_shared_library_not_in_application".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_dynamic_framework_and_resources", + binary_test_file = "$BUNDLE_ROOT/app_with_dynamic_framework_and_resources", + binary_test_architecture = "x86_64", + binary_not_contains_symbols = ["_$s24swift_lib_with_resources16dontCallMeSharedyyF"], + tags = [name], + ) + + archive_contents_test( + name = "{}_app_includes_transitive_framework_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_dynamic_framework_with_dynamic_framework", + binary_test_file = "$BUNDLE_ROOT/Frameworks/swift_transitive_lib.framework/swift_transitive_lib", + binary_test_architecture = "x86_64", + contains = [ + "$BUNDLE_ROOT/Frameworks/swift_transitive_lib.framework/swift_transitive_lib", + "$BUNDLE_ROOT/Frameworks/swift_transitive_lib.framework/Info.plist", + "$BUNDLE_ROOT/Frameworks/swift_shared_lib.framework/swift_shared_lib", + "$BUNDLE_ROOT/Frameworks/swift_shared_lib.framework/Info.plist", + ], + not_contains = [ + "$BUNDLE_ROOT/Frameworks/swift_transitive_lib.framework/Frameworks/", + "$BUNDLE_ROOT/Frameworks/swift_transitive_lib.framework/nonlocalized.plist", + "$BUNDLE_ROOT/framework_resources/nonlocalized.plist", + ], + binary_contains_symbols = ["_$s20swift_transitive_lib21anotherFunctionSharedyyF"], + tags = [name], + ) + + archive_contents_test( + name = "{}_app_includes_transitive_framework_symbols_not_in_app".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_dynamic_framework_with_dynamic_framework", + binary_test_file = "$BUNDLE_ROOT/app_with_dynamic_framework_with_dynamic_framework", + binary_test_architecture = "x86_64", + binary_not_contains_symbols = ["_$s20swift_transitive_lib21anotherFunctionSharedyyF"], + tags = [name], + ) + + native.test_suite( + name = name, + tags = [name], + ) diff --git a/test/starlark_tests/resources/BUILD b/test/starlark_tests/resources/BUILD index a6d102e59c..65c3e6b9e8 100644 --- a/test/starlark_tests/resources/BUILD +++ b/test/starlark_tests/resources/BUILD @@ -73,6 +73,67 @@ swift_library( tags = FIXTURE_TAGS, ) +swift_library( + name = "swift_lib_with_resources", + module_name = "swift_lib_with_resources", + srcs = [ + "Shared.swift", + ], + data = [ + ":structured_resources", + ], + testonly = True, + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +swift_library( + name = "swift_common_lib", + module_name = "swift_common_lib", + srcs = ["Common.swift"], + testonly = True, + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +swift_library( + name = "swift_shared_lib", + module_name = "swift_shared_lib", + srcs = ["Shared.swift"], + deps = [ + "//test/starlark_tests/resources:swift_common_lib", + ], + testonly = True, + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +swift_library( + name = "swift_transitive_lib", + module_name = "swift_transitive_lib", + srcs = ["Transitives.swift"], + deps = [ + "//test/starlark_tests/resources:swift_common_lib", + "//test/starlark_tests/resources:swift_shared_lib", + ], + testonly = True, + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +swift_library( + name = "swift_lib_with_transitives", + module_name = "dynamic_framework_with_resources", + srcs = ["Shared.swift"], + data = [ + "//test/starlark_tests/targets_under_test/ios:swift_common_lib_framework", + "//test/starlark_tests/targets_under_test/ios:swift_shared_lib_framework", + ], + testonly = True, + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + swift_library( name = "swift_framework_lib", srcs = ["//test/testdata/sources:main.swift"], diff --git a/test/starlark_tests/resources/BasicFramework.swift b/test/starlark_tests/resources/BasicFramework.swift new file mode 100644 index 0000000000..9e8e35a5c9 --- /dev/null +++ b/test/starlark_tests/resources/BasicFramework.swift @@ -0,0 +1,20 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +public class BasicFramework { + public init() {} + public func HelloWorld() { print("Hello World from Basic Framework") } +} diff --git a/test/starlark_tests/resources/Common.swift b/test/starlark_tests/resources/Common.swift new file mode 100644 index 0000000000..f7f3edd45a --- /dev/null +++ b/test/starlark_tests/resources/Common.swift @@ -0,0 +1,23 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +func doSomethingCommon() { + print("Doing something common") +} + +public protocol ObjectiveCCommonClass { + func doSomethingShared() +} diff --git a/test/starlark_tests/resources/DirectDependencyTest.swift b/test/starlark_tests/resources/DirectDependencyTest.swift new file mode 100644 index 0000000000..585b2cb92d --- /dev/null +++ b/test/starlark_tests/resources/DirectDependencyTest.swift @@ -0,0 +1,25 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation +import BasicFramework + +public class DirectDependencyTest { + public init() {} + public func directDependencyTest() { + print("DirectDependencyTest") + let framework = BasicFramework() + framework.HelloWorld() + } +} diff --git a/test/starlark_tests/resources/Info-watchos.plist b/test/starlark_tests/resources/Info-watchos.plist new file mode 100644 index 0000000000..6b0c9c34ec --- /dev/null +++ b/test/starlark_tests/resources/Info-watchos.plist @@ -0,0 +1,16 @@ + + + + + CFBundleName + $(PRODUCT_NAME) + CFBundleVersion + 1.0 + CFBundleShortVersionString + 1.0 + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundlePackageType + WatchOS + + diff --git a/test/starlark_tests/resources/Shared.swift b/test/starlark_tests/resources/Shared.swift new file mode 100644 index 0000000000..79621fc857 --- /dev/null +++ b/test/starlark_tests/resources/Shared.swift @@ -0,0 +1,35 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +public func dontCallMeShared() { + _ = 0; +} + +public func anotherFunctionShared() { + _ = 0; +} + +public func anticipatedDeadCode() { + _ = 0; +} + +public func doSomethingShared() { + print("Doing something shared") +} + +public protocol ObjectiveCSharedClass { + func doSomethingShared() +} diff --git a/test/starlark_tests/resources/TransitiveDependencyTest.swift b/test/starlark_tests/resources/TransitiveDependencyTest.swift new file mode 100644 index 0000000000..63d72e9121 --- /dev/null +++ b/test/starlark_tests/resources/TransitiveDependencyTest.swift @@ -0,0 +1,28 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation +import BasicFramework +import DirectDependencyTest + +public class TransitiveDependencyTest { + public init() {} + public func TransitiveDependencyTest() { + print("TransitiveDependencyTest") + let framework = BasicFramework() + framework.HelloWorld() + let framework2 = DirectDependencyTest() + framework2.directDependencyTest() + } +} diff --git a/test/starlark_tests/resources/Transitives.swift b/test/starlark_tests/resources/Transitives.swift new file mode 100644 index 0000000000..e74705a8b5 --- /dev/null +++ b/test/starlark_tests/resources/Transitives.swift @@ -0,0 +1,37 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +public func dontCallMeShared() { + _ = 0; +} + +public func anotherFunctionShared() { + _ = 0; +} + +public func anticipatedDeadCode() { + _ = 0; +} + +public func doSomethingShared() { + print("Doing something shared") +} + +public class Transitives { + public init() {} + public func doSomethingShared() { print("Something shared from transitives") } + public func doSomethingCommon() { print("Something common from transitives") } +} diff --git a/test/starlark_tests/resources/main.swift b/test/starlark_tests/resources/main.swift new file mode 100644 index 0000000000..c4f2b3c446 --- /dev/null +++ b/test/starlark_tests/resources/main.swift @@ -0,0 +1,20 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +public class main { + public init() {} + public func main() { print("Hello from main") } +} diff --git a/test/starlark_tests/targets_under_test/ios/BUILD b/test/starlark_tests/targets_under_test/ios/BUILD index d60579cd77..19c5b6df08 100644 --- a/test/starlark_tests/targets_under_test/ios/BUILD +++ b/test/starlark_tests/targets_under_test/ios/BUILD @@ -5,12 +5,14 @@ load( "ios_application", "ios_extension", "ios_framework", + "ios_dynamic_framework", "ios_imessage_application", "ios_static_framework", "ios_sticker_pack_extension", "ios_ui_test", "ios_unit_test", ) +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") load("//test/testdata/rules:substitution.bzl", "substitution") load("//test/starlark_tests:common.bzl", "FIXTURE_TAGS") @@ -1677,3 +1679,241 @@ ios_unit_test( ":test_lib", ], ) + +swift_library( + name = "basic_framework_lib", + module_name = "BasicFramework", + srcs = [ + "//test/starlark_tests/resources:BasicFramework.swift", + ], + visibility = ["//visibility:public"], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +ios_dynamic_framework( + name = "basic_framework", + bundle_name = "BasicFramework", + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_lib", + ], +) + +swift_library( + name = "basic_framework_with_direct_dependency_lib", + module_name = "DirectDependencyTest", + srcs = [ + "//test/starlark_tests/resources:DirectDependencyTest.swift", + ], + visibility = ["//visibility:public"], + deps = [ + ":basic_framework_lib", + ], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +ios_dynamic_framework( + name = "basic_framework_with_direct_dependency", + bundle_name = "DirectDependencyTest", + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_with_direct_dependency_lib", + ], +) + +swift_library( + name = "basic_framework_with_transitive_dependency_lib", + module_name = "TransitiveDependencyTest", + srcs = [ + "//test/starlark_tests/resources:TransitiveDependencyTest.swift", + ], + visibility = ["//visibility:public"], + deps = [ + ":basic_framework_lib", + ":basic_framework_with_direct_dependency_lib", + ], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +ios_dynamic_framework( + name = "basic_framework_with_transitive_dependency", + bundle_name = "TransitiveDependencyTest", + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_with_transitive_dependency_lib", + ], +) + +ios_dynamic_framework( + name = "dynamic_framework_with_resources", + bundle_name = "swift_lib_with_resources", + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + linkopts = ["-application_extension"], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = [ + "//test/starlark_tests/resources:swift_lib_with_resources", + ], +) + +ios_application( + name = "app_with_dynamic_framework_and_resources", + bundle_id = "com.google.example", + families = ["iphone"], + frameworks = [ + ":dynamic_framework_with_resources", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "11.0", + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = FIXTURE_TAGS, + deps = [ + "//test/starlark_tests/resources:swift_lib_with_resources", + "//test/starlark_tests/resources:objc_main_lib", + ], +) + +ios_dynamic_framework( + name = "swift_common_lib_framework", + bundle_name = "swift_common_lib", + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = ["//test/starlark_tests/resources:swift_common_lib"] +) + +ios_dynamic_framework( + name = "swift_shared_lib_framework", + bundle_name = "swift_shared_lib", + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = [ + "//test/starlark_tests/resources:swift_shared_lib", + ] +) + +ios_dynamic_framework( + name = "swift_transitive_lib_framework", + bundle_name = "swift_transitive_lib", + frameworks = [":swift_shared_lib_framework"], + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = ["//test/starlark_tests/resources:swift_transitive_lib"] +) + +ios_application( + name = "app_with_dynamic_framework_with_dynamic_framework", + bundle_id = "com.google.example", + families = [ + "iphone", + "ipad", + ], + frameworks = [":swift_transitive_lib_framework"], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = [ + "//test/starlark_tests/resources:ios_non_localized_assets_lib", + "//test/starlark_tests/resources:objc_main_lib", + ], +) + +ios_dynamic_framework( + name = "dynamic_fmwk_with_imported_fmwk", + bundle_id = "com.google.example.framework", + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "8.0", + tags = FIXTURE_TAGS, + deps = [ + "//test/starlark_tests/resources:objc_lib_with_resources", + "//test/testdata/frameworks:iOSImportedDynamicFramework", + ], +) + +ios_application( + name = "app_with_inner_and_outer_dynamic_framework", + bundle_id = "com.google.example", + families = ["iphone"], + frameworks = [ + ":dynamic_fmwk_with_imported_fmwk", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "11.0", + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = FIXTURE_TAGS, + deps = [ + "//test/starlark_tests/resources:objc_main_lib", + ], +) diff --git a/test/starlark_tests/targets_under_test/tvos/BUILD b/test/starlark_tests/targets_under_test/tvos/BUILD index 02df53bf48..059a3cde96 100644 --- a/test/starlark_tests/targets_under_test/tvos/BUILD +++ b/test/starlark_tests/targets_under_test/tvos/BUILD @@ -2,6 +2,7 @@ load("@rules_cc//cc:defs.bzl", "objc_library") load( "//apple:tvos.bzl", "tvos_application", + "tvos_dynamic_framework", "tvos_extension", "tvos_framework", "tvos_static_framework", @@ -392,3 +393,87 @@ objc_library( tags = FIXTURE_TAGS, deps = [":swift_lib"], ) + +# --------------------------------------------------------------------------------------- + +swift_library( + name = "basic_framework_lib", + module_name = "BasicFramework", + srcs = [ + "//test/starlark_tests/resources:BasicFramework.swift", + ], + visibility = ["//visibility:public"], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +tvos_dynamic_framework( + name = "basic_framework", + bundle_name = "BasicFramework", + bundle_id = "com.google.example.framework", + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "14.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_lib", + ], +) + +swift_library( + name = "basic_framework_with_direct_dependency_lib", + module_name = "DirectDependencyTest", + srcs = [ + "//test/starlark_tests/resources:DirectDependencyTest.swift", + ], + visibility = ["//visibility:public"], + deps = [ + ":basic_framework_lib", + ], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +tvos_dynamic_framework( + name = "basic_framework_with_direct_dependency", + bundle_name = "DirectDependencyTest", + bundle_id = "com.google.example.framework", + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "14.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_with_direct_dependency_lib", + ], +) + +swift_library( + name = "basic_framework_with_transitive_dependency_lib", + module_name = "TransitiveDependencyTest", + srcs = [ + "//test/starlark_tests/resources:TransitiveDependencyTest.swift", + ], + visibility = ["//visibility:public"], + deps = [ + ":basic_framework_lib", + ":basic_framework_with_direct_dependency_lib", + ], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +tvos_dynamic_framework( + name = "basic_framework_with_transitive_dependency", + bundle_name = "TransitiveDependencyTest", + bundle_id = "com.google.example.framework", + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = "14.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_with_transitive_dependency_lib", + ], +) diff --git a/test/starlark_tests/targets_under_test/watchos/BUILD b/test/starlark_tests/targets_under_test/watchos/BUILD index 965d3526cd..d05b848425 100644 --- a/test/starlark_tests/targets_under_test/watchos/BUILD +++ b/test/starlark_tests/targets_under_test/watchos/BUILD @@ -6,6 +6,7 @@ load( load( "//apple:watchos.bzl", "watchos_application", + "watchos_dynamic_framework", "watchos_extension", ) load( @@ -307,3 +308,88 @@ swift_library( srcs = ["//test/testdata/sources:main.swift"], tags = FIXTURE_TAGS, ) + +# --------------------------------------------------------------------------------------- + +swift_library( + name = "basic_framework_lib", + module_name = "BasicFramework", + srcs = [ + "//test/starlark_tests/resources:BasicFramework.swift", + "//test/starlark_tests/resources:main.swift", + ], + visibility = ["//visibility:public"], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +watchos_dynamic_framework( + name = "basic_framework", + bundle_name = "BasicFramework", + bundle_id = "com.google.example.framework", + infoplists = [ + "//test/starlark_tests/resources:Info-watchos.plist", + ], + minimum_os_version = "6.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_lib", + ], +) + +swift_library( + name = "basic_framework_with_direct_dependency_lib", + module_name = "DirectDependencyTest", + srcs = [ + "//test/starlark_tests/resources:DirectDependencyTest.swift", + ], + visibility = ["//visibility:public"], + deps = [ + ":basic_framework_lib", + ], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +watchos_dynamic_framework( + name = "basic_framework_with_direct_dependency", + bundle_name = "DirectDependencyTest", + bundle_id = "com.google.example.framework", + infoplists = [ + "//test/starlark_tests/resources:Info-watchos.plist", + ], + minimum_os_version = "6.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_with_direct_dependency_lib", + ], +) + +swift_library( + name = "basic_framework_with_transitive_dependency_lib", + module_name = "TransitiveDependencyTest", + srcs = [ + "//test/starlark_tests/resources:TransitiveDependencyTest.swift", + ], + visibility = ["//visibility:public"], + deps = [ + ":basic_framework_lib", + ":basic_framework_with_direct_dependency_lib", + ], + features = ["swift.no_generated_module_map"], + tags = FIXTURE_TAGS, +) + +watchos_dynamic_framework( + name = "basic_framework_with_transitive_dependency", + bundle_name = "TransitiveDependencyTest", + bundle_id = "com.google.example.framework", + infoplists = [ + "//test/starlark_tests/resources:Info-watchos.plist", + ], + minimum_os_version = "6.0", + tags = FIXTURE_TAGS, + deps = [ + ":basic_framework_with_transitive_dependency_lib", + ], +) diff --git a/test/starlark_tests/tvos_dynamic_framework_tests.bzl b/test/starlark_tests/tvos_dynamic_framework_tests.bzl new file mode 100644 index 0000000000..6bcac23cfa --- /dev/null +++ b/test/starlark_tests/tvos_dynamic_framework_tests.bzl @@ -0,0 +1,113 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""tvos_dynamic_framework Starlark tests.""" + +load( + ":rules/common_verification_tests.bzl", + "archive_contents_test", +) +load( + ":rules/infoplist_contents_test.bzl", + "infoplist_contents_test", +) + +def tvos_dynamic_framework_test_suite(name = "tvos_dynamic_framework"): + """Test suite for tvos_dynamic_framework. + + Args: + name: The name prefix for all the nested tests + """ + + archive_contents_test( + name = "{}_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/tvos:basic_framework", + binary_test_file = "$BUNDLE_ROOT/BasicFramework", + binary_test_architecture = "x86_64", + macho_load_commands_contain = ["name @rpath/BasicFramework.framework/BasicFramework (offset 24)"], + contains = [ + "$BUNDLE_ROOT/BasicFramework", + "$BUNDLE_ROOT/Headers/BasicFramework.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/BasicFramework.swiftmodule/x86_64.swiftdoc", + "$BUNDLE_ROOT/Modules/BasicFramework.swiftmodule/x86_64.swiftmodule" + ], + tags = [name], + ) + + infoplist_contents_test( + name = "{}_plist_test".format(name), + target_under_test = "//test/starlark_tests/targets_under_test/tvos:basic_framework", + expected_values = { + "BuildMachineOSBuild": "*", + "CFBundleExecutable": "BasicFramework", + "CFBundleIdentifier": "com.google.example.framework", + "CFBundleName": "BasicFramework", + "CFBundleSupportedPlatforms:0": "AppleTV*", + "DTCompiler": "com.apple.compilers.llvm.clang.1_0", + "DTPlatformBuild": "*", + "DTPlatformName": "appletvs*", + "DTPlatformVersion": "*", + "DTSDKBuild": "*", + "DTSDKName": "appletv*", + "DTXcode": "*", + "DTXcodeBuild": "*", + "MinimumOSVersion": "14.0", + "UIDeviceFamily:0": "3", + }, + tags = [name], + ) + + archive_contents_test( + name = "{}_direct_dependency_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/tvos:basic_framework_with_direct_dependency", + binary_test_file = "$BUNDLE_ROOT/DirectDependencyTest", + binary_test_architecture = "x86_64", + macho_load_commands_contain = ["name @rpath/DirectDependencyTest.framework/DirectDependencyTest (offset 24)"], + contains = [ + "$BUNDLE_ROOT/DirectDependencyTest", + "$BUNDLE_ROOT/Headers/DirectDependencyTest.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/DirectDependencyTest.swiftmodule/x86_64.swiftdoc", + "$BUNDLE_ROOT/Modules/DirectDependencyTest.swiftmodule/x86_64.swiftmodule" + ], + tags = [name], + ) + + archive_contents_test( + name = "{}_transitive_dependency_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/tvos:basic_framework_with_transitive_dependency", + binary_test_file = "$BUNDLE_ROOT/TransitiveDependencyTest", + binary_test_architecture = "x86_64", + macho_load_commands_contain = ["name @rpath/TransitiveDependencyTest.framework/TransitiveDependencyTest (offset 24)"], + contains = [ + "$BUNDLE_ROOT/TransitiveDependencyTest", + "$BUNDLE_ROOT/Headers/TransitiveDependencyTest.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/TransitiveDependencyTest.swiftmodule/x86_64.swiftdoc", + "$BUNDLE_ROOT/Modules/TransitiveDependencyTest.swiftmodule/x86_64.swiftmodule" + ], + tags = [name], + ) + + native.test_suite( + name = name, + tags = [name], + ) diff --git a/test/starlark_tests/watchos_dynamic_framework_tests.bzl b/test/starlark_tests/watchos_dynamic_framework_tests.bzl new file mode 100644 index 0000000000..a9e7981edb --- /dev/null +++ b/test/starlark_tests/watchos_dynamic_framework_tests.bzl @@ -0,0 +1,111 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""watchos_dynamic_framework Starlark tests.""" + +load( + ":rules/common_verification_tests.bzl", + "archive_contents_test", +) +load( + ":rules/infoplist_contents_test.bzl", + "infoplist_contents_test", +) + +def watchos_dynamic_framework_test_suite(name = "watchos_dynamic_framework"): + """Test suite for watchos_dynamic_framework. + + Args: + name: The name prefix for all the nested tests + """ + + archive_contents_test( + name = "{}_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/watchos:basic_framework", + binary_test_file = "$BUNDLE_ROOT/BasicFramework", + binary_test_architecture = "i386", + contains = [ + "$BUNDLE_ROOT/BasicFramework", + "$BUNDLE_ROOT/Headers/BasicFramework.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/BasicFramework.swiftmodule/i386.swiftdoc", + "$BUNDLE_ROOT/Modules/BasicFramework.swiftmodule/i386.swiftmodule" + ], + tags = [name], + ) + + infoplist_contents_test( + name = "{}_plist_test".format(name), + target_under_test = "//test/starlark_tests/targets_under_test/watchos:basic_framework", + expected_values = { + "BuildMachineOSBuild": "*", + "CFBundleExecutable": "BasicFramework", + "CFBundleIdentifier": "com.google.example.framework", + "CFBundleName": "BasicFramework", + "CFBundleSupportedPlatforms:0": "WatchSimulator*", + "DTCompiler": "com.apple.compilers.llvm.clang.1_0", + "DTPlatformBuild": "*", + "DTPlatformName": "watchsimulator*", + "DTPlatformVersion": "*", + "DTSDKBuild": "*", + "DTSDKName": "watchsimulator*", + "DTXcode": "*", + "DTXcodeBuild": "*", + "MinimumOSVersion": "6.0", + "UIDeviceFamily:0": "4", + }, + tags = [name], + ) + + archive_contents_test( + name = "{}_direct_dependency_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/watchos:basic_framework_with_direct_dependency", + binary_test_file = "$BUNDLE_ROOT/DirectDependencyTest", + binary_test_architecture = "i386", + contains = [ + "$BUNDLE_ROOT/DirectDependencyTest", + "$BUNDLE_ROOT/Headers/DirectDependencyTest.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/DirectDependencyTest.swiftmodule/i386.swiftdoc", + "$BUNDLE_ROOT/Modules/DirectDependencyTest.swiftmodule/i386.swiftmodule" + ], + tags = [name], + ) + + + archive_contents_test( + name = "{}_transitive_dependency_archive_contents_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/watchos:basic_framework_with_transitive_dependency", + binary_test_file = "$BUNDLE_ROOT/TransitiveDependencyTest", + binary_test_architecture = "i386", + contains = [ + "$BUNDLE_ROOT/TransitiveDependencyTest", + "$BUNDLE_ROOT/Headers/TransitiveDependencyTest.h", + "$BUNDLE_ROOT/Info.plist", + "$BUNDLE_ROOT/Modules/module.modulemap", + "$BUNDLE_ROOT/Modules/TransitiveDependencyTest.swiftmodule/i386.swiftdoc", + "$BUNDLE_ROOT/Modules/TransitiveDependencyTest.swiftmodule/i386.swiftmodule" + ], + tags = [name], + ) + + native.test_suite( + name = name, + tags = [name], + )