diff --git a/bazel/swift_header_collector.bzl b/bazel/swift_header_collector.bzl new file mode 100644 index 0000000000..e47deb18a0 --- /dev/null +++ b/bazel/swift_header_collector.bzl @@ -0,0 +1,22 @@ +""" +Propagate the generated Swift header from a swift_library target + +This exists to work around https://github.com/bazelbuild/rules_swift/issues/291 +""" + +def _swift_header_collector(ctx): + return [ + DefaultInfo( + files = ctx.attr.library[CcInfo].compilation_context.headers, + ), + ] + +swift_header_collector = rule( + attrs = dict( + library = attr.label( + mandatory = True, + providers = [CcInfo], + ), + ), + implementation = _swift_header_collector, +) diff --git a/bazel/swift_static_framework.bzl b/bazel/swift_static_framework.bzl deleted file mode 100644 index 6f881457c3..0000000000 --- a/bazel/swift_static_framework.bzl +++ /dev/null @@ -1,204 +0,0 @@ -""" -This rules creates a fat static framework that can be included later with -static_framework_import -""" - -load("@build_bazel_apple_support//lib:apple_support.bzl", "apple_support") -load("@build_bazel_rules_swift//swift:swift.bzl", "SwiftInfo", "swift_library") - -MINIMUM_IOS_VERSION = "10.0" - -_PLATFORM_TO_SWIFTMODULE = { - "ios_armv7": "arm", - "ios_arm64": "arm64", - "ios_i386": "i386", - "ios_x86_64": "x86_64", -} - -def _zip_binary_arg(module_name, input_file): - return "{module_name}.framework/{module_name}={file_path}".format( - module_name = module_name, - file_path = input_file.path, - ) - -def _zip_header_arg(module_name, input_file): - return "{module_name}.framework/Headers/{module_name}-Swift.h={file_path}".format( - module_name = module_name, - file_path = input_file.path, - ) - -def _zip_swift_arg(module_name, swift_identifier, input_file): - return "{module_name}.framework/Modules/{module_name}.swiftmodule/{swift_identifier}.{ext}={file_path}".format( - module_name = module_name, - swift_identifier = swift_identifier, - ext = input_file.extension, - file_path = input_file.path, - ) - -def _swift_static_framework_impl(ctx): - module_name = ctx.attr.framework_name - fat_file = ctx.outputs.fat_file - - input_archives = [] - input_modules_docs = [] - zip_args = [_zip_binary_arg(module_name, fat_file)] - - for platform, archive in ctx.split_attr.archive.items(): - swiftmodule_identifier = _PLATFORM_TO_SWIFTMODULE[platform] - if not swiftmodule_identifier: - fail("Unhandled platform '{}'".format(platform)) - - swift_info = archive[SwiftInfo] - - # We can potentially simplify this if this change lands upstream: - # https://github.com/bazelbuild/rules_swift/issues/291 - objc_headers = [ - header - for header in archive[apple_common.Objc].header.to_list() - if header.path.endswith("-Swift.h") - ] - - if len(objc_headers) == 1: - zip_args.append(_zip_header_arg(module_name, objc_headers[0])) - else: - header_names = [header.basename for header in objc_headers] - fail("Expected exactly 1 '-Swift.h' header, got {}".format(", ".join(header_names))) - - swiftdoc = swift_info.direct_swiftdocs[0] - swiftmodule = swift_info.direct_swiftmodules[0] - - libraries = archive[CcInfo].linking_context.libraries_to_link - archives = [] - for library in libraries.to_list(): - archive = library.pic_static_library or library.static_library - if archive: - archives.append(archive) - else: - fail("All linked dependencies must be static") - - platform_archive = ctx.actions.declare_file("{}.{}.a".format(module_name, platform)) - - libtool_args = ["-no_warning_for_no_symbols", "-static", "-syslibroot", "__BAZEL_XCODE_SDKROOT__", "-o", platform_archive.path] + [x.path for x in archives] - apple_support.run( - ctx, - inputs = archives, - outputs = [platform_archive], - mnemonic = "LibtoolLinkedLibraries", - progress_message = "Combining libraries for {} on {}".format(module_name, platform), - executable = ctx.executable._libtool, - arguments = libtool_args, - ) - - input_archives.append(platform_archive) - - input_modules_docs += [swiftdoc, swiftmodule] - zip_args += [ - _zip_swift_arg(module_name, swiftmodule_identifier, swiftdoc), - _zip_swift_arg(module_name, swiftmodule_identifier, swiftmodule), - ] - - ctx.actions.run( - inputs = input_archives, - outputs = [fat_file], - mnemonic = "LipoPlatformLibraries", - progress_message = "Creating fat library for {}".format(module_name), - executable = "lipo", - arguments = ["-create", "-output", fat_file.path] + [x.path for x in input_archives], - ) - - output_file = ctx.outputs.output_file - ctx.actions.run( - inputs = input_modules_docs + [fat_file], - outputs = [output_file], - mnemonic = "CreateFrameworkZip", - progress_message = "Creating framework zip for {}".format(module_name), - executable = ctx.executable._zipper, - arguments = ["c", output_file.path] + zip_args, - ) - - return [ - DefaultInfo( - files = depset([output_file]), - ), - ] - -_swift_static_framework = rule( - attrs = dict( - apple_support.action_required_attrs(), - _libtool = attr.label( - default = "@bazel_tools//tools/objc:libtool", - cfg = "host", - executable = True, - ), - _zipper = attr.label( - default = "@bazel_tools//tools/zip:zipper", - cfg = "host", - executable = True, - ), - archive = attr.label( - mandatory = True, - providers = [ - CcInfo, - SwiftInfo, - ], - cfg = apple_common.multi_arch_split, - ), - framework_name = attr.string(mandatory = True), - minimum_os_version = attr.string(default = MINIMUM_IOS_VERSION), - platform_type = attr.string( - default = str(apple_common.platform_type.ios), - ), - ), - fragments = [ - "apple", - ], - outputs = { - "fat_file": "%{framework_name}.fat", - "output_file": "%{framework_name}.zip", - }, - implementation = _swift_static_framework_impl, -) - -def swift_static_framework( - name, - module_name = None, - srcs = [], - deps = [], - objc_includes = [], - copts = [], - swiftc_inputs = [], - visibility = []): - """Create a static library, and static framework target for a swift module - - Args: - name: The name of the module, the framework's name will be this name - appending Framework so you can depend on this from other modules - srcs: Custom source paths for the swift files - objc_includes: Header files for any objective-c dependencies (required for linking) - copts: Any custom swiftc opts passed through to the swift_library - swiftc_inputs: Any labels that require expansion for copts (would also apply to linkopts) - deps: Any deps the swift_library requires - """ - archive_name = name + "_archive" - module_name = module_name or name + "_framework" - if objc_includes: - locations = ["$(location {})".format(x) for x in objc_includes] - copts = copts + ["-import-objc-header"] + locations - swiftc_inputs = swiftc_inputs + objc_includes - - swift_library( - name = archive_name, - srcs = srcs, - copts = copts, - swiftc_inputs = swiftc_inputs, - module_name = module_name, - visibility = ["//visibility:public"], - deps = deps, - ) - - _swift_static_framework( - name = name, - archive = archive_name, - framework_name = module_name, - visibility = visibility, - ) diff --git a/bazel/swift_test.bzl b/bazel/swift_test.bzl index 9eb9bb3785..aff4aa0e83 100644 --- a/bazel/swift_test.bzl +++ b/bazel/swift_test.bzl @@ -23,7 +23,7 @@ def envoy_mobile_swift_test(name, srcs): name = test_lib_name, srcs = srcs, deps = [ - "//library/swift/src:ios_framework_archive", + "//library/swift/src:lib", ], linkopts = ["-lresolv.9"], visibility = ["//visibility:private"], diff --git a/envoy-mobile.tulsiproj/Configs/all.tulsigen b/envoy-mobile.tulsiproj/Configs/all.tulsigen index 890f16b5ec..9ab31e6762 100644 --- a/envoy-mobile.tulsiproj/Configs/all.tulsigen +++ b/envoy-mobile.tulsiproj/Configs/all.tulsigen @@ -4,7 +4,7 @@ "library/swift/test/BUILD" ], "buildTargets" : [ - "//library/swift/src:ios_framework_archive" + "//library/swift/src:lib" ], "optionSet" : { "BazelBuildOptionsDebug" : { diff --git a/examples/objective-c/hello_world/ViewController.m b/examples/objective-c/hello_world/ViewController.m index 798f7e2975..a0cce26bf9 100644 --- a/examples/objective-c/hello_world/ViewController.m +++ b/examples/objective-c/hello_world/ViewController.m @@ -1,4 +1,4 @@ -#import +#import #import #import "Result.h" #import "ViewController.h" diff --git a/library/objective-c/BUILD b/library/objective-c/BUILD index 526e89d23b..ee13413674 100644 --- a/library/objective-c/BUILD +++ b/library/objective-c/BUILD @@ -16,6 +16,7 @@ objc_library( hdrs = [ "EnvoyEngine.h", ], + module_name = "EnvoyEngine", sdk_frameworks = [ "SystemConfiguration", "UIKit", diff --git a/library/swift/src/BUILD b/library/swift/src/BUILD index 126c08154d..8e96027645 100644 --- a/library/swift/src/BUILD +++ b/library/swift/src/BUILD @@ -1,9 +1,11 @@ licenses(["notice"]) # Apache 2 -load("//bazel:swift_static_framework.bzl", "swift_static_framework") +load("@build_bazel_rules_apple//apple:ios.bzl", "ios_static_framework") +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") +load("//bazel:swift_header_collector.bzl", "swift_header_collector") -swift_static_framework( - name = "ios_framework", +swift_library( + name = "lib", srcs = [ "Data+Extension.swift", "EnvoyClient.swift", @@ -27,9 +29,20 @@ swift_static_framework( "UpstreamHttpProtocol.swift", ], module_name = "Envoy", - objc_includes = [ - "//library/objective-c:EnvoyEngine.h", - ], + private_deps = ["//library/objective-c:envoy_engine_objc_lib"], + visibility = ["//visibility:public"], +) + +swift_header_collector( + name = "lib_headers", + library = "lib", +) + +ios_static_framework( + name = "ios_framework", + hdrs = ["lib_headers"], + bundle_name = "Envoy", + minimum_os_version = "10.0", visibility = ["//visibility:public"], - deps = ["//library/objective-c:envoy_engine_objc_lib"], + deps = ["lib"], ) diff --git a/library/swift/src/EnvoyClient.swift b/library/swift/src/EnvoyClient.swift index 93994c453d..c617a4a30c 100644 --- a/library/swift/src/EnvoyClient.swift +++ b/library/swift/src/EnvoyClient.swift @@ -1,3 +1,4 @@ +@_implementationOnly import EnvoyEngine import Foundation /// Envoy's implementation of `HTTPClient`, buildable using `EnvoyClientBuilder`. diff --git a/library/swift/src/EnvoyClientBuilder.swift b/library/swift/src/EnvoyClientBuilder.swift index 13b770d131..662f286248 100644 --- a/library/swift/src/EnvoyClientBuilder.swift +++ b/library/swift/src/EnvoyClientBuilder.swift @@ -1,3 +1,4 @@ +@_implementationOnly import EnvoyEngine import Foundation /// Builder used for creating new instances of EnvoyClient. diff --git a/library/swift/src/EnvoyStreamEmitter.swift b/library/swift/src/EnvoyStreamEmitter.swift index 5f9ccefae4..6373f72422 100644 --- a/library/swift/src/EnvoyStreamEmitter.swift +++ b/library/swift/src/EnvoyStreamEmitter.swift @@ -1,3 +1,4 @@ +@_implementationOnly import EnvoyEngine import Foundation /// Default implementation of the `StreamEmitter` interface. diff --git a/library/swift/src/ResponseHandler.swift b/library/swift/src/ResponseHandler.swift index cc82aaa73c..333d7d5b4f 100644 --- a/library/swift/src/ResponseHandler.swift +++ b/library/swift/src/ResponseHandler.swift @@ -1,3 +1,4 @@ +@_implementationOnly import EnvoyEngine import Foundation /// Callback interface for receiving stream events.