From d3f47657e54e50ce20b0785274f1515036440eaa Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Thu, 23 Feb 2023 13:25:43 -0700 Subject: [PATCH] feat: support `@import` of modules in Objective-C code (#238) - Fix the generation logic for Apple built-in frameworks to retrieve the values from the correct directories. - For Objective-C code, look for the import of Apple built-in frameworks and conditionally add them to the `sdk_frameworks` option in `objc_library`. - Generate modulemap for Swift targets `@import`'d by Objective-C. - Update module-to-Bazel label resolution to include modulemap targets when necessary. - Update Firebase example to use 10.5.0. - Enable the `appdistribution` example in the Firebase example. Closes #208. Closes #231. --- .bazelrc | 4 +- examples/firebase_example/Package.resolved | 32 +- examples/firebase_example/Package.swift | 2 +- .../AppDistributionExample/BUILD.bazel | 9 +- .../AppDistributionTests/BUILD.bazel | 3 - .../appdistribution/BUILD.bazel | 7 + examples/firebase_example/swift_deps.bzl | 20 +- .../firebase_example/swift_deps_index.json | 500 ++++++++++---- gazelle/internal/swift/builtin_modules.go | 303 ++++++++- gazelle/internal/swift/is_builtin_module.go | 17 +- .../internal/swift/is_builtin_module_test.go | 3 + swiftpkg/internal/BUILD.bazel | 31 + .../internal/apple_builtin_frameworks.bzl | 614 ++++++++++++++++++ swiftpkg/internal/bazel_apple_platforms.bzl | 33 + swiftpkg/internal/clang_files.bzl | 4 - swiftpkg/internal/deps_indexes.bzl | 94 ++- swiftpkg/internal/generate_modulemap.bzl | 12 +- swiftpkg/internal/module_maps.bzl | 3 +- swiftpkg/internal/objc_files.bzl | 145 +++++ swiftpkg/internal/pkginfo_target_deps.bzl | 8 +- swiftpkg/internal/pkginfo_targets.bzl | 27 + swiftpkg/internal/swift_files.bzl | 43 ++ swiftpkg/internal/swiftpkg_build_files.bzl | 131 +++- swiftpkg/tests/BUILD.bazel | 9 + .../tests/bazel_apple_platforms_tests.bzl | 49 ++ swiftpkg/tests/deps_indexes_tests.bzl | 98 ++- .../generate_modulemap_tests/BUILD.bazel | 1 + .../PrintVersionObjc/BUILD.bazel | 22 + .../PrintVersionObjc/main.m | 12 + .../Sources/FooSwift/BUILD.bazel | 26 + .../FooSwift/FooSwiftVersionInfo.swift | 10 + .../generate_modulemap_test.sh | 11 +- swiftpkg/tests/objc_files_tests.bzl | 145 +++++ swiftpkg/tests/pkginfo_target_deps_tests.bzl | 10 +- swiftpkg/tests/pkginfo_targets_tests.bzl | 11 + swiftpkg/tests/swift_files_tests.bzl | 65 ++ swiftpkg/tests/swiftpkg_build_files_tests.bzl | 130 +++- tools/generate_builtin_frameworks/BUILD.bazel | 3 + .../generate_builtin_frameworks.sh | 156 ++++- .../generate_builtin_frameworks_test.sh | 67 +- 40 files changed, 2544 insertions(+), 326 deletions(-) create mode 100644 examples/firebase_example/appdistribution/BUILD.bazel create mode 100644 swiftpkg/internal/apple_builtin_frameworks.bzl create mode 100644 swiftpkg/internal/bazel_apple_platforms.bzl create mode 100644 swiftpkg/internal/objc_files.bzl create mode 100644 swiftpkg/internal/swift_files.bzl create mode 100644 swiftpkg/tests/bazel_apple_platforms_tests.bzl create mode 100644 swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/BUILD.bazel create mode 100644 swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/main.m create mode 100644 swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/BUILD.bazel create mode 100644 swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/FooSwiftVersionInfo.swift create mode 100644 swiftpkg/tests/objc_files_tests.bzl create mode 100644 swiftpkg/tests/swift_files_tests.bzl diff --git a/.bazelrc b/.bazelrc index da7e265b1..967319a3b 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,7 +1,7 @@ # To update these lines, execute # `bazel run @contrib_rules_bazel_integration_test//tools:update_deleted_packages` -build --deleted_packages=examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/http_archive_ext_deps,examples/http_archive_ext_deps/Sources/MyDequeModule,examples/http_archive_ext_deps/Sources/PrintStuff,examples/http_archive_ext_deps/Tests/MyDequeModuleTests,examples/http_archive_ext_deps/third_party,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/objc_code,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example -query --deleted_packages=examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/http_archive_ext_deps,examples/http_archive_ext_deps/Sources/MyDequeModule,examples/http_archive_ext_deps/Sources/PrintStuff,examples/http_archive_ext_deps/Tests/MyDequeModuleTests,examples/http_archive_ext_deps/third_party,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/objc_code,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example +build --deleted_packages=examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/http_archive_ext_deps,examples/http_archive_ext_deps/Sources/MyDequeModule,examples/http_archive_ext_deps/Sources/PrintStuff,examples/http_archive_ext_deps/Tests/MyDequeModuleTests,examples/http_archive_ext_deps/third_party,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/objc_code,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example +query --deleted_packages=examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/http_archive_ext_deps,examples/http_archive_ext_deps/Sources/MyDequeModule,examples/http_archive_ext_deps/Sources/PrintStuff,examples/http_archive_ext_deps/Tests/MyDequeModuleTests,examples/http_archive_ext_deps/third_party,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/objc_code,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example # Import Shared settings import %workspace%/shared.bazelrc diff --git a/examples/firebase_example/Package.resolved b/examples/firebase_example/Package.resolved index 6bd421659..1c10147b7 100644 --- a/examples/firebase_example/Package.resolved +++ b/examples/firebase_example/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/abseil-cpp-SwiftPM.git", "state" : { - "revision" : "fffc3c2729be5747390ad02d5100291a0d9ad26a", - "version" : "0.20200225.4" + "revision" : "583de9bd60f66b40e78d08599cc92036c2e7e4e1", + "version" : "0.20220203.2" } }, { @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/boringssl-SwiftPM.git", "state" : { - "revision" : "734a8247442fde37df4364c21f6a0085b6a36728", - "version" : "0.7.2" + "revision" : "dd3eda2b05a3f459fc3073695ad1b28659066eab", + "version" : "0.9.1" } }, { @@ -23,8 +23,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk", "state" : { - "revision" : "839cc6b0cd80b0b8bf81fe9bd82b743b25dc6446", - "version" : "8.9.1" + "revision" : "f567ed9a2b30e29159df258049a9c662c517688e", + "version" : "10.5.0" } }, { @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { - "revision" : "9b2f6aca5b4685c45f9f5481f19bee8e7982c538", - "version" : "8.9.1" + "revision" : "9a09ece724128e8d1e14c5133b87c0e236844ac0", + "version" : "10.4.0" } }, { @@ -55,12 +55,12 @@ } }, { - "identity" : "grpc-swiftpm", + "identity" : "grpc-ios", "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/grpc-SwiftPM.git", + "location" : "https://github.com/grpc/grpc-ios.git", "state" : { - "revision" : "fb405dd2c7901485f7e158b24e3a0a47e4efd8b5", - "version" : "1.28.4" + "revision" : "8440b914756e0d26d4f4d054a1c1581daedfc5b6", + "version" : "1.44.3-grpc" } }, { @@ -68,8 +68,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/gtm-session-fetcher.git", "state" : { - "revision" : "4e9bbf2808b8fee444e84a48f5f3c12641987d3e", - "version" : "1.7.2" + "revision" : "96d7cc73a71ce950723aa3c50ce4fb275ae180b8", + "version" : "3.1.0" } }, { @@ -86,8 +86,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/nanopb.git", "state" : { - "revision" : "7ee9ef9f627d85cbe1b8c4f49a3ed26eed216c77", - "version" : "2.30908.0" + "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", + "version" : "2.30909.0" } }, { diff --git a/examples/firebase_example/Package.swift b/examples/firebase_example/Package.swift index 60ecd1c62..21895d17a 100644 --- a/examples/firebase_example/Package.swift +++ b/examples/firebase_example/Package.swift @@ -5,6 +5,6 @@ import PackageDescription let package = Package( name: "firebase_example", dependencies: [ - .package(url: "https://github.com/firebase/firebase-ios-sdk", .exact("8.9.1")), + .package(url: "https://github.com/firebase/firebase-ios-sdk", .upToNextMajor(from: "10.0.0")), ] ) diff --git a/examples/firebase_example/appdistribution/AppDistributionExample/BUILD.bazel b/examples/firebase_example/appdistribution/AppDistributionExample/BUILD.bazel index cd01111ce..c22a47628 100644 --- a/examples/firebase_example/appdistribution/AppDistributionExample/BUILD.bazel +++ b/examples/firebase_example/appdistribution/AppDistributionExample/BUILD.bazel @@ -12,7 +12,9 @@ swift_library( tags = ["manual"], visibility = ["//visibility:public"], # GH202: Incomplete deps are generated. - deps = ["@swiftpkg_firebase_ios_sdk//:SwiftPM-PlatformExclude_FirebaseAppDistributionWrap_FirebaseAppDistributionTarget"], + deps = [ + "@swiftpkg_firebase_ios_sdk//:SwiftPM-PlatformExclude_FirebaseAppDistributionWrap_FirebaseAppDistributionTarget", + ], ) ios_application( @@ -29,10 +31,7 @@ ios_application( ["Assets.xcassets/**"], exclude = ["Assets.xcassets/AppIcon.appiconset/**"], ) + [ - ":GoogleService-Info.plist", + "//appdistribution:shared_resources", ], - # GH208: This fails due to an Objc module not being found by another Objc module. - # Marking as manual so that they do not run during CI. - tags = ["manual"], deps = [":AppDistributionExample"], ) diff --git a/examples/firebase_example/appdistribution/AppDistributionTests/BUILD.bazel b/examples/firebase_example/appdistribution/AppDistributionTests/BUILD.bazel index 5527e13ea..390a76ff0 100644 --- a/examples/firebase_example/appdistribution/AppDistributionTests/BUILD.bazel +++ b/examples/firebase_example/appdistribution/AppDistributionTests/BUILD.bazel @@ -13,9 +13,6 @@ swift_library( ios_unit_test( name = "FooTests", minimum_os_version = "13.0", - # GH208: This fails due to an Objc module not being found by another Objc module. - # Marking as manual so that they do not run during CI. - tags = ["manual"], visibility = ["//visibility:private"], deps = [":AppDistributionTests"], ) diff --git a/examples/firebase_example/appdistribution/BUILD.bazel b/examples/firebase_example/appdistribution/BUILD.bazel new file mode 100644 index 000000000..7ebc3ab08 --- /dev/null +++ b/examples/firebase_example/appdistribution/BUILD.bazel @@ -0,0 +1,7 @@ +filegroup( + name = "shared_resources", + srcs = [ + "GoogleService-Info.plist", + ], + visibility = ["//appdistribution:__subpackages__"], +) diff --git a/examples/firebase_example/swift_deps.bzl b/examples/firebase_example/swift_deps.bzl index f65ae45d8..7c6320963 100644 --- a/examples/firebase_example/swift_deps.bzl +++ b/examples/firebase_example/swift_deps.bzl @@ -4,7 +4,7 @@ def swift_dependencies(): # version: 0.20200225.4 swift_package( name = "swiftpkg_abseil_cpp_swiftpm", - commit = "fffc3c2729be5747390ad02d5100291a0d9ad26a", + commit = "583de9bd60f66b40e78d08599cc92036c2e7e4e1", dependencies_index = "@//:swift_deps_index.json", remote = "https://github.com/firebase/abseil-cpp-SwiftPM.git", ) @@ -12,7 +12,7 @@ def swift_dependencies(): # version: 0.7.2 swift_package( name = "swiftpkg_boringssl_swiftpm", - commit = "734a8247442fde37df4364c21f6a0085b6a36728", + commit = "dd3eda2b05a3f459fc3073695ad1b28659066eab", dependencies_index = "@//:swift_deps_index.json", remote = "https://github.com/firebase/boringssl-SwiftPM.git", ) @@ -20,7 +20,7 @@ def swift_dependencies(): # version: 8.9.1 swift_package( name = "swiftpkg_firebase_ios_sdk", - commit = "839cc6b0cd80b0b8bf81fe9bd82b743b25dc6446", + commit = "f567ed9a2b30e29159df258049a9c662c517688e", dependencies_index = "@//:swift_deps_index.json", remote = "https://github.com/firebase/firebase-ios-sdk", ) @@ -28,7 +28,7 @@ def swift_dependencies(): # version: 8.9.1 swift_package( name = "swiftpkg_googleappmeasurement", - commit = "9b2f6aca5b4685c45f9f5481f19bee8e7982c538", + commit = "9a09ece724128e8d1e14c5133b87c0e236844ac0", dependencies_index = "@//:swift_deps_index.json", remote = "https://github.com/google/GoogleAppMeasurement.git", ) @@ -49,18 +49,18 @@ def swift_dependencies(): remote = "https://github.com/google/GoogleUtilities.git", ) - # version: 1.28.4 + # version: 1.44.3-grpc swift_package( - name = "swiftpkg_grpc_swiftpm", - commit = "fb405dd2c7901485f7e158b24e3a0a47e4efd8b5", + name = "swiftpkg_grpc_ios", + commit = "8440b914756e0d26d4f4d054a1c1581daedfc5b6", dependencies_index = "@//:swift_deps_index.json", - remote = "https://github.com/firebase/grpc-SwiftPM.git", + remote = "https://github.com/grpc/grpc-ios.git", ) # version: 1.7.2 swift_package( name = "swiftpkg_gtm_session_fetcher", - commit = "4e9bbf2808b8fee444e84a48f5f3c12641987d3e", + commit = "96d7cc73a71ce950723aa3c50ce4fb275ae180b8", dependencies_index = "@//:swift_deps_index.json", remote = "https://github.com/google/gtm-session-fetcher.git", ) @@ -76,7 +76,7 @@ def swift_dependencies(): # version: 2.30908.0 swift_package( name = "swiftpkg_nanopb", - commit = "7ee9ef9f627d85cbe1b8c4f49a3ed26eed216c77", + commit = "819d0a2173aff699fb8c364b6fb906f7cdb1a692", dependencies_index = "@//:swift_deps_index.json", remote = "https://github.com/firebase/nanopb.git", ) diff --git a/examples/firebase_example/swift_deps_index.json b/examples/firebase_example/swift_deps_index.json index 864d43c43..974a7d1bb 100644 --- a/examples/firebase_example/swift_deps_index.json +++ b/examples/firebase_example/swift_deps_index.json @@ -48,7 +48,7 @@ "product_memberships": [ "FirebaseAnalytics", "FirebaseAnalyticsWithoutAdIdSupport", - "FirebaseAnalyticsSwift-Beta", + "FirebaseAnalyticsSwift", "FirebaseAuth", "FirebaseAppCheck", "FirebaseAppDistribution-Beta", @@ -58,10 +58,10 @@ "FirebaseStorageCombine-Community", "FirebaseCrashlytics", "FirebaseDatabase", - "FirebaseDatabaseSwift-Beta", + "FirebaseDatabaseSwift", "FirebaseDynamicLinks", "FirebaseFirestore", - "FirebaseFirestoreSwift-Beta", + "FirebaseFirestoreSwift", "FirebaseFunctions", "FirebaseInAppMessaging-Beta", "FirebaseInAppMessagingSwift-Beta", @@ -70,8 +70,8 @@ "FirebaseMLModelDownloader", "FirebasePerformance", "FirebaseRemoteConfig", - "FirebaseStorage", - "FirebaseStorageSwift-Beta" + "FirebaseRemoteConfigSwift", + "FirebaseStorage" ] }, { @@ -84,6 +84,14 @@ "FirebaseCrashlytics" ] }, + { + "name": "FirebaseCrashlyticsUnit", + "c99name": "FirebaseCrashlyticsUnit", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:Crashlytics_UnitTests_FirebaseCrashlyticsUnit", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, { "name": "FirebaseABTesting", "c99name": "FirebaseABTesting", @@ -94,7 +102,8 @@ "FirebaseInAppMessaging-Beta", "FirebaseInAppMessagingSwift-Beta", "FirebasePerformance", - "FirebaseRemoteConfig" + "FirebaseRemoteConfig", + "FirebaseRemoteConfigSwift" ] }, { @@ -105,6 +114,16 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [] }, + { + "name": "FirebaseAnalyticsOnDeviceConversionTarget", + "c99name": "FirebaseAnalyticsOnDeviceConversionTarget", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseAnalyticsOnDeviceConversionWrapper_FirebaseAnalyticsOnDeviceConversionTarget", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseAnalyticsOnDeviceConversion" + ] + }, { "name": "FirebaseAnalyticsSwift", "c99name": "FirebaseAnalyticsSwift", @@ -112,7 +131,7 @@ "label": "@swiftpkg_firebase_ios_sdk//:FirebaseAnalyticsSwift_Sources_FirebaseAnalyticsSwift", "package_identity": "firebase-ios-sdk", "product_memberships": [ - "FirebaseAnalyticsSwift-Beta" + "FirebaseAnalyticsSwift" ] }, { @@ -133,7 +152,20 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [ "FirebaseAnalytics", - "FirebaseAnalyticsSwift-Beta" + "FirebaseAnalyticsSwift" + ] + }, + { + "name": "FirebaseAppCheckInterop", + "c99name": "FirebaseAppCheckInterop", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseAppCheck_Interop_FirebaseAppCheckInterop", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseFunctionsCombine-Community", + "FirebaseStorageCombine-Community", + "FirebaseFunctions", + "FirebaseStorage" ] }, { @@ -180,6 +212,27 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [] }, + { + "name": "AppDistributionUnitSwift", + "c99name": "AppDistributionUnitSwift", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseAppDistribution_Tests_Unit_Swift_AppDistributionUnitSwift", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseAuthInterop", + "c99name": "FirebaseAuthInterop", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseAuth_Interop_FirebaseAuthInterop", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseFunctionsCombine-Community", + "FirebaseStorageCombine-Community", + "FirebaseFunctions", + "FirebaseStorage" + ] + }, { "name": "FirebaseAuth", "c99name": "FirebaseAuth", @@ -239,6 +292,64 @@ "FirebaseStorageCombine-Community" ] }, + { + "name": "FirebaseCoreExtension", + "c99name": "FirebaseCoreExtension", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseCore_Extension_FirebaseCoreExtension", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseFirestoreCombine-Community", + "FirebaseFunctionsCombine-Community", + "FirebaseStorageCombine-Community", + "FirebaseFirestoreSwift", + "FirebaseFunctions", + "FirebaseStorage" + ] + }, + { + "name": "FirebaseCoreInternal", + "c99name": "FirebaseCoreInternal", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseCore_Internal_Sources_FirebaseCoreInternal", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseAnalytics", + "FirebaseAnalyticsWithoutAdIdSupport", + "FirebaseAnalyticsSwift", + "FirebaseAuth", + "FirebaseAppCheck", + "FirebaseAppDistribution-Beta", + "FirebaseAuthCombine-Community", + "FirebaseFirestoreCombine-Community", + "FirebaseFunctionsCombine-Community", + "FirebaseStorageCombine-Community", + "FirebaseCrashlytics", + "FirebaseDatabase", + "FirebaseDatabaseSwift", + "FirebaseDynamicLinks", + "FirebaseFirestore", + "FirebaseFirestoreSwift", + "FirebaseFunctions", + "FirebaseInAppMessaging-Beta", + "FirebaseInAppMessagingSwift-Beta", + "FirebaseInstallations", + "FirebaseMessaging", + "FirebaseMLModelDownloader", + "FirebasePerformance", + "FirebaseRemoteConfig", + "FirebaseRemoteConfigSwift", + "FirebaseStorage" + ] + }, + { + "name": "FirebaseCoreInternalTests", + "c99name": "FirebaseCoreInternalTests", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseCore_Internal_Tests_FirebaseCoreInternalTests", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, { "name": "FirebaseCore", "c99name": "FirebaseCore", @@ -248,7 +359,7 @@ "product_memberships": [ "FirebaseAnalytics", "FirebaseAnalyticsWithoutAdIdSupport", - "FirebaseAnalyticsSwift-Beta", + "FirebaseAnalyticsSwift", "FirebaseAuth", "FirebaseAppCheck", "FirebaseAppDistribution-Beta", @@ -258,10 +369,10 @@ "FirebaseStorageCombine-Community", "FirebaseCrashlytics", "FirebaseDatabase", - "FirebaseDatabaseSwift-Beta", + "FirebaseDatabaseSwift", "FirebaseDynamicLinks", "FirebaseFirestore", - "FirebaseFirestoreSwift-Beta", + "FirebaseFirestoreSwift", "FirebaseFunctions", "FirebaseInAppMessaging-Beta", "FirebaseInAppMessagingSwift-Beta", @@ -270,8 +381,8 @@ "FirebaseMLModelDownloader", "FirebasePerformance", "FirebaseRemoteConfig", - "FirebaseStorage", - "FirebaseStorageSwift-Beta" + "FirebaseRemoteConfigSwift", + "FirebaseStorage" ] }, { @@ -289,7 +400,7 @@ "label": "@swiftpkg_firebase_ios_sdk//:FirebaseDatabaseSwift_Sources_FirebaseDatabaseSwift", "package_identity": "firebase-ios-sdk", "product_memberships": [ - "FirebaseDatabaseSwift-Beta" + "FirebaseDatabaseSwift" ] }, { @@ -308,7 +419,7 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [ "FirebaseDatabase", - "FirebaseDatabaseSwift-Beta" + "FirebaseDatabaseSwift" ] }, { @@ -337,6 +448,49 @@ "FirebaseDynamicLinks" ] }, + { + "name": "FirebaseFunctions", + "c99name": "FirebaseFunctions", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseFunctions_Sources_FirebaseFunctions", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseFunctionsCombine-Community", + "FirebaseFunctions" + ] + }, + { + "name": "FunctionsCombineUnit", + "c99name": "FunctionsCombineUnit", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseFunctions_Tests_CombineUnit_FunctionsCombineUnit", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseFunctionsIntegration", + "c99name": "FirebaseFunctionsIntegration", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseFunctions_Tests_Integration_FirebaseFunctionsIntegration", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseFunctionsObjCIntegration", + "c99name": "FirebaseFunctionsObjCIntegration", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseFunctions_Tests_ObjCIntegration_FirebaseFunctionsObjCIntegration", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseFunctionsUnit", + "c99name": "FirebaseFunctionsUnit", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseFunctions_Tests_Unit_FirebaseFunctionsUnit", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, { "name": "FirebaseInAppMessaging", "c99name": "FirebaseInAppMessaging", @@ -378,7 +532,7 @@ "product_memberships": [ "FirebaseAnalytics", "FirebaseAnalyticsWithoutAdIdSupport", - "FirebaseAnalyticsSwift-Beta", + "FirebaseAnalyticsSwift", "FirebaseAppDistribution-Beta", "FirebaseCrashlytics", "FirebaseInAppMessaging-Beta", @@ -387,7 +541,8 @@ "FirebaseMessaging", "FirebaseMLModelDownloader", "FirebasePerformance", - "FirebaseRemoteConfig" + "FirebaseRemoteConfig", + "FirebaseRemoteConfigSwift" ] }, { @@ -408,6 +563,17 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [] }, + { + "name": "FirebaseMessagingInterop", + "c99name": "FirebaseMessagingInterop", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseMessaging_Interop_FirebaseMessagingInterop", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseFunctionsCombine-Community", + "FirebaseFunctions" + ] + }, { "name": "FirebaseMessaging", "c99name": "FirebaseMessaging", @@ -444,6 +610,32 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [] }, + { + "name": "FirebaseRemoteConfigSwift", + "c99name": "FirebaseRemoteConfigSwift", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseRemoteConfigSwift_Sources_FirebaseRemoteConfigSwift", + "package_identity": "firebase-ios-sdk", + "product_memberships": [ + "FirebaseRemoteConfigSwift" + ] + }, + { + "name": "RemoteConfigFakeConsoleObjC", + "c99name": "RemoteConfigFakeConsoleObjC", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseRemoteConfigSwift_Tests_ObjC_RemoteConfigFakeConsoleObjC", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "RemoteConfigFakeConsole", + "c99name": "RemoteConfigFakeConsole", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseRemoteConfigSwift_Tests_RemoteConfigFakeConsole", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, { "name": "FirebaseRemoteConfig", "c99name": "FirebaseRemoteConfig", @@ -452,7 +644,8 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [ "FirebasePerformance", - "FirebaseRemoteConfig" + "FirebaseRemoteConfig", + "FirebaseRemoteConfigSwift" ] }, { @@ -464,33 +657,76 @@ "product_memberships": [] }, { - "name": "FirebaseStorageSwift", - "c99name": "FirebaseStorageSwift", + "name": "FirebaseSessionsObjC", + "c99name": "FirebaseSessionsObjC", + "src_type": "objc", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseSessions_FirebaseSessionsObjC", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseSessions", + "c99name": "FirebaseSessions", "src_type": "swift", - "label": "@swiftpkg_firebase_ios_sdk//:FirebaseStorageSwift_Sources_FirebaseStorageSwift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseSessions_Sources_FirebaseSessions", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseSessionsUnit", + "c99name": "FirebaseSessionsUnit", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseSessions_Tests_Unit_FirebaseSessionsUnit", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseSharedSwift", + "c99name": "FirebaseSharedSwift", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseSharedSwift_Sources_FirebaseSharedSwift", "package_identity": "firebase-ios-sdk", "product_memberships": [ - "FirebaseStorageCombine-Community", - "FirebaseStorageSwift-Beta" + "FirebaseFirestoreCombine-Community", + "FirebaseFunctionsCombine-Community", + "FirebaseDatabaseSwift", + "FirebaseFirestoreSwift", + "FirebaseFunctions", + "FirebaseRemoteConfigSwift" ] }, + { + "name": "FirebaseSharedSwiftTests", + "c99name": "FirebaseSharedSwiftTests", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseSharedSwift_Tests_FirebaseSharedSwiftTests", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, { "name": "FirebaseStorage", "c99name": "FirebaseStorage", - "src_type": "objc", + "src_type": "swift", "label": "@swiftpkg_firebase_ios_sdk//:FirebaseStorage_Sources_FirebaseStorage", "package_identity": "firebase-ios-sdk", "product_memberships": [ "FirebaseStorageCombine-Community", - "FirebaseStorage", - "FirebaseStorageSwift-Beta" + "FirebaseStorage" ] }, { - "name": "StorageUnit", - "c99name": "StorageUnit", + "name": "StorageObjCIntegration", + "c99name": "StorageObjCIntegration", "src_type": "objc", - "label": "@swiftpkg_firebase_ios_sdk//:FirebaseStorage_Tests_Unit_StorageUnit", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseStorage_Tests_ObjCIntegration_StorageObjCIntegration", + "package_identity": "firebase-ios-sdk", + "product_memberships": [] + }, + { + "name": "FirebaseStorageUnit", + "c99name": "FirebaseStorageUnit", + "src_type": "swift", + "label": "@swiftpkg_firebase_ios_sdk//:FirebaseStorage_Tests_Unit_FirebaseStorageUnit", "package_identity": "firebase-ios-sdk", "product_memberships": [] }, @@ -510,49 +746,6 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [] }, - { - "name": "FirebaseFunctionsTestingSupport", - "c99name": "FirebaseFunctionsTestingSupport", - "src_type": "objc", - "label": "@swiftpkg_firebase_ios_sdk//:FirebaseTestingSupport_Functions_Sources_FirebaseFunctionsTestingSupport", - "package_identity": "firebase-ios-sdk", - "product_memberships": [] - }, - { - "name": "FirebaseCoreDiagnostics", - "c99name": "FirebaseCoreDiagnostics", - "src_type": "objc", - "label": "@swiftpkg_firebase_ios_sdk//:Firebase_CoreDiagnostics_FIRCDLibrary_FirebaseCoreDiagnostics", - "package_identity": "firebase-ios-sdk", - "product_memberships": [ - "FirebaseAnalytics", - "FirebaseAnalyticsWithoutAdIdSupport", - "FirebaseAnalyticsSwift-Beta", - "FirebaseAuth", - "FirebaseAppCheck", - "FirebaseAppDistribution-Beta", - "FirebaseAuthCombine-Community", - "FirebaseFirestoreCombine-Community", - "FirebaseFunctionsCombine-Community", - "FirebaseStorageCombine-Community", - "FirebaseCrashlytics", - "FirebaseDatabase", - "FirebaseDatabaseSwift-Beta", - "FirebaseDynamicLinks", - "FirebaseFirestore", - "FirebaseFirestoreSwift-Beta", - "FirebaseFunctions", - "FirebaseInAppMessaging-Beta", - "FirebaseInAppMessagingSwift-Beta", - "FirebaseInstallations", - "FirebaseMessaging", - "FirebaseMLModelDownloader", - "FirebasePerformance", - "FirebaseRemoteConfig", - "FirebaseStorage", - "FirebaseStorageSwift-Beta" - ] - }, { "name": "FirebaseFirestore", "c99name": "FirebaseFirestore", @@ -562,7 +755,7 @@ "product_memberships": [ "FirebaseFirestoreCombine-Community", "FirebaseFirestore", - "FirebaseFirestoreSwift-Beta" + "FirebaseFirestoreSwift" ] }, { @@ -573,41 +766,14 @@ "package_identity": "firebase-ios-sdk", "product_memberships": [ "FirebaseFirestoreCombine-Community", - "FirebaseFirestoreSwift-Beta" + "FirebaseFirestoreSwift" ] }, { - "name": "FunctionsUnit", - "c99name": "FunctionsUnit", - "src_type": "objc", - "label": "@swiftpkg_firebase_ios_sdk//:Functions_Example_Tests_FunctionsUnit", - "package_identity": "firebase-ios-sdk", - "product_memberships": [] - }, - { - "name": "FirebaseFunctions", - "c99name": "FirebaseFunctions", - "src_type": "objc", - "label": "@swiftpkg_firebase_ios_sdk//:Functions_FirebaseFunctions", - "package_identity": "firebase-ios-sdk", - "product_memberships": [ - "FirebaseFunctionsCombine-Community", - "FirebaseFunctions" - ] - }, - { - "name": "FunctionsCombineUnit", - "c99name": "FunctionsCombineUnit", - "src_type": "swift", - "label": "@swiftpkg_firebase_ios_sdk//:Functions_Tests_CombineUnit_FunctionsCombineUnit", - "package_identity": "firebase-ios-sdk", - "product_memberships": [] - }, - { - "name": "FunctionsUnitSwift", - "c99name": "FunctionsUnitSwift", + "name": "HeartbeatLoggingTestUtils", + "c99name": "HeartbeatLoggingTestUtils", "src_type": "swift", - "label": "@swiftpkg_firebase_ios_sdk//:Functions_Tests_Unit_Swift_FunctionsUnitSwift", + "label": "@swiftpkg_firebase_ios_sdk//:HeartbeatLoggingTestUtils_Sources_HeartbeatLoggingTestUtils", "package_identity": "firebase-ios-sdk", "product_memberships": [] }, @@ -626,7 +792,7 @@ "label": "@swiftpkg_firebase_ios_sdk//:SwiftPM-PlatformExclude_FirebaseAnalyticsSwiftWrap_FirebaseAnalyticsSwiftTarget", "package_identity": "firebase-ios-sdk", "product_memberships": [ - "FirebaseAnalyticsSwift-Beta" + "FirebaseAnalyticsSwift" ] }, { @@ -676,7 +842,7 @@ "label": "@swiftpkg_firebase_ios_sdk//:SwiftPM-PlatformExclude_FirebaseFirestoreSwiftWrap_FirebaseFirestoreSwiftTarget", "package_identity": "firebase-ios-sdk", "product_memberships": [ - "FirebaseFirestoreSwift-Beta" + "FirebaseFirestoreSwift" ] }, { @@ -750,7 +916,17 @@ "product_memberships": [ "FirebaseAnalytics", "FirebaseAnalyticsWithoutAdIdSupport", - "FirebaseAnalyticsSwift-Beta" + "FirebaseAnalyticsSwift" + ] + }, + { + "name": "GoogleAppMeasurementOnDeviceConversionTarget", + "c99name": "GoogleAppMeasurementOnDeviceConversionTarget", + "src_type": "objc", + "label": "@swiftpkg_googleappmeasurement//:GoogleAppMeasurementOnDeviceConversionWrapper_GoogleAppMeasurementOnDeviceConversionTarget", + "package_identity": "googleappmeasurement", + "product_memberships": [ + "GoogleAppMeasurementOnDeviceConversion" ] }, { @@ -794,6 +970,16 @@ "GoogleAppMeasurement" ] }, + { + "name": "GoogleAppMeasurementOnDeviceConversion", + "c99name": "GoogleAppMeasurementOnDeviceConversion", + "src_type": "binary", + "label": "@swiftpkg_googleappmeasurement//:remote_archive_GoogleAppMeasurementOnDeviceConversion.zip_GoogleAppMeasurementOnDeviceConversion", + "package_identity": "googleappmeasurement", + "product_memberships": [ + "GoogleAppMeasurementOnDeviceConversion" + ] + }, { "name": "GoogleDataTransport", "c99name": "GoogleDataTransport", @@ -965,20 +1151,12 @@ "package_identity": "googleutilities", "product_memberships": [] }, - { - "name": "build-test", - "c99name": "build_test", - "src_type": "clang", - "label": "@swiftpkg_grpc_swiftpm//:SwiftPMTests_build-test", - "package_identity": "grpc-swiftpm", - "product_memberships": [] - }, { "name": "gRPC-Core", "c99name": "gRPC_Core", "src_type": "clang", - "label": "@swiftpkg_grpc_swiftpm//:gRPC-Core", - "package_identity": "grpc-swiftpm", + "label": "@swiftpkg_grpc_ios//:native_src_gRPC-Core", + "package_identity": "grpc-ios", "product_memberships": [ "gRPC-Core", "gRPC-cpp" @@ -988,17 +1166,25 @@ "name": "gRPC-cpp", "c99name": "gRPC_cpp", "src_type": "clang", - "label": "@swiftpkg_grpc_swiftpm//:gRPC-cpp", - "package_identity": "grpc-swiftpm", + "label": "@swiftpkg_grpc_ios//:native_src_gRPC-cpp", + "package_identity": "grpc-ios", "product_memberships": [ "gRPC-cpp" ] }, + { + "name": "build-test", + "c99name": "build_test", + "src_type": "clang", + "label": "@swiftpkg_grpc_ios//:native_src_test_spm_build_build-test", + "package_identity": "grpc-ios", + "product_memberships": [] + }, { "name": "GTMSessionFetcherCore", "c99name": "GTMSessionFetcherCore", "src_type": "objc", - "label": "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherCore", + "label": "@swiftpkg_gtm_session_fetcher//:Sources_Core_GTMSessionFetcherCore", "package_identity": "gtm-session-fetcher", "product_memberships": [ "GTMSessionFetcher", @@ -1011,7 +1197,7 @@ "name": "GTMSessionFetcherFull", "c99name": "GTMSessionFetcherFull", "src_type": "objc", - "label": "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherFull", + "label": "@swiftpkg_gtm_session_fetcher//:Sources_Full_GTMSessionFetcherFull", "package_identity": "gtm-session-fetcher", "product_memberships": [ "GTMSessionFetcher", @@ -1022,17 +1208,33 @@ "name": "GTMSessionFetcherLogView", "c99name": "GTMSessionFetcherLogView", "src_type": "objc", - "label": "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherLogView", + "label": "@swiftpkg_gtm_session_fetcher//:Sources_LogView_GTMSessionFetcherLogView", "package_identity": "gtm-session-fetcher", "product_memberships": [ "GTMSessionFetcherLogView" ] }, + { + "name": "objc-import-test", + "c99name": "objc_import_test", + "src_type": "objc", + "label": "@swiftpkg_gtm_session_fetcher//:SwiftPMTests_ObjCImportTest_objc-import-test", + "package_identity": "gtm-session-fetcher", + "product_memberships": [] + }, + { + "name": "swift-test", + "c99name": "swift_test", + "src_type": "swift", + "label": "@swiftpkg_gtm_session_fetcher//:SwiftPMTests_SwiftImportTest_swift-test", + "package_identity": "gtm-session-fetcher", + "product_memberships": [] + }, { "name": "GTMSessionFetcherCoreTests", "c99name": "GTMSessionFetcherCoreTests", "src_type": "objc", - "label": "@swiftpkg_gtm_session_fetcher//:Source_UnitTests_GTMSessionFetcherCoreTests", + "label": "@swiftpkg_gtm_session_fetcher//:UnitTests_GTMSessionFetcherCoreTests", "package_identity": "gtm-session-fetcher", "product_memberships": [] }, @@ -1265,7 +1467,15 @@ }, { "identity": "firebase-ios-sdk", - "name": "FirebaseAnalyticsSwift-Beta", + "name": "FirebaseAnalyticsOnDeviceConversion", + "type": "library", + "target_labels": [ + "@swiftpkg_firebase_ios_sdk//:FirebaseAnalyticsOnDeviceConversionWrapper_FirebaseAnalyticsOnDeviceConversionTarget" + ] + }, + { + "identity": "firebase-ios-sdk", + "name": "FirebaseAnalyticsSwift", "type": "library", "target_labels": [ "@swiftpkg_firebase_ios_sdk//:SwiftPM-PlatformExclude_FirebaseAnalyticsSwiftWrap_FirebaseAnalyticsSwiftTarget" @@ -1329,7 +1539,7 @@ }, { "identity": "firebase-ios-sdk", - "name": "FirebaseDatabaseSwift-Beta", + "name": "FirebaseDatabaseSwift", "type": "library", "target_labels": [ "@swiftpkg_firebase_ios_sdk//:FirebaseDatabaseSwift_Sources_FirebaseDatabaseSwift" @@ -1361,7 +1571,7 @@ }, { "identity": "firebase-ios-sdk", - "name": "FirebaseFirestoreSwift-Beta", + "name": "FirebaseFirestoreSwift", "type": "library", "target_labels": [ "@swiftpkg_firebase_ios_sdk//:SwiftPM-PlatformExclude_FirebaseFirestoreSwiftWrap_FirebaseFirestoreSwiftTarget" @@ -1372,7 +1582,7 @@ "name": "FirebaseFunctions", "type": "library", "target_labels": [ - "@swiftpkg_firebase_ios_sdk//:Functions_FirebaseFunctions" + "@swiftpkg_firebase_ios_sdk//:FirebaseFunctions_Sources_FirebaseFunctions" ] }, { @@ -1439,6 +1649,14 @@ "@swiftpkg_firebase_ios_sdk//:FirebaseRemoteConfig_Sources_FirebaseRemoteConfig" ] }, + { + "identity": "firebase-ios-sdk", + "name": "FirebaseRemoteConfigSwift", + "type": "library", + "target_labels": [ + "@swiftpkg_firebase_ios_sdk//:FirebaseRemoteConfigSwift_Sources_FirebaseRemoteConfigSwift" + ] + }, { "identity": "firebase-ios-sdk", "name": "FirebaseStorage", @@ -1456,19 +1674,19 @@ ] }, { - "identity": "firebase-ios-sdk", - "name": "FirebaseStorageSwift-Beta", + "identity": "googleappmeasurement", + "name": "GoogleAppMeasurement", "type": "library", "target_labels": [ - "@swiftpkg_firebase_ios_sdk//:FirebaseStorageSwift_Sources_FirebaseStorageSwift" + "@swiftpkg_googleappmeasurement//:GoogleAppMeasurementWrapper_GoogleAppMeasurementTarget" ] }, { "identity": "googleappmeasurement", - "name": "GoogleAppMeasurement", + "name": "GoogleAppMeasurementOnDeviceConversion", "type": "library", "target_labels": [ - "@swiftpkg_googleappmeasurement//:GoogleAppMeasurementWrapper_GoogleAppMeasurementTarget" + "@swiftpkg_googleappmeasurement//:GoogleAppMeasurementOnDeviceConversionWrapper_GoogleAppMeasurementOnDeviceConversionTarget" ] }, { @@ -1568,19 +1786,19 @@ ] }, { - "identity": "grpc-swiftpm", + "identity": "grpc-ios", "name": "gRPC-Core", "type": "library", "target_labels": [ - "@swiftpkg_grpc_swiftpm//:gRPC-Core" + "@swiftpkg_grpc_ios//:native_src_gRPC-Core" ] }, { - "identity": "grpc-swiftpm", + "identity": "grpc-ios", "name": "gRPC-cpp", "type": "library", "target_labels": [ - "@swiftpkg_grpc_swiftpm//:gRPC-cpp" + "@swiftpkg_grpc_ios//:native_src_gRPC-cpp" ] }, { @@ -1588,8 +1806,8 @@ "name": "GTMSessionFetcher", "type": "library", "target_labels": [ - "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherCore", - "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherFull" + "@swiftpkg_gtm_session_fetcher//:Sources_Core_GTMSessionFetcherCore", + "@swiftpkg_gtm_session_fetcher//:Sources_Full_GTMSessionFetcherFull" ] }, { @@ -1597,7 +1815,7 @@ "name": "GTMSessionFetcherCore", "type": "library", "target_labels": [ - "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherCore" + "@swiftpkg_gtm_session_fetcher//:Sources_Core_GTMSessionFetcherCore" ] }, { @@ -1605,7 +1823,7 @@ "name": "GTMSessionFetcherFull", "type": "library", "target_labels": [ - "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherFull" + "@swiftpkg_gtm_session_fetcher//:Sources_Full_GTMSessionFetcherFull" ] }, { @@ -1613,7 +1831,7 @@ "name": "GTMSessionFetcherLogView", "type": "library", "target_labels": [ - "@swiftpkg_gtm_session_fetcher//:Source_GTMSessionFetcherLogView" + "@swiftpkg_gtm_session_fetcher//:Sources_LogView_GTMSessionFetcherLogView" ] }, { diff --git a/gazelle/internal/swift/builtin_modules.go b/gazelle/internal/swift/builtin_modules.go index 367ca425f..dadc70da8 100644 --- a/gazelle/internal/swift/builtin_modules.go +++ b/gazelle/internal/swift/builtin_modules.go @@ -235,69 +235,370 @@ var macosFrameworks = mapset.NewSet[string]( var iosFrameworks = mapset.NewSet[string]( "ARKit", + "AVFAudio", + "AVFoundation", "AVKit", + "AVRouting", + "Accelerate", + "Accessibility", + "Accounts", + "ActivityKit", + "AdServices", + "AdSupport", "AddressBook", "AddressBookUI", "AppClip", + "AppIntents", + "AppTrackingTransparency", "AssetsLibrary", + "AudioToolbox", + "AudioUnit", "AuthenticationServices", + "AutomatedDeviceEnrollment", + "AutomaticAssessmentConfiguration", + "BackgroundAssets", + "BackgroundTasks", "BusinessChat", + "CFNetwork", + "CallKit", + "CarKey", "CarPlay", "Charts", + "ClassKit", "ClockKit", + "CloudKit", + "ColorSync", + "Combine", + "Contacts", "ContactsUI", + "CoreAudio", "CoreAudioKit", + "CoreAudioTypes", + "CoreBluetooth", + "CoreData", + "CoreFoundation", + "CoreGraphics", + "CoreHaptics", + "CoreImage", + "CoreLocation", "CoreLocationUI", + "CoreMIDI", + "CoreML", + "CoreMedia", + "CoreMotion", "CoreNFC", + "CoreServices", + "CoreSpotlight", + "CoreTelephony", + "CoreText", + "CoreTransferable", + "CoreVideo", + "CreateML", + "CreateMLComponents", + "CryptoKit", + "CryptoTokenKit", + "DataDetection", + "DeveloperToolsSupport", "DeviceActivity", + "DeviceCheck", + "DeviceDiscoveryExtension", + "EventKit", "EventKitUI", + "ExposureNotification", + "ExtensionFoundation", "ExtensionKit", + "ExternalAccessory", "FamilyControls", + "FileProvider", + "FileProviderUI", + "Foundation", + "GLKit", + "GSS", "GameController", "GameKit", "GameplayKit", "GroupActivities", + "HealthKit", "HealthKitUI", "HomeKit", + "IOKit", + "IOSurface", + "IdentityLookup", "IdentityLookupUI", + "ImageCaptureCore", + "ImageIO", + "Intents", "IntentsUI", "JavaScriptCore", "LinkPresentation", + "LocalAuthentication", + "LocalAuthenticationEmbeddedUI", + "MLCompute", + "ManagedSettings", "ManagedSettingsUI", "MapKit", + "Matter", + "MatterSupport", + "MediaAccessibility", "MediaPlayer", "MediaSetup", + "MediaToolbox", "MessageUI", "Messages", + "Metal", + "MetalFX", "MetalKit", + "MetalPerformanceShaders", + "MetalPerformanceShadersGraph", + "MetricKit", "MobileCoreServices", + "ModelIO", "MultipeerConnectivity", "MusicKit", - "NetworkExtensioniOSSupport", + "NaturalLanguage", + "NearbyInteraction", + "Network", + "NetworkExtension", + "NewsstandKit", + "NotificationCenter", + "OSLog", "OpenAL", + "OpenGLES", "PDFKit", + "PHASE", "PassKit", "PencilKit", + "Photos", "PhotosUI", + "ProximityReader", + "PushKit", + "PushToTalk", + "QuartzCore", "QuickLook", + "QuickLookThumbnailing", "RealityFoundation", "RealityKit", "ReplayKit", "RoomPlan", "SafariServices", + "SafetyKit", "SceneKit", "ScreenTime", + "Security", + "SensorKit", "SharedWithYou", + "SharedWithYouCore", + "ShazamKit", "Social", + "SoundAnalysis", + "Speech", "SpriteKit", "StoreKit", "SwiftUI", + "SystemConfiguration", + "TabularData", + "ThreadNetwork", "Twitter", "UIKit", + "UniformTypeIdentifiers", + "UserNotifications", "UserNotificationsUI", + "VideoSubscriberAccount", + "VideoToolbox", + "Vision", "VisionKit", "WatchConnectivity", + "WeatherKit", "WebKit", "WidgetKit", "iAd", ) + +var tvosFrameworks = mapset.NewSet[string]( + "AVFAudio", + "AVFoundation", + "AVKit", + "Accelerate", + "Accessibility", + "AdSupport", + "AppIntents", + "AppTrackingTransparency", + "AudioToolbox", + "AudioUnit", + "AuthenticationServices", + "BackgroundTasks", + "CFNetwork", + "Charts", + "CloudKit", + "ColorSync", + "Combine", + "CoreAudio", + "CoreAudioTypes", + "CoreBluetooth", + "CoreData", + "CoreFoundation", + "CoreGraphics", + "CoreHaptics", + "CoreImage", + "CoreLocation", + "CoreMIDI", + "CoreML", + "CoreMedia", + "CoreServices", + "CoreSpotlight", + "CoreText", + "CoreTransferable", + "CoreVideo", + "CreateML", + "CreateMLComponents", + "CryptoKit", + "CryptoTokenKit", + "DataDetection", + "DeveloperToolsSupport", + "DeviceCheck", + "DeviceDiscoveryUI", + "ExposureNotification", + "ExtensionFoundation", + "ExtensionKit", + "ExternalAccessory", + "Foundation", + "GLKit", + "GameController", + "GameKit", + "GameplayKit", + "GroupActivities", + "HomeKit", + "IOSurface", + "ImageIO", + "Intents", + "IntentsUI", + "JavaScriptCore", + "LinkPresentation", + "MLCompute", + "MapKit", + "Matter", + "MediaAccessibility", + "MediaPlayer", + "MediaToolbox", + "Metal", + "MetalKit", + "MetalPerformanceShaders", + "MetalPerformanceShadersGraph", + "MetricKit", + "MobileCoreServices", + "ModelIO", + "MultipeerConnectivity", + "MusicKit", + "NaturalLanguage", + "Network", + "OSLog", + "OpenAL", + "OpenGLES", + "PHASE", + "Photos", + "PhotosUI", + "QuartzCore", + "ReplayKit", + "SceneKit", + "Security", + "SharedWithYou", + "SharedWithYouCore", + "ShazamKit", + "SoundAnalysis", + "SpriteKit", + "StoreKit", + "SwiftUI", + "SystemConfiguration", + "TVMLKit", + "TVServices", + "TVUIKit", + "TabularData", + "UIKit", + "UniformTypeIdentifiers", + "UserNotifications", + "UserNotificationsUI", + "VideoSubscriberAccount", + "VideoToolbox", + "Vision", + "WeatherKit", +) + +var watchosFrameworks = mapset.NewSet[string]( + "AVFAudio", + "AVFoundation", + "AVKit", + "Accelerate", + "Accessibility", + "AppIntents", + "AuthenticationServices", + "CFNetwork", + "CallKit", + "CarKey", + "Charts", + "ClockKit", + "CloudKit", + "ColorSync", + "Combine", + "Contacts", + "CoreAudio", + "CoreAudioTypes", + "CoreBluetooth", + "CoreData", + "CoreFoundation", + "CoreGraphics", + "CoreLocation", + "CoreLocationUI", + "CoreMIDI", + "CoreML", + "CoreMedia", + "CoreMotion", + "CoreServices", + "CoreText", + "CoreTransferable", + "CoreVideo", + "CryptoKit", + "CryptoTokenKit", + "DataDetection", + "DeveloperToolsSupport", + "DeviceCheck", + "EventKit", + "ExtensionFoundation", + "ExtensionKit", + "Foundation", + "GameKit", + "HealthKit", + "HomeKit", + "ImageIO", + "Intents", + "LocalAuthentication", + "MapKit", + "Matter", + "MediaPlayer", + "MobileCoreServices", + "MusicKit", + "NaturalLanguage", + "NearbyInteraction", + "Network", + "NetworkExtension", + "OSLog", + "PassKit", + "PhotosUI", + "PushKit", + "SafetyKit", + "SceneKit", + "Security", + "ShazamKit", + "SoundAnalysis", + "SpriteKit", + "StoreKit", + "SwiftUI", + "TabularData", + "UIKit", + "UniformTypeIdentifiers", + "UserNotifications", + "UserNotificationsUI", + "WatchConnectivity", + "WatchKit", + "WeatherKit", + "WidgetKit", +) diff --git a/gazelle/internal/swift/is_builtin_module.go b/gazelle/internal/swift/is_builtin_module.go index 239a1d699..b933815f4 100644 --- a/gazelle/internal/swift/is_builtin_module.go +++ b/gazelle/internal/swift/is_builtin_module.go @@ -7,7 +7,22 @@ var otherBuiltinModules = mapset.NewSet[string]( ) // The list of frameworks is found in builtin_modules.go. -var allBuiltInModules = otherBuiltinModules.Union(macosFrameworks.Union(iosFrameworks)) +var allBuiltInModuleSets = []mapset.Set[string]{ + otherBuiltinModules, + macosFrameworks, + iosFrameworks, + tvosFrameworks, + watchosFrameworks, +} + +var allBuiltInModules mapset.Set[string] + +func init() { + allBuiltInModules = mapset.NewSet[string]() + for _, mset := range allBuiltInModuleSets { + allBuiltInModules = allBuiltInModules.Union(mset) + } +} // IsBuiltInModule determines if the module is built into the Swift standard library. func IsBuiltInModule(name string) bool { diff --git a/gazelle/internal/swift/is_builtin_module_test.go b/gazelle/internal/swift/is_builtin_module_test.go index ceef85ec3..84257e9e3 100644 --- a/gazelle/internal/swift/is_builtin_module_test.go +++ b/gazelle/internal/swift/is_builtin_module_test.go @@ -15,6 +15,9 @@ func TestIsBuiltInModule(t *testing.T) { }{ {msg: "AppKit", name: "AppKit", exp: true}, {msg: "UIKit", name: "UIKit", exp: true}, + // XCTest is unusual in that it does not appear in any of the framework lists, but it is + // there. + {msg: "XCTest", name: "XCTest", exp: true}, {msg: "does not exist", name: "DoesNotExist", exp: false}, } for _, tt := range tests { diff --git a/swiftpkg/internal/BUILD.bazel b/swiftpkg/internal/BUILD.bazel index ee96f6c03..119a2b349 100644 --- a/swiftpkg/internal/BUILD.bazel +++ b/swiftpkg/internal/BUILD.bazel @@ -232,6 +232,37 @@ bzl_library( deps = [":module_maps"], ) +bzl_library( + name = "apple_builtin_frameworks", + srcs = ["apple_builtin_frameworks.bzl"], + visibility = ["//swiftpkg:__subpackages__"], + deps = ["@bazel_skylib//lib:sets"], +) + +bzl_library( + name = "objc_files", + srcs = ["objc_files.bzl"], + visibility = ["//swiftpkg:__subpackages__"], + deps = [ + ":apple_builtin_frameworks", + "@bazel_skylib//lib:sets", + ], +) + +bzl_library( + name = "bazel_apple_platforms", + srcs = ["bazel_apple_platforms.bzl"], + visibility = ["//swiftpkg:__subpackages__"], + deps = [":apple_builtin_frameworks"], +) + +bzl_library( + name = "swift_files", + srcs = ["swift_files.bzl"], + visibility = ["//swiftpkg:__subpackages__"], + deps = ["@bazel_skylib//lib:paths"], +) + bzl_library( name = "bazel_repo_names", srcs = ["bazel_repo_names.bzl"], diff --git a/swiftpkg/internal/apple_builtin_frameworks.bzl b/swiftpkg/internal/apple_builtin_frameworks.bzl new file mode 100644 index 000000000..9d0147174 --- /dev/null +++ b/swiftpkg/internal/apple_builtin_frameworks.bzl @@ -0,0 +1,614 @@ +"""Module listing built-in Frameworks.""" + +load("@bazel_skylib//lib:sets.bzl", "sets") + +# NOTE: This file is generated by running the following: +# bazel run //tools/generate_builtin_frameworks +# +# SDK Version: 13.1 +# SDK Build Version: 22C55 + +_macos = sets.make([ + "AGL", + "AVFAudio", + "AVFoundation", + "AVKit", + "AVRouting", + "Accelerate", + "Accessibility", + "Accounts", + "AdServices", + "AdSupport", + "AddressBook", + "AppIntents", + "AppKit", + "AppTrackingTransparency", + "AppleScriptKit", + "AppleScriptObjC", + "ApplicationServices", + "AudioToolbox", + "AudioUnit", + "AudioVideoBridging", + "AuthenticationServices", + "AutomaticAssessmentConfiguration", + "Automator", + "BackgroundAssets", + "BackgroundTasks", + "BusinessChat", + "CFNetwork", + "CalendarStore", + "CallKit", + "Carbon", + "Charts", + "ClassKit", + "CloudKit", + "Cocoa", + "Collaboration", + "ColorSync", + "Combine", + "Contacts", + "ContactsUI", + "CoreAudio", + "CoreAudioKit", + "CoreAudioTypes", + "CoreBluetooth", + "CoreData", + "CoreDisplay", + "CoreFoundation", + "CoreGraphics", + "CoreHaptics", + "CoreImage", + "CoreLocation", + "CoreMIDI", + "CoreMIDIServer", + "CoreML", + "CoreMedia", + "CoreMediaIO", + "CoreMotion", + "CoreServices", + "CoreSpotlight", + "CoreTelephony", + "CoreText", + "CoreTransferable", + "CoreVideo", + "CoreWLAN", + "CreateML", + "CreateMLComponents", + "CryptoKit", + "CryptoTokenKit", + "DVDPlayback", + "DataDetection", + "DeveloperToolsSupport", + "DeviceActivity", + "DeviceCheck", + "DirectoryService", + "DiscRecording", + "DiscRecordingUI", + "DiskArbitration", + "DriverKit", + "EventKit", + "ExceptionHandling", + "ExecutionPolicy", + "ExposureNotification", + "ExtensionFoundation", + "ExtensionKit", + "ExternalAccessory", + "FamilyControls", + "FileProvider", + "FileProviderUI", + "FinderSync", + "ForceFeedback", + "Foundation", + "GLKit", + "GLUT", + "GSS", + "GameController", + "GameKit", + "GameplayKit", + "GroupActivities", + "HealthKit", + "Hypervisor", + "ICADevices", + "IMServicePlugIn", + "IOBluetooth", + "IOBluetoothUI", + "IOKit", + "IOSurface", + "IOUSBHost", + "IdentityLookup", + "ImageCaptureCore", + "ImageIO", + "InputMethodKit", + "InstallerPlugins", + "InstantMessage", + "Intents", + "IntentsUI", + "JavaNativeFoundation", + "JavaRuntimeSupport", + "JavaScriptCore", + "Kerberos", + "Kernel", + "KernelManagement", + "LDAP", + "LatentSemanticMapping", + "LinkPresentation", + "LocalAuthentication", + "LocalAuthenticationEmbeddedUI", + "MLCompute", + "MailKit", + "ManagedSettings", + "MapKit", + "Matter", + "MediaAccessibility", + "MediaLibrary", + "MediaPlayer", + "MediaToolbox", + "Message", + "Metal", + "MetalFX", + "MetalKit", + "MetalPerformanceShaders", + "MetalPerformanceShadersGraph", + "MetricKit", + "ModelIO", + "MultipeerConnectivity", + "MusicKit", + "NaturalLanguage", + "NearbyInteraction", + "NetFS", + "Network", + "NetworkExtension", + "NotificationCenter", + "OSAKit", + "OSLog", + "OpenAL", + "OpenCL", + "OpenDirectory", + "OpenGL", + "PCSC", + "PDFKit", + "PHASE", + "ParavirtualizedGraphics", + "PassKit", + "PencilKit", + "Photos", + "PhotosUI", + "PreferencePanes", + "PushKit", + "PushToTalk", + "QTKit", + "Quartz", + "QuartzCore", + "QuickLook", + "QuickLookThumbnailing", + "QuickLookUI", + "RealityFoundation", + "RealityKit", + "ReplayKit", + "Ruby", + "SafariServices", + "SafetyKit", + "SceneKit", + "ScreenCaptureKit", + "ScreenSaver", + "ScreenTime", + "ScriptingBridge", + "Security", + "SecurityFoundation", + "SecurityInterface", + "SensorKit", + "ServiceManagement", + "SharedWithYou", + "SharedWithYouCore", + "ShazamKit", + "Social", + "SoundAnalysis", + "Speech", + "SpriteKit", + "StoreKit", + "SwiftUI", + "SyncServices", + "System", + "SystemConfiguration", + "SystemExtensions", + "TWAIN", + "TabularData", + "Tcl", + "ThreadNetwork", + "Tk", + "UniformTypeIdentifiers", + "UserNotifications", + "UserNotificationsUI", + "VideoDecodeAcceleration", + "VideoSubscriberAccount", + "VideoToolbox", + "Virtualization", + "Vision", + "VisionKit", + "WeatherKit", + "WebKit", + "WidgetKit", + "iTunesLibrary", + "vecLib", + "vmnet", +]) + +_ios = sets.make([ + "ARKit", + "AVFAudio", + "AVFoundation", + "AVKit", + "AVRouting", + "Accelerate", + "Accessibility", + "Accounts", + "ActivityKit", + "AdServices", + "AdSupport", + "AddressBook", + "AddressBookUI", + "AppClip", + "AppIntents", + "AppTrackingTransparency", + "AssetsLibrary", + "AudioToolbox", + "AudioUnit", + "AuthenticationServices", + "AutomatedDeviceEnrollment", + "AutomaticAssessmentConfiguration", + "BackgroundAssets", + "BackgroundTasks", + "BusinessChat", + "CFNetwork", + "CallKit", + "CarKey", + "CarPlay", + "Charts", + "ClassKit", + "ClockKit", + "CloudKit", + "ColorSync", + "Combine", + "Contacts", + "ContactsUI", + "CoreAudio", + "CoreAudioKit", + "CoreAudioTypes", + "CoreBluetooth", + "CoreData", + "CoreFoundation", + "CoreGraphics", + "CoreHaptics", + "CoreImage", + "CoreLocation", + "CoreLocationUI", + "CoreMIDI", + "CoreML", + "CoreMedia", + "CoreMotion", + "CoreNFC", + "CoreServices", + "CoreSpotlight", + "CoreTelephony", + "CoreText", + "CoreTransferable", + "CoreVideo", + "CreateML", + "CreateMLComponents", + "CryptoKit", + "CryptoTokenKit", + "DataDetection", + "DeveloperToolsSupport", + "DeviceActivity", + "DeviceCheck", + "DeviceDiscoveryExtension", + "EventKit", + "EventKitUI", + "ExposureNotification", + "ExtensionFoundation", + "ExtensionKit", + "ExternalAccessory", + "FamilyControls", + "FileProvider", + "FileProviderUI", + "Foundation", + "GLKit", + "GSS", + "GameController", + "GameKit", + "GameplayKit", + "GroupActivities", + "HealthKit", + "HealthKitUI", + "HomeKit", + "IOKit", + "IOSurface", + "IdentityLookup", + "IdentityLookupUI", + "ImageCaptureCore", + "ImageIO", + "Intents", + "IntentsUI", + "JavaScriptCore", + "LinkPresentation", + "LocalAuthentication", + "LocalAuthenticationEmbeddedUI", + "MLCompute", + "ManagedSettings", + "ManagedSettingsUI", + "MapKit", + "Matter", + "MatterSupport", + "MediaAccessibility", + "MediaPlayer", + "MediaSetup", + "MediaToolbox", + "MessageUI", + "Messages", + "Metal", + "MetalFX", + "MetalKit", + "MetalPerformanceShaders", + "MetalPerformanceShadersGraph", + "MetricKit", + "MobileCoreServices", + "ModelIO", + "MultipeerConnectivity", + "MusicKit", + "NaturalLanguage", + "NearbyInteraction", + "Network", + "NetworkExtension", + "NewsstandKit", + "NotificationCenter", + "OSLog", + "OpenAL", + "OpenGLES", + "PDFKit", + "PHASE", + "PassKit", + "PencilKit", + "Photos", + "PhotosUI", + "ProximityReader", + "PushKit", + "PushToTalk", + "QuartzCore", + "QuickLook", + "QuickLookThumbnailing", + "RealityFoundation", + "RealityKit", + "ReplayKit", + "RoomPlan", + "SafariServices", + "SafetyKit", + "SceneKit", + "ScreenTime", + "Security", + "SensorKit", + "SharedWithYou", + "SharedWithYouCore", + "ShazamKit", + "Social", + "SoundAnalysis", + "Speech", + "SpriteKit", + "StoreKit", + "SwiftUI", + "SystemConfiguration", + "TabularData", + "ThreadNetwork", + "Twitter", + "UIKit", + "UniformTypeIdentifiers", + "UserNotifications", + "UserNotificationsUI", + "VideoSubscriberAccount", + "VideoToolbox", + "Vision", + "VisionKit", + "WatchConnectivity", + "WeatherKit", + "WebKit", + "WidgetKit", + "iAd", +]) + +_tvos = sets.make([ + "AVFAudio", + "AVFoundation", + "AVKit", + "Accelerate", + "Accessibility", + "AdSupport", + "AppIntents", + "AppTrackingTransparency", + "AudioToolbox", + "AudioUnit", + "AuthenticationServices", + "BackgroundTasks", + "CFNetwork", + "Charts", + "CloudKit", + "ColorSync", + "Combine", + "CoreAudio", + "CoreAudioTypes", + "CoreBluetooth", + "CoreData", + "CoreFoundation", + "CoreGraphics", + "CoreHaptics", + "CoreImage", + "CoreLocation", + "CoreMIDI", + "CoreML", + "CoreMedia", + "CoreServices", + "CoreSpotlight", + "CoreText", + "CoreTransferable", + "CoreVideo", + "CreateML", + "CreateMLComponents", + "CryptoKit", + "CryptoTokenKit", + "DataDetection", + "DeveloperToolsSupport", + "DeviceCheck", + "DeviceDiscoveryUI", + "ExposureNotification", + "ExtensionFoundation", + "ExtensionKit", + "ExternalAccessory", + "Foundation", + "GLKit", + "GameController", + "GameKit", + "GameplayKit", + "GroupActivities", + "HomeKit", + "IOSurface", + "ImageIO", + "Intents", + "IntentsUI", + "JavaScriptCore", + "LinkPresentation", + "MLCompute", + "MapKit", + "Matter", + "MediaAccessibility", + "MediaPlayer", + "MediaToolbox", + "Metal", + "MetalKit", + "MetalPerformanceShaders", + "MetalPerformanceShadersGraph", + "MetricKit", + "MobileCoreServices", + "ModelIO", + "MultipeerConnectivity", + "MusicKit", + "NaturalLanguage", + "Network", + "OSLog", + "OpenAL", + "OpenGLES", + "PHASE", + "Photos", + "PhotosUI", + "QuartzCore", + "ReplayKit", + "SceneKit", + "Security", + "SharedWithYou", + "SharedWithYouCore", + "ShazamKit", + "SoundAnalysis", + "SpriteKit", + "StoreKit", + "SwiftUI", + "SystemConfiguration", + "TVMLKit", + "TVServices", + "TVUIKit", + "TabularData", + "UIKit", + "UniformTypeIdentifiers", + "UserNotifications", + "UserNotificationsUI", + "VideoSubscriberAccount", + "VideoToolbox", + "Vision", + "WeatherKit", +]) + +_watchos = sets.make([ + "AVFAudio", + "AVFoundation", + "AVKit", + "Accelerate", + "Accessibility", + "AppIntents", + "AuthenticationServices", + "CFNetwork", + "CallKit", + "CarKey", + "Charts", + "ClockKit", + "CloudKit", + "ColorSync", + "Combine", + "Contacts", + "CoreAudio", + "CoreAudioTypes", + "CoreBluetooth", + "CoreData", + "CoreFoundation", + "CoreGraphics", + "CoreLocation", + "CoreLocationUI", + "CoreMIDI", + "CoreML", + "CoreMedia", + "CoreMotion", + "CoreServices", + "CoreText", + "CoreTransferable", + "CoreVideo", + "CryptoKit", + "CryptoTokenKit", + "DataDetection", + "DeveloperToolsSupport", + "DeviceCheck", + "EventKit", + "ExtensionFoundation", + "ExtensionKit", + "Foundation", + "GameKit", + "HealthKit", + "HomeKit", + "ImageIO", + "Intents", + "LocalAuthentication", + "MapKit", + "Matter", + "MediaPlayer", + "MobileCoreServices", + "MusicKit", + "NaturalLanguage", + "NearbyInteraction", + "Network", + "NetworkExtension", + "OSLog", + "PassKit", + "PhotosUI", + "PushKit", + "SafetyKit", + "SceneKit", + "Security", + "ShazamKit", + "SoundAnalysis", + "SpriteKit", + "StoreKit", + "SwiftUI", + "TabularData", + "UIKit", + "UniformTypeIdentifiers", + "UserNotifications", + "UserNotificationsUI", + "WatchConnectivity", + "WatchKit", + "WeatherKit", + "WidgetKit", +]) + +_all = sets.union(_macos, _ios, _tvos, _watchos) + +apple_builtin_frameworks = struct( + all = _all, + ios = _ios, + macos = _macos, + tvos = _tvos, + watchos = _watchos, +) diff --git a/swiftpkg/internal/bazel_apple_platforms.bzl b/swiftpkg/internal/bazel_apple_platforms.bzl new file mode 100644 index 000000000..557b02abe --- /dev/null +++ b/swiftpkg/internal/bazel_apple_platforms.bzl @@ -0,0 +1,33 @@ +"""Module for retrieving information about Apple platforms.""" + +load("@bazel_skylib//lib:sets.bzl", "sets") +load("//config_settings/spm/platform:platforms.bzl", spm_platforms = "platforms") +load(":apple_builtin_frameworks.bzl", "apple_builtin_frameworks") + +_platform_sets = { + spm_platforms.macos: apple_builtin_frameworks.macos, + spm_platforms.ios: apple_builtin_frameworks.ios, + spm_platforms.tvos: apple_builtin_frameworks.tvos, + spm_platforms.watchos: apple_builtin_frameworks.watchos, +} + +_condition_tmpl = "@cgrindel_swift_bazel//config_settings/spm/platform:{}" + +def _for_framework(framework): + """Returns the platform condition labels for an Apple built-in framework. + + Args: + framework: The name of the Apple framework as a `string`. + + Returns: + A `list` of the platform condition labels. + """ + platforms = [] + for (platform, pset) in _platform_sets.items(): + if sets.contains(pset, framework): + platforms.append(_condition_tmpl.format(platform)) + return sorted(platforms) + +bazel_apple_platforms = struct( + for_framework = _for_framework, +) diff --git a/swiftpkg/internal/clang_files.bzl b/swiftpkg/internal/clang_files.bzl index 299285381..8b12b73a6 100644 --- a/swiftpkg/internal/clang_files.bzl +++ b/swiftpkg/internal/clang_files.bzl @@ -259,13 +259,9 @@ def _collect_files( others = sorted(others), ) -def _has_objc_srcs(srcs): - return lists.contains(srcs, lambda x: x.endswith(".m")) - clang_files = struct( collect_files = _collect_files, get_hdr_paths_from_modulemap = _get_hdr_paths_from_modulemap, - has_objc_srcs = _has_objc_srcs, is_hdr = _is_hdr, is_include_hdr = _is_include_hdr, is_public_modulemap = _is_public_modulemap, diff --git a/swiftpkg/internal/deps_indexes.bzl b/swiftpkg/internal/deps_indexes.bzl index 655e477dd..6d230826f 100644 --- a/swiftpkg/internal/deps_indexes.bzl +++ b/swiftpkg/internal/deps_indexes.bzl @@ -91,9 +91,45 @@ def _new_product(identity, name, type, target_labels): target_labels = target_labels, ) +def _modulemap_label_for_module(module): + return bazel_labels.new( + name = pkginfo_targets.modulemap_label_name(module.label.name), + repository_name = module.label.repository_name, + package = module.label.package, + ) + +def _labels_for_module(module, depender_src_type): + """Returns the dep labels that should be used for a module. + + Args: + module: The dependent module (`struct` as returned by + `dep_indexes.new_module`). + depender_src_type: The source type for the target (`string` value from + `src_types`) that will depend on the module. + + Returns: + A `list` of Bazel label `struct` values as returned by `bazel_labels.new`, + """ + labels = [module.label] + + if module.src_type == src_types.objc: + # If the dep is an objc, return the real Objective-C target, not the Swift + # module alias. This is part of a workaround for Objective-C modules not + # being able to `@import` modules from other Objective-C modules. + # See `swiftpkg_build_files.bzl` for more information. + labels.append(_modulemap_label_for_module(module)) + + elif depender_src_type == src_types.objc and module.src_type == src_types.swift: + # If an Objc module wants to @import a Swift module, it will need the + # modulemap target. + labels.append(_modulemap_label_for_module(module)) + + return labels + def _resolve_module_labels( deps_index, module_name, + depender_module_name, preferred_repo_name = None, restrict_to_repo_names = []): """Finds a Bazel label that provides the specified module. @@ -101,6 +137,7 @@ def _resolve_module_labels( Args: deps_index: A `dict` as returned by `deps_indexes.new_from_json`. module_name: The name of the module as a `string` + depender_module_name: The name of the depender module as a `string`. preferred_repo_name: Optional. If a target in this repository provides the module, prefer it. restrict_to_repo_names: Optional. A `list` of repository names to @@ -112,7 +149,10 @@ def _resolve_module_labels( modules = deps_index.modules.get(module_name, []) if len(modules) == 0: return [] - labels = [m.label for m in modules] + + depender_modules = deps_index.modules.get(depender_module_name, []) + if len(depender_modules) == 0: + fail("No depender modules found for {}.".format(depender_module_name)) # If a repo name is provided, prefer that over any other matches if preferred_repo_name != None: @@ -121,22 +161,14 @@ def _resolve_module_labels( modules, lambda m: m.label.repository_name == preferred_repo_name, ) + depender_module = lists.find( + depender_modules, + lambda m: m.label.repository_name == preferred_repo_name, + ) + if depender_module == None: + depender_module = depender_modules[0] if module != None: - # We found a match for the current/preferred repo. If the dep is an - # objc, return the real Objective-C target, not the Swift module - # alias. This is part of a workaround for Objective-C modules not - # being able to `@import` modules from other Objective-C modules. - # See `swiftpkg_build_files.bzl` for more information. - if module.src_type == src_types.objc: - return [ - bazel_labels.new( - name = pkginfo_targets.objc_label_name(module.label.name), - repository_name = module.label.repository_name, - package = module.label.package, - ), - ] - else: - return [module.label] + return _labels_for_module(module, depender_module.src_type) # If we are meant to only find a match in a set of repo names, then if len(restrict_to_repo_names) > 0: @@ -145,16 +177,25 @@ def _resolve_module_labels( for rn in restrict_to_repo_names ] repo_names = sets.make(restrict_to_repo_names) - labels = [ - lbl - for lbl in labels - if sets.contains(repo_names, lbl.repository_name) + modules = [ + m + for m in modules + if sets.contains(repo_names, m.label.repository_name) + ] + depender_modules = [ + m + for m in depender_modules + if sets.contains(repo_names, m.label.repository_name) ] - # Only return the first label. - if len(labels) == 0: + # Only labels for the first module. + if len(modules) == 0: return [] - return [labels[0]] + if len(depender_modules) == 0: + fail("No depender modules found for {} in the restricted repos.".format( + depender_module_name, + )) + return _labels_for_module(modules[0], depender_modules[0].src_type) def _new_product_index_key(identity, name): return identity.lower() + "|" + name @@ -213,12 +254,16 @@ def _new_ctx(deps_index, preferred_repo_name = None, restrict_to_repo_names = [] restrict_to_repo_names = restrict_to_repo_names, ) -def _resolve_module_labels_with_ctx(deps_index_ctx, module_name): +def _resolve_module_labels_with_ctx( + deps_index_ctx, + module_name, + depender_module_name): """Finds a Bazel label that provides the specified module. Args: deps_index_ctx: A `struct` as returned by `deps_indexes.new_ctx`. module_name: The name of the module as a `string` + depender_module_name: The name of the depender module as a `string`. Returns: A `list` of `struct` values as returned by `bazel_labels.new`. @@ -226,6 +271,7 @@ def _resolve_module_labels_with_ctx(deps_index_ctx, module_name): return _resolve_module_labels( deps_index = deps_index_ctx.deps_index, module_name = module_name, + depender_module_name = depender_module_name, preferred_repo_name = deps_index_ctx.preferred_repo_name, restrict_to_repo_names = deps_index_ctx.restrict_to_repo_names, ) diff --git a/swiftpkg/internal/generate_modulemap.bzl b/swiftpkg/internal/generate_modulemap.bzl index 21785dcbd..63d29b8b2 100644 --- a/swiftpkg/internal/generate_modulemap.bzl +++ b/swiftpkg/internal/generate_modulemap.bzl @@ -5,6 +5,7 @@ # https://github.com/bazel-xcode/PodToBUILD/blob/e9bbf68151caf6c8cd9b8ed2fa361b38e0f6a860/BazelExtensions/extensions.bzl#L113 # https://github.com/bazel-xcode/xchammer/blob/master/sample/UrlGet/Vendor/rules_pods/BazelExtensions/extensions.bzl +load(":clang_files.bzl", "clang_files") load(":module_maps.bzl", "write_module_map") ModuleMapInfo = provider( @@ -24,12 +25,21 @@ def _generate_modulemap_impl(ctx): out_filename = "{}/module.modulemap".format(module_name) modulemap_file = ctx.actions.declare_file(out_filename) + hdrs = [ + f + for f in ctx.files.hdrs + if clang_files.is_hdr(f.path) + ] + + if len(hdrs) == 0: + fail("No header files were provided.") + write_module_map( actions = ctx.actions, module_map_file = modulemap_file, module_name = module_name, dependent_module_names = uses, - public_headers = ctx.files.hdrs, + public_headers = hdrs, ) provider_hdr = [modulemap_file] diff --git a/swiftpkg/internal/module_maps.bzl b/swiftpkg/internal/module_maps.bzl index bcee6f924..eed789b6d 100644 --- a/swiftpkg/internal/module_maps.bzl +++ b/swiftpkg/internal/module_maps.bzl @@ -17,7 +17,8 @@ """Logic for generating Clang module map files.""" -# TODO(#723): Remove these disables once https://github.com/bazelbuild/buildtools/issues/926 is fixed +# NOTE(cgrindel): Mangled the prefix to avoid finding this when looking for temporary task comments. +# T-O-D-O(#723): Remove these disables once https://github.com/bazelbuild/buildtools/issues/926 is fixed # buildifier: disable=return-value # buildifier: disable=function-docstring-return def write_module_map( diff --git a/swiftpkg/internal/objc_files.bzl b/swiftpkg/internal/objc_files.bzl new file mode 100644 index 000000000..b55b02224 --- /dev/null +++ b/swiftpkg/internal/objc_files.bzl @@ -0,0 +1,145 @@ +"""Module for retrieving info about Objective-C files.""" + +load("@bazel_skylib//lib:paths.bzl", "paths") +load("@bazel_skylib//lib:sets.bzl", "sets") +load("@cgrindel_bazel_starlib//bzllib:defs.bzl", "lists") +load(":apple_builtin_frameworks.bzl", "apple_builtin_frameworks") + +_pound_import = "#import " +_pound_import_len = len(_pound_import) +_at_import = "@import " +_at_import_len = len(_at_import) + +def _parse_pound_import(line): + import_idx = line.find(_pound_import) + if import_idx < 0: + return None + start_idx = import_idx + _pound_import_len + line_len = len(line) + + # Find the opening bracket + open_bracket_idx = -1 + for idx in range(start_idx, line_len): + char = line[idx] + if char == " " or char == "\t": + continue + elif char == "<": + open_bracket_idx = idx + break + else: + return None + if open_bracket_idx < 0: + return None + framework_start_idx = open_bracket_idx + 1 + + # Find the first slash (/) + slash_idx = -1 + for idx in range(open_bracket_idx, line_len): + char = line[idx] + if char == "/": + slash_idx = idx + if slash_idx < 0: + return None + + return line[framework_start_idx:slash_idx] + +def _parse_at_import(line): + import_idx = line.find(_at_import) + if import_idx < 0: + return None + start_idx = import_idx + _at_import_len + line_len = len(line) + + framework_start_idx = -1 + framework_end_idx = -1 + for idx in range(start_idx, line_len): + char = line[idx] + if char == " " or char == "\t": + continue + elif char == ";": + framework_end_idx = idx + break + elif framework_start_idx < 0: + framework_start_idx = idx + + if framework_start_idx < 0 or framework_end_idx < 0: + return None + return line[framework_start_idx:framework_end_idx] + +def _parse_for_imported_framework(line): + """Parse a single line of text looking for a framework import. + + Args: + line: The line to be parsed as a `string`. + + Returns: + The name of the imported framework as a `string`, if a framework + import is found. Otherwise, it returns `None`. + """ + if line == None or line == "": + return None + + def _verify(name): + if sets.contains(apple_builtin_frameworks.all, name): + return name + else: + return None + + framework = _parse_pound_import(line) + if framework != None: + return _verify(framework) + framework = _parse_at_import(line) + if framework != None: + return _verify(framework) + return None + +def _collect_frameworks_for_src(repository_ctx, src_path): + frameworks = [] + contents = repository_ctx.read(src_path) + + lines = contents.splitlines() + for line in lines: + imported_framework = _parse_for_imported_framework(line) + if imported_framework != None: + frameworks.append(imported_framework) + return frameworks + +def _collect_builtin_frameworks(repository_ctx, root_path, srcs): + """Collect all of the Apple built-in frameworks imported by the specified \ + source files. + + Args: + repository_ctx: An instance of `repository_ctx`. + root_path: The parent path for the source files as a `string`. + srcs: A `list` of source file paths relative to the `root_path`. + + Returns: + A `list` of the imported Apple built-in frameworks. + """ + frameworks = sets.make() + for src in srcs: + src_path = paths.join(root_path, src) + src_frameworks = _collect_frameworks_for_src(repository_ctx, src_path) + + for sf in src_frameworks: + sets.insert(frameworks, sf) + return sorted(sets.to_list(frameworks)) + +def _has_objc_srcs(srcs): + """Determines whether any of the provide paths are Objective-C files. + + Args: + srcs: A `list` of file paths (`string`). + + Returns: + A `bool` indicating whether any of the source files are Objective-C + files. + """ + return lists.contains(srcs, lambda x: x.endswith(".m")) + +objc_files = struct( + collect_builtin_frameworks = _collect_builtin_frameworks, + has_objc_srcs = _has_objc_srcs, + # Public for testing purposes + parse_for_imported_framework = _parse_for_imported_framework, +) diff --git a/swiftpkg/internal/pkginfo_target_deps.bzl b/swiftpkg/internal/pkginfo_target_deps.bzl index cd98805a1..230ce503c 100644 --- a/swiftpkg/internal/pkginfo_target_deps.bzl +++ b/swiftpkg/internal/pkginfo_target_deps.bzl @@ -9,7 +9,7 @@ load(":pkginfo_dependencies.bzl", "pkginfo_dependencies") _target_dep_kind = "_target_dep" def make_pkginfo_target_deps(bazel_labels): - def _bazel_label_strs(pkg_ctx, target_dep): + def _bzl_select_list(pkg_ctx, target_dep, depender_module_name): """Return the Bazel labels associated with a target dependency. A module will resolve to a single label. A product can resolve to one @@ -19,6 +19,8 @@ def make_pkginfo_target_deps(bazel_labels): pkg_ctx: A `struct` as returned by `pkg_ctxs.new`. target_dep: A `struct` as returned by `pkginfos.new_target_dependency`. + depender_module_name: The name of the module that depends on the + target dependency. Returns: A `list` of `struct` values as returned by `bzl_selects.new` @@ -32,6 +34,7 @@ def make_pkginfo_target_deps(bazel_labels): labels = deps_indexes.resolve_module_labels_with_ctx( pkg_ctx.deps_index_ctx, target_dep.by_name.name, + depender_module_name, ) if len(labels) == 0: # Seeing Package.swift files with byName dependencies that @@ -49,6 +52,7 @@ def make_pkginfo_target_deps(bazel_labels): labels = deps_indexes.resolve_module_labels_with_ctx( pkg_ctx.deps_index_ctx, target_dep.target.target_name, + depender_module_name, ) if len(labels) == 0: fail("""\ @@ -94,7 +98,7 @@ Unrecognized target dependency while generating a Bazel dependency label.\ ) return struct( - bazel_label_strs = _bazel_label_strs, + bzl_select_list = _bzl_select_list, target_dep_kind = _target_dep_kind, ) diff --git a/swiftpkg/internal/pkginfo_targets.bzl b/swiftpkg/internal/pkginfo_targets.bzl index c50684fae..587ba6163 100644 --- a/swiftpkg/internal/pkginfo_targets.bzl +++ b/swiftpkg/internal/pkginfo_targets.bzl @@ -3,6 +3,8 @@ load("@bazel_skylib//lib:paths.bzl", "paths") load("@cgrindel_bazel_starlib//bzllib:defs.bzl", "bazel_labels") +_modulemap_suffix = "_modulemap" + def _get(targets, name, fail_if_not_found = True): """Retrieves the target with the given name from a list of targets. @@ -84,6 +86,29 @@ def _objc_label_name(target_name): """ return target_name + "_Objc" +def _modulemap_label_name(target_name): + """Returns the name of the related `generate_modulemap` target. + + Args: + target_name: The publicly advertised name for the `objc_library` target. + + Returns: + The name of the `generate_modulemap` target as a `string`. + """ + return target_name + _modulemap_suffix + +def _is_modulemap_label(target_name): + """Determines whether the name is a `generate_modulemap` target name. + + Args: + target_name: The name to be evaluated as a `string`. + + Returns: + A `bool` representing whether the input name is a `generate_modulemap` + target. + """ + return target_name.endswith(_modulemap_suffix) + def make_pkginfo_targets(bazel_labels): """Create a `pkginfo_targets` module. @@ -116,7 +141,9 @@ def make_pkginfo_targets(bazel_labels): bazel_label = _bazel_label, bazel_label_name = _bazel_label_name, get = _get, + is_modulemap_label = _is_modulemap_label, join_path = _join_path, + modulemap_label_name = _modulemap_label_name, objc_label_name = _objc_label_name, srcs = _srcs, ) diff --git a/swiftpkg/internal/swift_files.bzl b/swiftpkg/internal/swift_files.bzl new file mode 100644 index 000000000..66a28aad4 --- /dev/null +++ b/swiftpkg/internal/swift_files.bzl @@ -0,0 +1,43 @@ +"""Module for Swift file operations.""" + +load("@bazel_skylib//lib:paths.bzl", "paths") + +def _has_objc_directive(repository_ctx, path): + """Determines whether the specified file contains any `@objc` or \ + `@objcMembers` directives indicating that the Swift file will be consumed \ + by Objective-C code. + + Args: + repository_ctx: A `repository_ctx` instance. + path: The path to a file as a `string`. + + Returns: + A `bool` indicating whether the file contains an Objective-C directive. + """ + contents = repository_ctx.read(path) + result = contents.find("@objc") + return result >= 0 + +def _imports_xctest(repository_ctx, pkg_ctx, target): + """Determines whether any of the Swift sources for a target import XCTest. + + Args: + repository_ctx: A `repository_ctx` instance. + pkg_ctx: A `struct` as created by `pkg_ctxs.new`. + target: A `struct` as created by `pkginfos.new_target`. + + Returns: + A `bool` indicating whether the target imports `XCTest`. + """ + target_path = paths.join(pkg_ctx.pkg_info.path, target.path) + for src in target.sources: + path = paths.join(target_path, src) + file_contents = repository_ctx.read(path) + if file_contents.find("import XCTest") > -1: + return True + return False + +swift_files = struct( + has_objc_directive = _has_objc_directive, + imports_xctest = _imports_xctest, +) diff --git a/swiftpkg/internal/swiftpkg_build_files.bzl b/swiftpkg/internal/swiftpkg_build_files.bzl index 54a9acfd7..6f8a68b66 100644 --- a/swiftpkg/internal/swiftpkg_build_files.bzl +++ b/swiftpkg/internal/swiftpkg_build_files.bzl @@ -3,16 +3,19 @@ load("@bazel_skylib//lib:paths.bzl", "paths") load("@bazel_skylib//lib:sets.bzl", "sets") load("@cgrindel_bazel_starlib//bzllib:defs.bzl", "bazel_labels", "lists") +load(":bazel_apple_platforms.bzl", "bazel_apple_platforms") load(":build_decls.bzl", "build_decls") load(":build_files.bzl", "build_files") load(":bzl_selects.bzl", "bzl_selects") load(":clang_files.bzl", "clang_files") load(":load_statements.bzl", "load_statements") +load(":objc_files.bzl", "objc_files") load(":pkginfo_target_deps.bzl", "pkginfo_target_deps") load(":pkginfo_targets.bzl", "pkginfo_targets") load(":pkginfos.bzl", "build_setting_kinds", "module_types", "pkginfos", "target_types") load(":repository_files.bzl", "repository_files") load(":starlark_codegen.bzl", scg = "starlark_codegen") +load(":swift_files.bzl", "swift_files") # MARK: - Target Entry Point @@ -33,7 +36,7 @@ def _new_for_target(repository_ctx, pkg_ctx, target): def _swift_target_build_file(repository_ctx, pkg_ctx, target): deps = lists.flatten([ - pkginfo_target_deps.bazel_label_strs(pkg_ctx, td) + pkginfo_target_deps.bzl_select_list(pkg_ctx, td, depender_module_name = target.c99name) for td in target.dependencies ]) attrs = { @@ -51,9 +54,18 @@ def _swift_target_build_file(repository_ctx, pkg_ctx, target): # GH046: Support plugins. + # Check if any of the sources indicate that the module will be used by + # Objective-C code. If so, generate the bridge header file. + target_path = paths.join(pkg_ctx.pkg_info.path, target.path) + for src in target.sources: + path = paths.join(target_path, src) + if swift_files.has_objc_directive(repository_ctx, path): + attrs["generates_header"] = True + break + # The rules_swift code links in developer libraries if the rule is marked testonly. # https://github.com/bazelbuild/rules_swift/blob/master/swift/internal/compiling.bzl#L1312-L1319 - is_test = _imports_xctest(repository_ctx, pkg_ctx, target) + is_test = swift_files.imports_xctest(repository_ctx, pkg_ctx, target) if target.swift_settings != None: if len(target.swift_settings.defines) > 0: @@ -86,20 +98,30 @@ def _swift_target_build_file(repository_ctx, pkg_ctx, target): else: fail("Unrecognized target type for a Swift target. type:", target.type) + # Generate a modulemap for the Swift module. + if attrs.get("generates_header", False): + load_stmts.append(swiftpkg_generate_modulemap_load_stmt) + bzl_target_name = pkginfo_targets.bazel_label_name(target) + modulemap_target_name = pkginfo_targets.modulemap_label_name(bzl_target_name) + modulemap_deps = _collect_modulemap_deps(deps) + decls.append( + build_decls.new( + kind = swiftpkg_kinds.generate_modulemap, + name = modulemap_target_name, + attrs = { + "deps": bzl_selects.to_starlark(modulemap_deps), + "hdrs": [":{}".format(bzl_target_name)], + "module_name": target.c99name, + "visibility": ["//visibility:public"], + }, + ), + ) + return build_files.new( load_stmts = load_stmts, decls = decls, ) -def _imports_xctest(repository_ctx, pkg_ctx, target): - target_path = paths.join(pkg_ctx.pkg_info.path, target.path) - for src in target.sources: - path = paths.join(target_path, src) - file_contents = repository_ctx.read(path) - if file_contents.find("import XCTest") > -1: - return True - return False - def _swift_library_from_target(target, attrs): return build_decls.new( kind = swift_kinds.library, @@ -190,7 +212,11 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target): relative_to = pkg_path, ) deps = lists.flatten([ - pkginfo_target_deps.bazel_label_strs(pkg_ctx, td) + pkginfo_target_deps.bzl_select_list( + pkg_ctx, + td, + depender_module_name = target.c99name, + ) for td in target.dependencies ]) @@ -271,7 +297,6 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target): for bs in target.linker_settings.linked_libraries ])) if len(target.linker_settings.linked_frameworks) > 0: - # copts.extend(lists.flatten([ linkopts.extend(lists.flatten([ bzl_selects.new_from_build_setting(bs) for bs in target.linker_settings.linked_frameworks @@ -362,35 +387,58 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target): attrs["defines"] = bzl_selects.to_starlark(defines) bzl_target_name = pkginfo_targets.bazel_label_name(target) - if clang_files.has_objc_srcs(srcs): + if objc_files.has_objc_srcs(srcs): # Enable clang module support. # https://bazel.build/reference/be/objective-c#objc_library.enable_modules attrs["enable_modules"] = True attrs["module_name"] = target.c99name + sdk_frameworks = objc_files.collect_builtin_frameworks( + repository_ctx = repository_ctx, + root_path = pkg_path, + srcs = attrs.get("srcs", []) + attrs.get("hdrs", []), + ) + sdk_framework_bzl_selects = [] + for sf in sdk_frameworks: + platform_conditions = bazel_apple_platforms.for_framework(sf) + for pc in platform_conditions: + sdk_framework_bzl_selects.append( + bzl_selects.new( + value = sf, + kind = _condition_kinds.sdk_frameworks, + condition = pc, + ), + ) + attrs["sdk_frameworks"] = bzl_selects.to_starlark( + sdk_framework_bzl_selects, + ) + + modulemap_deps = _collect_modulemap_deps(deps) + # There is a known issue with Objective-C library targets not # supporting the `@import` of modules defined in other Objective-C # targets. As a workaround, we will define two targets. One is the - # `objc_library` target. The other is a `swift_objc_module_alias` - # target. This second target generates a Swift module that re-exports - # the modules defined in the Objective-C. Any internal targets that - # depend upon this module will reference the `objc_library`. Any - # external targets that depend upon this module will reference the - # `swift_library` generated by the `swift_objc_module_alias` macro. + # `objc_library` target. The other is a `generate_modulemap` + # target. This second target generates a `module.modulemap` file and + # provides information about that generated file to `objc_library` + # targets. # # See `deps_indexes.bzl` for the logic that resolves the dependency # labels. - # See `swift_objc_module_alias.bzl` for details on the re-export macro. - load_stmts = [swiftpkg_objc_module_alias_load_stmt] - objc_target_name = pkginfo_targets.objc_label_name(bzl_target_name) + # See `generate_modulemap.bzl` for details on the modulemap generation. + # See `//swiftpkg/tests/generate_modulemap_tests` package for a usage + # example. + load_stmts = [swiftpkg_generate_modulemap_load_stmt] + modulemap_target_name = pkginfo_targets.modulemap_label_name(bzl_target_name) decls = [ - build_decls.new(objc_kinds.library, objc_target_name, attrs = attrs), + build_decls.new(objc_kinds.library, bzl_target_name, attrs = attrs), build_decls.new( - kind = swiftpkg_kinds.objc_module_alias, - name = bzl_target_name, + kind = swiftpkg_kinds.generate_modulemap, + name = modulemap_target_name, attrs = { - "deps": [":{}".format(objc_target_name)], - "module_names": [target.c99name], + "deps": bzl_selects.to_starlark(modulemap_deps), + "hdrs": hdrs, + "module_name": target.c99name, "visibility": ["//visibility:public"], }, ), @@ -551,6 +599,26 @@ def _swift_binary_from_product(product, dep_target, repo_name): }, ) +# MARK: - generate_modulemap Helpers + +def _collect_modulemap_deps(deps): + modulemap_deps = [] + for dep in deps: + mm_values = [ + v + for v in dep.value + if pkginfo_targets.is_modulemap_label(v) + ] + if len(mm_values) == 0: + continue + mm_dep = bzl_selects.new( + value = mm_values, + kind = dep.kind, + condition = dep.condition, + ) + modulemap_deps.append(mm_dep) + return modulemap_deps + # MARK: - Constants and API Definition swift_location = "@build_bazel_rules_swift//swift:swift.bzl" @@ -621,6 +689,7 @@ apple_dynamic_xcframework_import_load_stmt = load_statements.new( swiftpkg_kinds = struct( objc_module_alias = "swift_objc_module_alias", + generate_modulemap = "generate_modulemap", ) swiftpkg_build_defs_location = "@cgrindel_swift_bazel//swiftpkg:build_defs.bzl" @@ -630,8 +699,14 @@ swiftpkg_objc_module_alias_load_stmt = load_statements.new( swiftpkg_kinds.objc_module_alias, ) +swiftpkg_generate_modulemap_load_stmt = load_statements.new( + swiftpkg_build_defs_location, + swiftpkg_kinds.generate_modulemap, +) + _condition_kinds = struct( private_includes = "_privateIncludes", + sdk_frameworks = "_sdkFrameworks", header_search_path = build_setting_kinds.header_search_path, linked_framework = build_setting_kinds.linked_framework, linked_library = build_setting_kinds.linked_library, diff --git a/swiftpkg/tests/BUILD.bazel b/swiftpkg/tests/BUILD.bazel index 8f6ff9899..249af6464 100644 --- a/swiftpkg/tests/BUILD.bazel +++ b/swiftpkg/tests/BUILD.bazel @@ -1,4 +1,5 @@ load("@cgrindel_bazel_starlib//bzlformat:defs.bzl", "bzlformat_pkg") +load(":bazel_apple_platforms_tests.bzl", "bazel_apple_platforms_test_suite") load(":bazel_repo_names_tests.bzl", "bazel_repo_names_test_suite") load(":build_decls_tests.bzl", "build_decls_test_suite") load(":build_files_tests.bzl", "build_files_test_suite") @@ -6,17 +7,21 @@ load(":bzl_selects_tests.bzl", "bzl_selects_test_suite") load(":clang_files_tests.bzl", "clang_files_test_suite") load(":deps_indexes_tests.bzl", "deps_indexes_test_suite") load(":load_statements_tests.bzl", "load_statements_test_suite") +load(":objc_files_tests.bzl", "objc_files_test_suite") load(":pkginfo_ext_deps_tests.bzl", "pkginfo_ext_deps_test_suite") load(":pkginfo_target_deps_tests.bzl", "pkginfo_target_deps_test_suite") load(":pkginfo_targets_tests.bzl", "pkginfo_targets_test_suite") load(":pkginfos_tests.bzl", "pkginfos_test_suite") load(":repository_files_tests.bzl", "repository_files_test_suite") load(":starlark_codegen_tests.bzl", "starlark_codegen_test_suite") +load(":swift_files_tests.bzl", "swift_files_test_suite") load(":swiftpkg_build_files_tests.bzl", "swiftpkg_build_files_test_suite") load(":validations_tests.bzl", "validations_test_suite") bzlformat_pkg(name = "bzlformat") +bazel_apple_platforms_test_suite() + bazel_repo_names_test_suite() build_decls_test_suite() @@ -29,6 +34,8 @@ load_statements_test_suite() deps_indexes_test_suite() +objc_files_test_suite() + pkginfo_ext_deps_test_suite() pkginfo_target_deps_test_suite() @@ -43,6 +50,8 @@ bzl_selects_test_suite() starlark_codegen_test_suite() +swift_files_test_suite() + swiftpkg_build_files_test_suite() validations_test_suite() diff --git a/swiftpkg/tests/bazel_apple_platforms_tests.bzl b/swiftpkg/tests/bazel_apple_platforms_tests.bzl new file mode 100644 index 000000000..4ec6dada8 --- /dev/null +++ b/swiftpkg/tests/bazel_apple_platforms_tests.bzl @@ -0,0 +1,49 @@ +"""Tests for `bazel_apple_platforms` module.""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//swiftpkg/internal:bazel_apple_platforms.bzl", "bazel_apple_platforms") + +def _for_framework_test(ctx): + env = unittest.begin(ctx) + + tests = [ + struct( + msg = "all platforms", + framework = "Foundation", + exp = [ + "@cgrindel_swift_bazel//config_settings/spm/platform:ios", + "@cgrindel_swift_bazel//config_settings/spm/platform:macos", + "@cgrindel_swift_bazel//config_settings/spm/platform:tvos", + "@cgrindel_swift_bazel//config_settings/spm/platform:watchos", + ], + ), + struct( + msg = "single platform", + framework = "AppKit", + exp = [ + "@cgrindel_swift_bazel//config_settings/spm/platform:macos", + ], + ), + struct( + msg = "several platformis", + framework = "UIKit", + exp = [ + "@cgrindel_swift_bazel//config_settings/spm/platform:ios", + "@cgrindel_swift_bazel//config_settings/spm/platform:tvos", + "@cgrindel_swift_bazel//config_settings/spm/platform:watchos", + ], + ), + ] + for t in tests: + actual = bazel_apple_platforms.for_framework(t.framework) + asserts.equals(env, t.exp, actual, t.msg) + + return unittest.end(env) + +for_framework_test = unittest.make(_for_framework_test) + +def bazel_apple_platforms_test_suite(): + return unittest.suite( + "bazel_apple_platforms_tests", + for_framework_test, + ) diff --git a/swiftpkg/tests/deps_indexes_tests.bzl b/swiftpkg/tests/deps_indexes_tests.bzl index ac9d0c218..1f2a04c7b 100644 --- a/swiftpkg/tests/deps_indexes_tests.bzl +++ b/swiftpkg/tests/deps_indexes_tests.bzl @@ -21,6 +21,28 @@ def _new_from_json_test(ctx): ), ), ], + "Bar": [ + deps_indexes.new_module( + name = "Bar", + c99name = "Bar", + src_type = "swift", + label = bazel_labels.new( + repository_name = "@example_cool_repo", + package = "", + name = "Bar", + ), + ), + deps_indexes.new_module( + name = "Bar", + c99name = "Bar", + src_type = "swift", + label = bazel_labels.new( + repository_name = "@example_another_repo", + package = "Sources/Bar", + name = "Bar", + ), + ), + ], "Foo": [ deps_indexes.new_module( name = "Foo", @@ -43,6 +65,18 @@ def _new_from_json_test(ctx): ), ), ], + "ObjcLibrary": [ + deps_indexes.new_module( + name = "ObjcLibrary", + c99name = "ObjcLibrary", + src_type = "objc", + label = bazel_labels.new( + repository_name = "@example_cool_repo", + package = "", + name = "ObjcLibrary", + ), + ), + ], } expected = deps_indexes.new(modules = expected_modules) asserts.equals(env, expected, actual) @@ -58,6 +92,7 @@ def _resolve_module_labels_test(ctx): struct( msg = "Foo module", module = "Foo", + depender_module_name = "Bar", preferred = None, restrict_to = [], exp = [bazel_labels.new( @@ -68,7 +103,8 @@ def _resolve_module_labels_test(ctx): ), struct( msg = "module not in index", - module = "Bar", + module = "DoesNotExist", + depender_module_name = "DoesNotExist", preferred = None, restrict_to = [], exp = [], @@ -76,6 +112,7 @@ def _resolve_module_labels_test(ctx): struct( msg = "preferred repo name exists", module = "Foo", + depender_module_name = "Bar", preferred = "example_cool_repo", restrict_to = [], exp = [bazel_labels.new( @@ -87,6 +124,7 @@ def _resolve_module_labels_test(ctx): struct( msg = "preferred repo name not found", module = "ArgumentParser", + depender_module_name = "Bar", preferred = "example_another_repo", restrict_to = [], exp = [bazel_labels.new( @@ -98,6 +136,7 @@ def _resolve_module_labels_test(ctx): struct( msg = "restrict to repos, found one", module = "Foo", + depender_module_name = "Bar", preferred = None, restrict_to = ["some_other_repo", "example_another_repo"], exp = [bazel_labels.new( @@ -109,6 +148,7 @@ def _resolve_module_labels_test(ctx): struct( msg = "restrict to repos, not found", module = "Foo", + depender_module_name = "Bar", preferred = None, restrict_to = ["some_other_repo"], exp = [], @@ -116,6 +156,7 @@ def _resolve_module_labels_test(ctx): struct( msg = "preferred repo and restrict to repos, found preferred", module = "Foo", + depender_module_name = "Bar", preferred = "example_cool_repo", restrict_to = ["example_cool_repo", "example_another_repo"], exp = [bazel_labels.new( @@ -125,21 +166,49 @@ def _resolve_module_labels_test(ctx): )], ), struct( - msg = "preferred repo and restrict to repos, found not preferred", + msg = "Swift library depends upon Objc library", + module = "ObjcLibrary", + depender_module_name = "Bar", + preferred = None, + restrict_to = [], + exp = [ + bazel_labels.new( + repository_name = "@example_cool_repo", + package = "", + name = "ObjcLibrary", + ), + bazel_labels.new( + repository_name = "@example_cool_repo", + package = "", + name = "ObjcLibrary_modulemap", + ), + ], + ), + struct( + msg = "Objc library depends upon Swift library", module = "Foo", - preferred = "some_other_repo", - restrict_to = ["some_other_repo", "example_another_repo"], - exp = [bazel_labels.new( - repository_name = "@example_another_repo", - package = "Sources/Foo", - name = "Foo", - )], + depender_module_name = "ObjcLibrary", + preferred = None, + restrict_to = [], + exp = [ + bazel_labels.new( + repository_name = "@example_cool_repo", + package = "", + name = "Foo", + ), + bazel_labels.new( + repository_name = "@example_cool_repo", + package = "", + name = "Foo_modulemap", + ), + ], ), ] for t in tests: actual = deps_indexes.resolve_module_labels( _deps_index, module_name = t.module, + depender_module_name = t.depender_module_name, preferred_repo_name = t.preferred, restrict_to_repo_names = t.restrict_to, ) @@ -157,7 +226,11 @@ def _resolve_module_labels_with_ctx_test(ctx): preferred_repo_name = "example_cool_repo", restrict_to_repo_names = ["example_cool_repo", "example_another_repo"], ) - actuals = deps_indexes.resolve_module_labels_with_ctx(deps_index_ctx, "Foo") + actuals = deps_indexes.resolve_module_labels_with_ctx( + deps_index_ctx = deps_index_ctx, + module_name = "Foo", + depender_module_name = "Bar", + ) asserts.equals(env, 1, len(actuals)) actual = actuals[0] asserts.equals(env, "@example_cool_repo", actual.repository_name) @@ -180,7 +253,10 @@ _deps_index_json = """ "modules": [ {"name": "ArgumentParser", "c99name": "ArgumentParser", "src_type": "swift", "label": "@apple_swift_argument_parser//Sources/ArgumentParser"}, {"name": "Foo", "c99name": "Foo", "src_type": "swift", "label": "@example_cool_repo//:Foo"}, - {"name": "Foo", "c99name": "Foo", "src_type": "swift", "label": "@example_another_repo//Sources/Foo"} + {"name": "Foo", "c99name": "Foo", "src_type": "swift", "label": "@example_another_repo//Sources/Foo"}, + {"name": "Bar", "c99name": "Bar", "src_type": "swift", "label": "@example_cool_repo//:Bar"}, + {"name": "Bar", "c99name": "Bar", "src_type": "swift", "label": "@example_another_repo//Sources/Bar"}, + {"name": "ObjcLibrary", "c99name": "ObjcLibrary", "src_type": "objc", "label": "@example_cool_repo//:ObjcLibrary"} ], "products": [] } diff --git a/swiftpkg/tests/generate_modulemap_tests/BUILD.bazel b/swiftpkg/tests/generate_modulemap_tests/BUILD.bazel index 362e06e4f..2d6a60e65 100644 --- a/swiftpkg/tests/generate_modulemap_tests/BUILD.bazel +++ b/swiftpkg/tests/generate_modulemap_tests/BUILD.bazel @@ -6,6 +6,7 @@ sh_test( name = "generate_modulemap_test", srcs = ["generate_modulemap_test.sh"], data = [ + "//swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc", "//swiftpkg/tests/generate_modulemap_tests/Sources/PrintVersion", ], deps = [ diff --git a/swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/BUILD.bazel b/swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/BUILD.bazel new file mode 100644 index 000000000..b5cc2b508 --- /dev/null +++ b/swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/BUILD.bazel @@ -0,0 +1,22 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_binary") +load("@cgrindel_bazel_starlib//bzlformat:defs.bzl", "bzlformat_pkg") +load("@rules_cc//cc:defs.bzl", "objc_library") + +bzlformat_pkg(name = "bzlformat") + +objc_library( + name = "main", + srcs = ["main.m"], + enable_modules = True, + target_compatible_with = ["@platforms//os:macos"], + deps = [ + "//swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift", + "//swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift:FooSwift_modulemap", + ], +) + +swift_binary( + name = "PrintVersionObjc", + visibility = ["//swiftpkg/tests/generate_modulemap_tests:__subpackages__"], + deps = [":main"], +) diff --git a/swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/main.m b/swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/main.m new file mode 100644 index 000000000..f47fbb8a7 --- /dev/null +++ b/swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/main.m @@ -0,0 +1,12 @@ +// #import "Foundation/Foundation.h"; +@import Foundation; +@import FooSwift; + +int main(int argc, char **argv) { + @autoreleasepool { + OIFooSwiftVersionInfo *verInfo = [[OIFooSwiftVersionInfo alloc] init]; + NSString *version = verInfo.myVersion; + [version writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:NULL]; + } + return 0; +} diff --git a/swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/BUILD.bazel b/swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/BUILD.bazel new file mode 100644 index 000000000..845792d16 --- /dev/null +++ b/swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/BUILD.bazel @@ -0,0 +1,26 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") +load("@cgrindel_bazel_starlib//bzlformat:defs.bzl", "bzlformat_pkg") +load("//swiftpkg/internal:generate_modulemap.bzl", "generate_modulemap") + +bzlformat_pkg(name = "bzlformat") + +swift_library( + name = "FooSwift", + srcs = ["FooSwiftVersionInfo.swift"], + generates_header = True, + module_name = "FooSwift", + visibility = ["//visibility:public"], + deps = [ + "//swiftpkg/tests/generate_modulemap_tests/SimpleCore", + ], +) + +generate_modulemap( + name = "FooSwift_modulemap", + hdrs = [":FooSwift"], + module_name = "FooSwift", + visibility = ["//swiftpkg/tests/generate_modulemap_tests:__subpackages__"], + deps = [ + "//swiftpkg/tests/generate_modulemap_tests/SimpleCore:SimpleCore_modulemap", + ], +) diff --git a/swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/FooSwiftVersionInfo.swift b/swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/FooSwiftVersionInfo.swift new file mode 100644 index 000000000..a9afb8a2b --- /dev/null +++ b/swiftpkg/tests/generate_modulemap_tests/Sources/FooSwift/FooSwiftVersionInfo.swift @@ -0,0 +1,10 @@ +import Foundation +import SimpleCore + +@objc(OIFooSwiftVersionInfo) +public class FooSwiftVersionInfo: NSObject { + @objc(myVersion) public func version() -> String { + let verInfo = VersionInfo() + return verInfo.version + } +} diff --git a/swiftpkg/tests/generate_modulemap_tests/generate_modulemap_test.sh b/swiftpkg/tests/generate_modulemap_tests/generate_modulemap_test.sh index 152366e89..7017ba845 100755 --- a/swiftpkg/tests/generate_modulemap_tests/generate_modulemap_test.sh +++ b/swiftpkg/tests/generate_modulemap_tests/generate_modulemap_test.sh @@ -23,7 +23,16 @@ PrintVersion_location=cgrindel_swift_bazel/swiftpkg/tests/generate_modulemap_tes PrintVersion="$(rlocation "${PrintVersion_location}")" || \ (echo >&2 "Failed to locate ${PrintVersion_location}" && exit 1) +PrintVersionObjc_location=cgrindel_swift_bazel/swiftpkg/tests/generate_modulemap_tests/PrintVersionObjc/PrintVersionObjc +PrintVersionObjc="$(rlocation "${PrintVersionObjc_location}")" || \ + (echo >&2 "Failed to locate ${PrintVersionObjc_location}" && exit 1) + # MARK - Test +expected="1.2.3" + output="$("${PrintVersion}")" -assert_equal "1.2.3" "${output}" "version check" +assert_equal "${expected}" "${output}" "version check" + +objc_output="$("${PrintVersionObjc}")" +assert_equal "${expected}" "${output}" "version check" diff --git a/swiftpkg/tests/objc_files_tests.bzl b/swiftpkg/tests/objc_files_tests.bzl new file mode 100644 index 000000000..b14643ecc --- /dev/null +++ b/swiftpkg/tests/objc_files_tests.bzl @@ -0,0 +1,145 @@ +"""Tests for `objc_files` module.""" + +load("@bazel_skylib//lib:paths.bzl", "paths") +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//swiftpkg/internal:objc_files.bzl", "objc_files") + +def _parse_for_imported_framework_test(ctx): + env = unittest.begin(ctx) + + tests = [ + struct( + msg = "no line", + line = None, + exp = None, + ), + struct( + msg = "empty line", + line = "", + exp = None, + ), + struct( + msg = "line with the word import", + line = """\ + return @"this is not an import"; +""", + exp = None, + ), + struct( + msg = "#import dir/header with brackets, is framework", + line = """\ +#import +""", + exp = "CoreTelephony", + ), + struct( + msg = "#import dir/header with brackets, is not framework", + line = """\ +#import +""", + exp = None, + ), + struct( + msg = "#import header with brackets", + line = """\ +#import +""", + exp = None, + ), + struct( + msg = "#import dir/header with quotes", + line = """\ +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" +""", + exp = None, + ), + struct( + msg = "@import, is framework", + line = """\ +@import UIKit; +""", + exp = "UIKit", + ), + struct( + msg = "@import, is not framework", + line = """\ +@import FirebaseCore; +""", + exp = None, + ), + ] + for t in tests: + actual = objc_files.parse_for_imported_framework(t.line) + asserts.equals(env, t.exp, actual, t.msg) + + return unittest.end(env) + +parse_for_imported_framework_test = unittest.make(_parse_for_imported_framework_test) + +def new_stub_repository_ctx(file_contents = {}): + def read(path): + return file_contents.get(path, "") + + return struct( + read = read, + ) + +def _collect_builtin_frameworks_test(ctx): + env = unittest.begin(ctx) + + root_path = "/path/to/target" + + tests = [ + struct( + msg = "target with #imports", + srcs = ["Foo.h", "Foo.m", "Bar.h", "Bar.m"], + file_contents = { + "Bar.h": """\ +#import +""", + "Foo.h": """\ +#import +#import +""", + }, + exp = ["CoreTelephony", "Foundation"], + ), + struct( + msg = "target with @imports", + srcs = ["Foo.h", "Foo.m", "Bar.h", "Bar.m"], + file_contents = { + "Bar.h": """\ +@import Foundation; +""", + "Foo.h": """\ +@import Foundation; +@import CoreTelephony; +""", + }, + exp = ["CoreTelephony", "Foundation"], + ), + ] + for t in tests: + stub_repository_ctx = new_stub_repository_ctx( + file_contents = { + paths.normalize(paths.join(root_path, fname)): cnts + for fname, cnts in getattr(t, "file_contents", {}).items() + }, + ) + actual = objc_files.collect_builtin_frameworks( + repository_ctx = stub_repository_ctx, + root_path = root_path, + srcs = t.srcs, + ) + asserts.equals(env, t.exp, actual, t.msg) + + return unittest.end(env) + +collect_builtin_frameworks_test = unittest.make(_collect_builtin_frameworks_test) + +def objc_files_test_suite(): + return unittest.suite( + "objc_files_tests", + parse_for_imported_framework_test, + collect_builtin_frameworks_test, + ) diff --git a/swiftpkg/tests/pkginfo_target_deps_tests.bzl b/swiftpkg/tests/pkginfo_target_deps_tests.bzl index c6232cc66..4be68e13e 100644 --- a/swiftpkg/tests/pkginfo_target_deps_tests.bzl +++ b/swiftpkg/tests/pkginfo_target_deps_tests.bzl @@ -84,11 +84,13 @@ _deps_index_json = """\ { "name": "AwesomePackage", "c99name": "AwesomePackage", + "src_type": "swift", "label": "@swiftpkg_example_swift_package//:AwesomePackage" }, { "name": "Foo", "c99name": "Foo", + "src_type": "swift", "label": "@swiftpkg_example_swift_package//:Source/Foo" } ], @@ -111,7 +113,7 @@ _pkg_ctx = pkg_ctxs.new( deps_index_json = _deps_index_json, ) -def _bazel_label_strs_test(ctx): +def _bzl_select_list_test(ctx): env = unittest.begin(ctx) tests = [ @@ -207,15 +209,15 @@ def _bazel_label_strs_test(ctx): ), ] for t in tests: - actual = pkginfo_target_deps.bazel_label_strs(_pkg_ctx, t.td) + actual = pkginfo_target_deps.bzl_select_list(_pkg_ctx, t.td, "Foo") asserts.equals(env, t.exp, actual, t.msg) return unittest.end(env) -bazel_label_strs_test = unittest.make(_bazel_label_strs_test) +bzl_select_list_test = unittest.make(_bzl_select_list_test) def pkginfo_target_deps_test_suite(): return unittest.suite( "pkginfo_target_deps_tests", - bazel_label_strs_test, + bzl_select_list_test, ) diff --git a/swiftpkg/tests/pkginfo_targets_tests.bzl b/swiftpkg/tests/pkginfo_targets_tests.bzl index fdbf0357a..316c18383 100644 --- a/swiftpkg/tests/pkginfo_targets_tests.bzl +++ b/swiftpkg/tests/pkginfo_targets_tests.bzl @@ -144,6 +144,17 @@ def _join_path_test(ctx): join_path_test = unittest.make(_join_path_test) +def _modulemap_label_names_test(ctx): + env = unittest.begin(ctx) + + asserts.false(env, pkginfo_targets.is_modulemap_label("Foo")) + mm_label = pkginfo_targets.modulemap_label_name("Foo") + asserts.true(env, pkginfo_targets.is_modulemap_label(mm_label)) + + return unittest.end(env) + +modulemap_label_names_test = unittest.make(_modulemap_label_names_test) + def pkginfo_targets_test_suite(): return unittest.suite( "pkginfo_targets_tests", diff --git a/swiftpkg/tests/swift_files_tests.bzl b/swiftpkg/tests/swift_files_tests.bzl new file mode 100644 index 000000000..cc2d9cd64 --- /dev/null +++ b/swiftpkg/tests/swift_files_tests.bzl @@ -0,0 +1,65 @@ +"""Tests for `swift_files` module.""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//swiftpkg/internal:swift_files.bzl", "swift_files") + +def _has_objc_directive_test(ctx): + env = unittest.begin(ctx) + + path = "path/to/File.swift" + + tests = [ + struct( + msg = "has @objc", + contents = """\ +@objc(OIFooSwiftVersionInfo) +public class FooSwiftVersionInfo: NSObject { + @objc(myVersion) public func version() -> String { + let verInfo = VersionInfo() + return verInfo.version + } +} +""", + exp = True, + ), + struct( + msg = "has @objcMembers", + contents = """\ +@objcMembers public class FooSwiftVersionInfo: NSObject { + public func version() -> String { + let verInfo = VersionInfo() + return verInfo.version + } +} +""", + exp = True, + ), + struct( + msg = "no directives", + contents = """\ +public class FooSwiftVersionInfo: NSObject { + public func version() -> String { + let verInfo = VersionInfo() + return verInfo.version + } +} +""", + exp = False, + ), + ] + for t in tests: + stub_repository_ctx = struct( + read = lambda p: t.contents, + ) + actual = swift_files.has_objc_directive(stub_repository_ctx, path) + asserts.equals(env, t.exp, actual, t.msg) + + return unittest.end(env) + +has_objc_directive_test = unittest.make(_has_objc_directive_test) + +def swift_files_test_suite(): + return unittest.suite( + "swift_files_tests", + has_objc_directive_test, + ) diff --git a/swiftpkg/tests/swiftpkg_build_files_tests.bzl b/swiftpkg/tests/swiftpkg_build_files_tests.bzl index c5837f730..1465a2b42 100644 --- a/swiftpkg/tests/swiftpkg_build_files_tests.bzl +++ b/swiftpkg/tests/swiftpkg_build_files_tests.bzl @@ -222,6 +222,22 @@ _pkg_info = pkginfos.new( ), ]), ), + pkginfos.new_target( + name = "ObjcLibraryDep", + type = "regular", + c99name = "ObjcLibraryDep", + module_type = "ClangTarget", + path = ".", + sources = [ + "objc_dep/foo.m", + "objc_dep/foo.h", + ], + source_paths = [ + "objc_dep/", + ], + public_hdrs_path = "include", + dependencies = [], + ), pkginfos.new_target( name = "ObjcLibrary", type = "regular", @@ -239,7 +255,11 @@ _pkg_info = pkginfos.new( "src/", ], public_hdrs_path = "include", - dependencies = [], + dependencies = [ + pkginfos.new_target_dependency( + by_name = pkginfos.new_by_name_reference("ObjcLibraryDep"), + ), + ], ), pkginfos.new_target( name = "SwiftLibraryWithConditionalDep", @@ -267,7 +287,7 @@ _pkg_info = pkginfos.new( pkginfos.new_target( name = "ClangLibraryWithConditionalDep", type = "regular", - c99name = "SwiftLibraryWithConditionalDep", + c99name = "ClangLibraryWithConditionalDep", module_type = "ClangTarget", path = ".", # NOTE: SPM does not report header files in the sources for clang @@ -291,6 +311,21 @@ _pkg_info = pkginfos.new( ), ], ), + pkginfos.new_target( + name = "SwiftForObjcTarget", + type = "regular", + c99name = "SwiftForObjcTarget", + module_type = "SwiftTarget", + path = "Source/SwiftForObjcTarget", + sources = [ + "SwiftForObjcTarget.swift", + ], + dependencies = [ + pkginfos.new_target_dependency( + by_name = pkginfos.new_by_name_reference("ObjcLibraryDep"), + ), + ], + ), ], ) @@ -302,7 +337,11 @@ _deps_index_json = """ {"name": "RegularSwiftTargetAsLibraryTests", "c99name": "RegularSwiftTargetAsLibraryTests", "src_type": "swift", "label": "@swiftpkg_mypackage//:Source_RegularSwiftTargetAsLibraryTests"}, {"name": "SwiftExecutableTarget", "c99name": "SwiftExecutableTarget", "src_type": "swift", "label": "@swiftpkg_mypackage//:Source_SwiftLibraryTarget"}, {"name": "ClangLibrary", "c99name": "ClangLibrary", "src_type": "clang", "label": "@swiftpkg_mypackage//:ClangLibrary"}, - {"name": "ObjcLibrary", "c99name": "ObjcLibrary", "src_type": "objc", "label": "@swiftpkg_mypackage//:ObjcLibrary"} + {"name": "ObjcLibrary", "c99name": "ObjcLibrary", "src_type": "objc", "label": "@swiftpkg_mypackage//:ObjcLibrary"}, + {"name": "ObjcLibraryDep", "c99name": "ObjcLibraryDep", "src_type": "objc", "label": "@swiftpkg_mypackage//:ObjcLibraryDep"}, + {"name": "SwiftLibraryWithConditionalDep", "c99name": "SwiftLibraryWithConditionalDep", "src_type": "swift", "label": "@swiftpkg_mypackage//:Source_SwiftLibraryWithConditionalDep"}, + {"name": "ClangLibraryWithConditionalDep", "c99name": "ClangLibraryWithConditionalDep", "src_type": "clang", "label": "@swiftpkg_mypackage//:ClangLibraryWithConditionalDep"}, + {"name": "SwiftForObjcTarget", "c99name": "SwiftForObjcTarget", "src_type": "swift", "label": "@swiftpkg_mypackage//:Source_SwiftForObjcTarget"} ], "products": [ ] @@ -467,6 +506,12 @@ cc_library( struct( msg = "Objc target", name = "ObjcLibrary", + file_contents = { + "src/foo.h": """\ +#import +#import +""", + }, find_results = { "include": [ "external.h", @@ -477,10 +522,10 @@ cc_library( ], }, exp = """\ -load("@cgrindel_swift_bazel//swiftpkg:build_defs.bzl", "swift_objc_module_alias") +load("@cgrindel_swift_bazel//swiftpkg:build_defs.bzl", "generate_modulemap") objc_library( - name = "ObjcLibrary_Objc", + name = "ObjcLibrary", copts = [ "-fblocks", "-fobjc-arc", @@ -489,11 +534,30 @@ objc_library( "-Iexternal/swiftpkg_mypackage/src", ], defines = ["SWIFT_PACKAGE=1"], - deps = [], + deps = [ + "@swiftpkg_mypackage//:ObjcLibraryDep", + "@swiftpkg_mypackage//:ObjcLibraryDep_modulemap", + ], enable_modules = True, hdrs = ["include/external.h"], includes = ["include"], module_name = "ObjcLibrary", + sdk_frameworks = select({ + "@cgrindel_swift_bazel//config_settings/spm/platform:ios": [ + "Foundation", + "UIKit", + ], + "@cgrindel_swift_bazel//config_settings/spm/platform:macos": ["Foundation"], + "@cgrindel_swift_bazel//config_settings/spm/platform:tvos": [ + "Foundation", + "UIKit", + ], + "@cgrindel_swift_bazel//config_settings/spm/platform:watchos": [ + "Foundation", + "UIKit", + ], + "//conditions:default": [], + }), srcs = [ "src/foo.h", "src/foo.m", @@ -502,10 +566,11 @@ objc_library( visibility = ["//visibility:public"], ) -swift_objc_module_alias( - name = "ObjcLibrary", - deps = [":ObjcLibrary_Objc"], - module_names = ["ObjcLibrary"], +generate_modulemap( + name = "ObjcLibrary_modulemap", + deps = ["@swiftpkg_mypackage//:ObjcLibraryDep_modulemap"], + hdrs = ["include/external.h"], + module_name = "ObjcLibrary", visibility = ["//visibility:public"], ) """, @@ -550,7 +615,7 @@ cc_library( "-fblocks", "-fobjc-arc", "-fPIC", - "-fmodule-name=SwiftLibraryWithConditionalDep", + "-fmodule-name=ClangLibraryWithConditionalDep", "-Iexternal/swiftpkg_mypackage/src", ], defines = ["SWIFT_PACKAGE=1"], @@ -565,7 +630,48 @@ cc_library( "src/foo.cc", "src/foo.h", ], - tags = ["swift_module=SwiftLibraryWithConditionalDep"], + tags = ["swift_module=ClangLibraryWithConditionalDep"], + visibility = ["//visibility:public"], +) +""", + ), + struct( + msg = "Swift library target with @objc directives and Objc dep", + name = "SwiftForObjcTarget", + file_contents = { + "SwiftForObjcTarget.swift": """\ +import Foundation + +@objc(OIFooBar) +public class FooBar: NSObject { + @objc public func doSomething() { + // Intentionally blank + } +} +""", + }, + exp = """\ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") +load("@cgrindel_swift_bazel//swiftpkg:build_defs.bzl", "generate_modulemap") + +swift_library( + name = "Source_SwiftForObjcTarget", + defines = ["SWIFT_PACKAGE"], + deps = [ + "@swiftpkg_mypackage//:ObjcLibraryDep", + "@swiftpkg_mypackage//:ObjcLibraryDep_modulemap", + ], + generates_header = True, + module_name = "SwiftForObjcTarget", + srcs = ["Source/SwiftForObjcTarget/SwiftForObjcTarget.swift"], + visibility = ["//visibility:public"], +) + +generate_modulemap( + name = "Source_SwiftForObjcTarget_modulemap", + deps = ["@swiftpkg_mypackage//:ObjcLibraryDep_modulemap"], + hdrs = [":Source_SwiftForObjcTarget"], + module_name = "SwiftForObjcTarget", visibility = ["//visibility:public"], ) """, diff --git a/tools/generate_builtin_frameworks/BUILD.bazel b/tools/generate_builtin_frameworks/BUILD.bazel index 403f2c349..fad816834 100644 --- a/tools/generate_builtin_frameworks/BUILD.bazel +++ b/tools/generate_builtin_frameworks/BUILD.bazel @@ -6,7 +6,10 @@ sh_binary( name = "generate_builtin_frameworks", srcs = ["generate_builtin_frameworks.sh"], args = [ + "--go_output", "gazelle/internal/swift/builtin_modules.go", + "--bzl_output", + "swiftpkg/internal/apple_builtin_frameworks.bzl", ], target_compatible_with = [ "@platforms//os:macos", diff --git a/tools/generate_builtin_frameworks/generate_builtin_frameworks.sh b/tools/generate_builtin_frameworks/generate_builtin_frameworks.sh index ffab071b9..d95696715 100755 --- a/tools/generate_builtin_frameworks/generate_builtin_frameworks.sh +++ b/tools/generate_builtin_frameworks/generate_builtin_frameworks.sh @@ -28,16 +28,46 @@ source "${env_sh}" # MARK - Functions -list_frameworks() { - local dir="${1}" +sdk_dirs() { + local platform_path="${1}" + local sdks_path="${platform_path}/Developer/SDKs" + find "${sdks_path}" -name "*.sdk" -depth 1 -type d -print0 +} + +list_frameworks_for_sdk() { + local sdk_path="${1}" + local dir="${sdk_path}/System/Library/Frameworks" find "${dir}" -name "*.framework" -depth 1 -not -name "_*" -exec basename -s .framework {} \; \ | sort } +export -f list_frameworks_for_sdk + +list_frameworks_for_platform() { + local platform_path="${1}" + + # Find the SDK paths for the platform + local sdk_paths=() + while IFS= read -r -d $'\0'; do + sdk_paths+=("$REPLY") + done < <(sdk_dirs "${platform_path}") + + local frameworks="" + for sdk_path in "${sdk_paths[@]}" ; do + frameworks+="$(list_frameworks_for_sdk "${sdk_path}")" + done + + echo "${frameworks}" | sort -u +} -format_as_go_args() { +format_as_go_list_item() { sed -E -e 's/^(.*)/\t"\1",/g' } +format_as_bzl_list_item() { + sed -E -e 's/^(.*)/ "\1",/g' +} + + show_usage() { get_usage exit 0 @@ -54,13 +84,13 @@ get_usage() { Generates a Go source file with the current list of macOS and iOS frameworks. Usage: -${utility} [OPTION]... [] +${utility} [OPTION]... [] Options: - --go_package The name of the Go package. (Default: ${go_package}) - The path where to write the Go source. If it is a - relative path, it is evaluated relative to the - workspace root. + --go_package The name of the Go package. (Default: ${go_package}) + --go_output The path where to write the Go source. If it is a + relative path, it is evaluated relative to the + workspace root. EOF } @@ -74,16 +104,19 @@ while (("$#")); do go_package="${2}" shift 2 ;; + "--go_output") + go_output="${2}" + shift 2 + ;; + "--bzl_output") + bzl_output="${2}" + shift 2 + ;; -*) usage_error "Unrecognized option. ${1}" ;; *) - if [[ -z "${output_path:-}" ]]; then - output_path="${1}" - shift 1 - else - usage_error "Unexpected argument. ${1}" - fi + usage_error "Unexpected argument. ${1}" ;; esac done @@ -91,15 +124,28 @@ done is_installed xcrun || usage_error "This utility requires that xcrun is available on the PATH." -sdk_path="$(xcrun --show-sdk-path)" -macos_frameworks_dir="${sdk_path}/System/Library/Frameworks" -ios_frameworks_dir="${sdk_path}/System/iOSSupport/System/Library/Frameworks" +if [[ -z "${go_output:-}" ]]; then + usage_error "Must specify an output path for the Go source file." +fi +if [[ -z "${bzl_output:-}" ]]; then + usage_error "Must specify an output path for the Bazel Starlark source file." +fi + + + +# sdk_path="$(xcrun --show-sdk-path)" +# macos_frameworks_dir="${sdk_path}/System/Library/Frameworks" sdk_version="$(xcrun --show-sdk-version)" sdk_build_version="$(xcrun --show-sdk-build-version)" -macos_frameworks="$(list_frameworks "${macos_frameworks_dir}")" -ios_frameworks="$(list_frameworks "${ios_frameworks_dir}")" +platforms_path="$(dirname "$(xcrun --show-sdk-platform-path)")" +macos_frameworks="$(list_frameworks_for_platform "${platforms_path}/MacOSX.platform")" +ios_frameworks="$(list_frameworks_for_platform "${platforms_path}/iPhoneOS.platform")" +tvos_frameworks="$(list_frameworks_for_platform "${platforms_path}/AppleTVOS.platform")" +watchos_frameworks="$(list_frameworks_for_platform "${platforms_path}/WatchOS.platform")" + +# Go Source go_src="$(cat <<-EOF package ${go_package} @@ -113,22 +159,74 @@ import mapset "github.com/deckarep/golang-set/v2" // SDK Build Version: ${sdk_build_version} var macosFrameworks = mapset.NewSet[string]( -$(echo "${macos_frameworks}" | format_as_go_args) +$(echo "${macos_frameworks}" | format_as_go_list_item) ) var iosFrameworks = mapset.NewSet[string]( -$(echo "${ios_frameworks}" | format_as_go_args) +$(echo "${ios_frameworks}" | format_as_go_list_item) +) + +var tvosFrameworks = mapset.NewSet[string]( +$(echo "${tvos_frameworks}" | format_as_go_list_item) +) + +var watchosFrameworks = mapset.NewSet[string]( +$(echo "${watchos_frameworks}" | format_as_go_list_item) ) EOF )" # Ouptut the Go source -output_cmd=( echo "${go_src}" ) -if [[ -n "${output_path:-}" ]]; then - if [[ ! "${output_path}" = /* ]]; then - output_path="${BUILD_WORKSPACE_DIRECTORY}/${output_path}" - fi - "${output_cmd[@]}" > "${output_path}" -else - "${output_cmd[@]}" +go_output_cmd=( echo "${go_src}" ) +if [[ ! "${go_output}" = /* ]]; then + go_output="${BUILD_WORKSPACE_DIRECTORY}/${go_output}" +fi +"${go_output_cmd[@]}" > "${go_output}" + +# Starlark Source + +bzl_src="$(cat <<-EOF +"""Module listing built-in Frameworks.""" + +load("@bazel_skylib//lib:sets.bzl", "sets") + +# NOTE: This file is generated by running the following: +# bazel run //tools/generate_builtin_frameworks +# +# SDK Version: ${sdk_version} +# SDK Build Version: ${sdk_build_version} + +_macos = sets.make([ +$(echo "${macos_frameworks}" | format_as_bzl_list_item) +]) + +_ios = sets.make([ +$(echo "${ios_frameworks}" | format_as_bzl_list_item) +]) + +_tvos = sets.make([ +$(echo "${tvos_frameworks}" | format_as_bzl_list_item) +]) + +_watchos = sets.make([ +$(echo "${watchos_frameworks}" | format_as_bzl_list_item) +]) + +_all = sets.union(_macos, _ios, _tvos, _watchos) + +apple_builtin_frameworks = struct( + all = _all, + ios = _ios, + macos = _macos, + tvos = _tvos, + watchos = _watchos, +) +EOF +)" + +# Ouptut the Starlark source +bzl_output_cmd=( echo "${bzl_src}" ) +if [[ ! "${bzl_output}" = /* ]]; then + bzl_output="${BUILD_WORKSPACE_DIRECTORY}/${bzl_output}" fi +"${bzl_output_cmd[@]}" > "${bzl_output}" diff --git a/tools/generate_builtin_frameworks/generate_builtin_frameworks_test.sh b/tools/generate_builtin_frameworks/generate_builtin_frameworks_test.sh index e7c8137d0..9568893e4 100755 --- a/tools/generate_builtin_frameworks/generate_builtin_frameworks_test.sh +++ b/tools/generate_builtin_frameworks/generate_builtin_frameworks_test.sh @@ -29,38 +29,47 @@ generate_builtin_frameworks_sh="$(rlocation "${generate_builtin_frameworks_sh_lo output="$("${generate_builtin_frameworks_sh}" --help)" assert_match "Usage:" "${output}" -# Default output -output="$("${generate_builtin_frameworks_sh}")" -assert_match "package swift" "${output}" -assert_match "var macosFrameworks =" "${output}" -assert_match "AppKit" "${output}" -assert_match "var iosFrameworks =" "${output}" -assert_match "UIKit" "${output}" - -# Change the package -output="$("${generate_builtin_frameworks_sh}" --go_package foobar)" -assert_match "package foobar" "${output}" - output_dir="${PWD}/output" rm -rf "${output_dir}" mkdir -p "${output_dir}" -# Write to an absolute path -absolute_path="${output_dir}/absolute.go" -"${generate_builtin_frameworks_sh}" "${absolute_path}" -[[ -e "${absolute_path}" ]] || fail "Expected the output file for the absolute path to exist." -output="$(< "${absolute_path}")" -assert_match "package swift" "${output}" -assert_match "var macosFrameworks =" "${output}" -assert_match "var iosFrameworks =" "${output}" +# Write Go file to an absolute path and change the package +go_abs_path="${output_dir}/absolute.go" +bzl_abs_path="${output_dir}/absolute.bzl" +"${generate_builtin_frameworks_sh}" \ + --go_output "${go_abs_path}" \ + --go_package foobar \ + --bzl_output "${bzl_abs_path}" +[[ -e "${go_abs_path}" ]] || \ + fail "Expected the output file for the Go absolute path to exist." +[[ -e "${bzl_abs_path}" ]] || \ + fail "Expected the output file for the Starlark absolute path to exist." +go_output="$(< "${go_abs_path}")" +assert_match "package foobar" "${go_output}" "Go absolute path" +assert_match "var macosFrameworks =" "${go_output}" "Go absolute path" +assert_match "var iosFrameworks =" "${go_output}" "Go absolute path" +bzl_output="$(< "${bzl_abs_path}")" +assert_match "_macos = " "${bzl_output}" "Starlark absolute path" +assert_match "_ios = " "${bzl_output}" "Starlark absolute path" -# Write to a relative path +# Write Go file to a relative path export BUILD_WORKSPACE_DIRECTORY="${output_dir}" -relative_path="foo/relative.go" -expected_output_path="${BUILD_WORKSPACE_DIRECTORY}/${relative_path}" -mkdir -p "$(dirname "${expected_output_path}")" -"${generate_builtin_frameworks_sh}" "${relative_path}" -[[ -e "${expected_output_path}" ]] || fail "Expected the output file for the relative path to exist." -assert_match "package swift" "${output}" -assert_match "var macosFrameworks =" "${output}" -assert_match "var iosFrameworks =" "${output}" +go_rel_path="foo/relative.go" +bzl_rel_path="foo/relative.bzl" +exp_go_output_path="${BUILD_WORKSPACE_DIRECTORY}/${go_rel_path}" +exp_bzl_output_path="${BUILD_WORKSPACE_DIRECTORY}/${bzl_rel_path}" +mkdir -p "$(dirname "${exp_go_output_path}")" +"${generate_builtin_frameworks_sh}" \ + --go_output "${go_rel_path}" \ + --bzl_output "${bzl_rel_path}" +[[ -e "${exp_go_output_path}" ]] || \ + fail "Expected the Go output file for the relative path to exist." +[[ -e "${exp_bzl_output_path}" ]] || \ + fail "Expected the Starlark output file for the relative path to exist." +go_output="$(< "${exp_go_output_path}")" +assert_match "package swift" "${go_output}" "Go relative path" +assert_match "var macosFrameworks =" "${go_output}" "Go relative path" +assert_match "var iosFrameworks =" "${go_output}" "Go relative path" +bzl_output="$(< "${exp_bzl_output_path}")" +assert_match "_macos = " "${bzl_output}" "Starlark relative path" +assert_match "_ios = " "${bzl_output}" "Starlark relative path"