Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Swift Package Manager binaryTarget by providing xcframework in a release #6564

Closed
ollieatkinson opened this issue Sep 25, 2020 · 53 comments · Fixed by #11066
Closed
Assignees
Labels
api: firestore macOS Issues or feature requests for macOS. Swift Package Manager type: feature request zip-builder Tools related to building the zip file.
Milestone

Comments

@ollieatkinson
Copy link

ollieatkinson commented Sep 25, 2020

Feature proposal

  • Firebase Component: All

Swift Package Manager support is great and has enabled a much easier integration with many projects which use Firebase, however this comes at a cost of having each developer to compile all of the sources. Swift Package Manager added support for binaryTarget dependencies and from looking at https://github.com/firebase/firebase-ios-sdk/tree/master/ZipBuilder you've already made a start on this but is still lacking things like x86_64 support.

I am raising this as it will likely save hundreds if not thousands of hours of developers time in due course.

@google-oss-bot
Copy link

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.
@paulb777
Copy link
Member

paulb777 commented Sep 25, 2020

@ollieatkinson Thanks for the request. We've thought about a complete binary distribution and will continue to evaluate. However, we have no plans beyond Analytics in the near-term for the following reasons:

  • We're focused on completing a successful beta of the primarily source SPM distribution
  • The SPM binary implementation is still immature with major bugs and usability issues. Browse the issues here for examples
  • Providing platform and version coverage with a binary distribution is much more challenging than a source distribution
  • We're considering the alternative of improving this ZipBuilder tool so that it's easy for developers to create the binaries that they need
@paulb777 paulb777 changed the title Support for Swift Package Manager binaryTarget by providing xccframework in a release Sep 29, 2020
@ollieatkinson
Copy link
Author

We're considering the alternative of improving this ZipBuilder tool so that it's easy for developers to create the binaries that they need

This would be hugely enabling! Please let me know if you are willing to accept community support and provide some instruction to do so.

I think another useful outcome of this would be that ZipBuilder will support building x86_64 macOS (for the set of frameworks which you already support)

@paulb777
Copy link
Member

paulb777 commented Oct 5, 2020

We're definitely willing to accept community support. In fact, a large part of the Catalyst support came from @steipete in the community.

Instructions for getting started are at https://github.com/firebase/firebase-ios-sdk/tree/master/ZipBuilder.

We'll be happy to answer any questions and provide additional feedback and guidance on issues and PRs here.

@ollieatkinson
Copy link
Author

ollieatkinson commented Oct 6, 2020

Thanks!

From my initial investigation it seems we need to rephrase FrameworkBuilder and how it is managing it's architectures since x86_64 can mean macOS platform as well as iOS simulator platform.

When I've generated xcframeworks in the past I have specified the destination parameter to xcodebuild , do you think this is something that ZipBuilder should use? Currently you specify -arch instead.

xcodebuild archive \
..
-destination destination="generic/platform=iOS"
..
struct Destination {
    
    struct Platform: RawRepresentable {
        let rawValue: String
        static let macOS = Platform(rawValue: "platform=macOS")
        static let iOS = Platform(rawValue: "generic/platform=iOS")
        static let iOS_Simulator = Platform(rawValue: "generic/platform=iOS Simulator")
        static let watchOS = Platform(rawValue: "generic/platform=watchOS")
        static let watchOS_Simulator = Platform(rawValue: "generic/platform=watchOS Simulator")
        static let tvOS = Platform(rawValue: "generic/platform=tvOS")
        static let tvOS_Simulator = Platform(rawValue: "generic/platform=tvOS Simulator")
    }
    
    struct Variant: RawRepresentable {
        let rawValue: String
        static let catalyst = Variant(rawValue: "variant=Mac Catalyst")
    }

    let isMacCayalyst: Bool
    let string: String
    
    init(platform: Platform) {
        isMacCayalyst = false
        string = platform.rawValue
    }
    
    init(platform: Platform, variant: Variant) {
        isMacCayalyst = variant == .catalyst
        string = [platform.rawValue, variant.rawValue].joined(separator: ",")
    }

}
@paulb777
Copy link
Member

paulb777 commented Oct 6, 2020

It looks like we're currently using -sdk combined with ARCHS. -destination could be a cleaner implementation.

@ryanwilson ryanwilson added macOS Issues or feature requests for macOS. zip-builder Tools related to building the zip file. labels Nov 6, 2020
@mikehardy
Copy link
Contributor

mikehardy commented Jan 6, 2021

I'm looking at this while investigating a response to a request in our "pre-compiled Firestore framework" repo: invertase/firestore-ios-sdk-frameworks#19

It looks like we could maybe provide an SPM version of the compiled Firestore framework as well, based on this issue, by using ZipBuilder? Perhaps with SSL collision errors though (#6869)

It appears ZipBuilder has moved to here (a couple directories deeper): https://github.com/firebase/firebase-ios-sdk/tree/master/ReleaseTooling/Sources/ZipBuilder if I am looking at the correct thing?

Related (and more about how ZipBuilder works) I am working on re-packaging the binary release of an iOS SDK from previous .framework with one fat library (fails on Apple Silicon simulators with arm64 slice collision as you all clearly know) to a modern .xcframework and adding in all the flavors (catalyst, tvos etc) while I'm there. It's all working now after quite a few different tests to get there.

During the work I consulted your ZipBuilder and to @ollieatkinson's point I think destination is more precise than combination of sdk and ARCH. Most specifically, I tried the sdk macosx used in your binary catalyst builds from ZipBuilder in my build for catalyst and it actually brings in other symbols (e.g. AppKit vs UIKit) vs the destination that Apple appears to bless (and which worked for me compile+runtime demo, since we use UIKit symbols): -destination='platform=macOS,arch=x86_64,variant=Mac Catalyst'

So I'd consider moving to destination unless I'm missing something. Allows you to remove ARCHes entirely in my experience (I end up with the same ARCH skew in my .xcframework that ZipBuilder specifies explicitly, but I get it with nothing specified - xcodebuild automatically generated the fat multi-arch-per-flavor frameworks)

Not sure what I'll do with regard to SPM support for the pre-compiled framework given status here - probably have to let that sit pending a community contribution as it appears pretty bleeding edge w.r.t. what's possible

Cheers

@paulb777
Copy link
Member

paulb777 commented Jan 6, 2021

@mikehardy It's definitely possible to do build xcframeworks with the ZipBuilder and that's how we build Analytics for Swift Package Manager. However, as I noted above, SPM is still hard to use with binaries. See especially #6472. The combination of Firestore and its dependencies would exacerbate the difficulty of working around the usability issues.

Despite these difficulties, it may all be solvable with additional tooling and we'll be happy to help you continue down the path.

Also we're soon planning to merge a refactor of the ZipBuilder that simplifies the options and adds macOS/tvOS support. See #7221

@mikehardy
Copy link
Contributor

mikehardy commented Jan 6, 2021

Cool re: support for other platforms, it appears that despite it being fairly bleeding on all edges react-native (via firebase at SDK level, then react-native / react-native-firebase) is going to have a much larger platform reach with modern app dev facilities mainstream shortly. I suppose FlutterFire will be quite excited as well

For the SPM firestore binary distribution idea I said effectively the same thing as I carried it back to the issue in our repo: I highlighted there were some hurdles to clear but that the team here is quite collaborative and would likely welcome any contributed effort to get it done. It's not a priority for me/us as maintainers but similarly we'd happily merge anything needed in the pre-compiled framework repo

@mikehardy
Copy link
Contributor

Just a note - I think I need to retract a statement here:

During the work I consulted your ZipBuilder and to @ollieatkinson's point I think destination is more precise than combination of sdk and ARCH. Most specifically, I tried the sdk macosx used in your binary catalyst builds from ZipBuilder in my build for catalyst and it actually brings in other symbols (e.g. AppKit vs UIKit) vs the destination that Apple appears to bless (and which worked for me compile+runtime demo, since we use UIKit symbols): -destination='platform=macOS,arch=x86_64,variant=Mac Catalyst'

I have continued testing different combinations of destination and sdk arguments for xcodebuild command line and @ollieatkinson I am not able to make 'destination' work correctly on Xcode12.3 with destination alone for most targets. For catalyst build it appears the special destination argument we've been using works without sdk specified but for other targets (at minimum ios, ios simulator) the sdk by itself is sufficient, sdk + destination works, but destination alone does not.

So in my testing there is no way to rely on destination alone. I'm still learning xcodebuild so if I'm missing something I'd love pointers to examples that work, but I didn't want to let that comment stand in case someone else based work on it. Cheers

@ollieatkinson
Copy link
Author

ollieatkinson commented Jan 8, 2021

Do you have some examples for what's not working?
Currently, I am able to build a vanilla project using the destination specifier:

xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=iOS" -archivePath archive/iOS BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=iOS Simulator" -archivePath archive/iOS-Simulator BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=tvOS" -archivePath archive/tvOS BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=tvOS Simulator" -archivePath archive/tvOS-Simulator BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=watchOS" -archivePath archive/watchOS BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=watchOS Simulator" -archivePath archive/watchOS-Simulator BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=macOS,name=Any Mac" -archivePath archive/macOS BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild archive -project example.xcodeproj -scheme example -destination "generic/platform=macOS,variant=Mac Catalyst" -archivePath archive/macOS-Catalyst BUILD_LIBRARY_FOR_DISTRIBUTION=YES SKIP_INSTALL=NO
xcodebuild -create-xcframework \
	-framework archive/iOS.xcarchive/Products/Library/Frameworks/example.framework \
	-framework archive/iOS-Simulator.xcarchive/Products/Library/Frameworks/example.framework \
	-framework archive/tvOS.xcarchive/Products/Library/Frameworks/example.framework \
	-framework archive/tvOS-Simulator.xcarchive/Products/Library/Frameworks/example.framework \
	-framework archive/watchOS.xcarchive/Products/Library/Frameworks/example.framework \
	-framework archive/watchOS-Simulator.xcarchive/Products/Library/Frameworks/example.framework \
	-framework archive/macOS.xcarchive/Products/Library/Frameworks/example.framework \
	-framework archive/macOS-Catalyst.xcarchive/Products/Library/Frameworks/example.framework \
	-output example.xcframework

xcframework successfully written out to: example.xcframework

ll example.xcframework
drwxr-xr-x oliver wheel 352 B  Fri Jan  8 10:15:17 2021 .
drwxr-xr-x oliver wheel 224 B  Fri Jan  8 10:15:17 2021 ..
.rw-r--r-- oliver wheel 3.1 KB Fri Jan  8 10:15:17 2021 Info.plist
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 ios-arm64
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 ios-arm64_x86_64-maccatalyst
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 ios-arm64_x86_64-simulator
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 macos-arm64_x86_64
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 tvos-arm64
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 tvos-arm64_x86_64-simulator
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 watchos-arm64_32_armv7k
drwxr-xr-x oliver wheel  96 B  Fri Jan  8 10:15:17 2021 watchos-arm64_x86_64-simulator
@mikehardy
Copy link
Contributor

mikehardy commented Jan 8, 2021

Not sure why, but when I did that without specifying sdk for the iphone builds, it was attempting to compile it catalyst style (I was receiving API warnings about things not available for catalyst or deprecated in catalyst whereas I would not receive those during an -sdk iphoneos build) using the exact destination you propose. At the same time / conversely, if I specify sdk during the catalyst destination builds catalyst compiles incorrectly (it generates binaries lipo will tell you are for iphone and -create-xcframework complains of duplicatation). Perhaps your SDK API usage does not have any availability differences between macOS Catalyst API set and iphoneos API set?

I had a separate issue bringing the macos target in where it built but left the thing in DerivedData/.../UninstalledProducts and did not actually drop it in the specified archivePath, which was quite odd given #? was 0, and especially as -create-xcframework after would work if I copied contents into the expected structure in the specified archivePath.

In the end I have a real library with real functionality working with a directory result (and verified correct xcframework/Info.plist) as you demonstrate but it wasn't nearly so clean producing it 🤷

This is still an active area of research for me, I'll see if I can isolate something, I appreciate the extra info

@paulb777
Copy link
Member

paulb777 commented May 6, 2021

@mikehardy Any more updates on this? Perhaps it might be worthwhile to chat about binary distribution directions? Let me know.

@mikehardy
Copy link
Contributor

@paulb777 not going to name names but someone (coughfirebase-ios-sdkcoughfirebase-android-sdk*) just released a bunch of breaking changes and new functionality (how dare they!?) and I'm on a personal crusade to ingest them before Google I/O when everyone will be all excited and check out the repo(s). So this is still on my radar but will probably be another week or so - cheers

@mikehardy
Copy link
Contributor

Okay @paulb777 so I had a moment and read through this issue and the linked one in firestore-ios-sdk-frameworks, and I'm curious what you're thinking.

To me it seems a tad silly to have a repo (ours) downstream that does nothing but run a scheduled job that pulls the ZipBuilder artifacts you produce / own / already know about) only to generate a new Cocoapod podspec that refers to some internal chunk of the zip - but is a neat hack and does save people time as a pod dependency.

To add to that odd-seeming (but useful!) 3rd party hack by also layering a Package.swift file with binaryTarget on there to reference the same (but possibly re-processed slightly) internal binary chunk that you own here seems like it would definitely work, but also be better as an official SPM endpoint here, just as ideally there would be a FirebaseFirestore-binary.podspec here (just making the name up).

So I think for the SPM crowd that just wants faster compile we could integrate a new Package.swift in firestore-ios-sdk-frameworks, but if this repo did pre-compiled frameworks officially it would seem more coherent.

Can set up a real time chat if you like - but I would have needed to do this re-read / re-think as prep anyway. You can email my github address if you like or just send a meeting invite for anytime about 9-11a your time (my old home Alameda? I used to live there!) on a weekday and I'm probably available.

Cheers!

@paulb777
Copy link
Member

Sounds good. I proposed a meeting for tomorrow.

Agreed about the hackiness and I wanted to take a step back and discuss binary distributions in general and ideally better align them.

@schlingding
Copy link

Are there any updates for supporting Firebase SPM as Binary targets?

In about 8 hours or so I implemented this myself with trial and error using the XCFrameworks downloaded from the Firebase site. The XCFrameworks zipped up need to be hosted which is less than ideal. Any framework specific resources still need to be added such as gRPCCertificates-Cpp.bundle.

Compile and run time is a HUGE difference. Using the Firebase binaries with SPM I can compile in less than a minute. Using the current Firebase SPM as provided, Xcode will churn for up to 30 minutes after any clean build.

@paulb777
Copy link
Member

My perception is that build time is only an issue for Firestore. The rest of Firebase builds reasonably fast and it wouldn't be worth the complexity and reduced stability of SPM binary target support.

Given that, we can potentially consider a SPM variation of https://github.com/invertase/firestore-ios-sdk-frameworks that provides a binary Firestore SPM distribution and integrates with the rest of the Firebase source SPM distribution.

@kikettas
Copy link

kikettas commented Oct 6, 2021

Great to hear that @paulb777. Do you know if that is something happening in the short term?

@paulb777
Copy link
Member

paulb777 commented Oct 6, 2021

There is some ongoing discussion, but no concrete plans yet.

@maxime-day
Copy link

@paulb777 Any update on the subject ? It really takes a long time to build. 30secs or 1 minute is quite an issue on the long term.

@jesus-mg-ios
Copy link

is this https://github.com/akaffenberger/firebase-ios-sdk-xcframeworks going to be hosted by Firebase? I mean I think is the best option, and should be supported by firebase

@paulb777
Copy link
Member

We haven't yet decided to directly support binary distributions via SPM, but if we do, we'll host the binaries.

Note that we already do distribute binary xcframeworks via the Carthage distribution.

@arielelkin
Copy link

@paulb777 what's the added value for developers who use Firebase to build Firebase from source? It involves:

  • Fetching a dozen dependencies (takes 120 seconds on average)
  • Building a dozen different targets (takes 50 seconds from clean to compile hundreds of source files)

This would make sense if most developers were interested in inspecting or debugging the Firebase code, but I suspect that's a tiny fraction of us. Feels like the rest of us waste a lot of computing time by constantly building from source instead of using precompiled binaries. In fact that's the default in Carthage, which you support. Why can't it also be the default in SPM?

@jesus-mg-ios
Copy link

jesus-mg-ios commented Nov 25, 2022

@paulb777 , thanks for your reply.
It's truth and before I was using Carthage, but the last update was on May 8, 2021, no active contributors, it's not the Apple standard and it has lots of problems managing dependencies because the lack of contribution.

I think that's my point of view and the point in which lots of developers are.
Even (with this SDK using SPM) the timings that wrote down @arielelkin are very optimistic ...

@paulb777
Copy link
Member

We're adding this feature request to the active backlog. Most likely a first solution will be Firestore only.

@jesus-mg-ios
Copy link

Any updates about when is it planned to be developed?

@unxavi
Copy link

unxavi commented Jan 4, 2023

@paulb777 hope you had happy holidays, do you happen to have any news?

@ncooke3
Copy link
Member

ncooke3 commented Jan 5, 2023

Hi everyone! No updates to share right now, but I should have something within the next few weeks.

@jesus-mg-ios
Copy link

Hi @ncooke3:
I've seen you made some tests on repos. Am I right? Any estimated delivery date for this?

Thanks in advance

@ncooke3
Copy link
Member

ncooke3 commented Feb 16, 2023

Hi @jesus-mg-ios, yes– I have been exploring several solutions. I do not have an ETA to share yet. We are actively working on this and I'll share more info when things are more finalized. Thanks for your patience!

@casperriboe
Copy link

Some interesting new features and fixes just released with the new Xcode 14.3 beta. Particularly this one among other noteworthy:

Binary targets can now directly be vended as products without requiring the declaration of an additional source target. (101096803)

@unxavi
Copy link

unxavi commented Mar 6, 2023

@ncooke3 I had some question on how is the progress going and why aren't you using this approach https://github.com/akaffenberger/firebase-ios-sdk-xcframeworks ? do you see any possible issues with this approach?

Thanks

@ncooke3
Copy link
Member

ncooke3 commented Mar 9, 2023

Hi @unxavi, I don't see any major issues with using SPM binary targets. Firebase Analytics has been released as a binary target for as long as Firebase has supported SPM. And, after various experiments, we'll be moving forward with this approach of releasing Firestore as a binary target. Since my last update, we have been preparing for this. I don't have a release date to share yet, but will update this thread when the remaining details have been settled. Thanks again for your patience everyone!

@xmollv
Copy link

xmollv commented Mar 21, 2023

@ncooke3 Any updates? Firebase it's getting to a point where's it's becoming a PITA to work with. I've just did the migration from Cocoapods to SPM and it takes 10 minutes to download Firebase related stuff via SPM 🥲

e033bd8a95830a68

@ncooke3
Copy link
Member

ncooke3 commented Mar 21, 2023

Sorry @xmollv, we are currently ironing out the details for how we will distribute and version each of Firestore's large C++ dependencies as binaries. I don't have an eta to share yet, so please continue to be patient until I have one to share. Thanks again everyone for your patience–– I'll share an update at the end of the week with where we are at then.

@ncooke3
Copy link
Member

ncooke3 commented Mar 29, 2023

Hi everyone, I just want to let everyone know that I'm actively working on the final stages of wiring everything up. I can't share a release date yet, but please know we are getting close. As always, thanks everyone for your patience! 🙂

@ncooke3
Copy link
Member

ncooke3 commented Apr 5, 2023

Hi everyone, I'm happy to say that this feature is expected to roll out in the next release (est. week of 4/11). In terms of what to expect, you should see a speed up in the time it takes to add/resolve the Firebase package as well as the time it takes to build Firestore.

@ncooke3 ncooke3 closed this as completed Apr 5, 2023
@ncooke3
Copy link
Member

ncooke3 commented Apr 11, 2023

Hey everyone– Firebase 10.8.0 was just released and includes this feature! If you run into any issues, please open an issue. Additionally, feel free to share any feedback in this thread. Thanks again everyone! 🚀

@unxavi
Copy link

unxavi commented Apr 11, 2023

@ncooke3 great! is there any plan to include additional frameworks like Functions, Crashlytics, Storage or others in the near future?

@ncooke3
Copy link
Member

ncooke3 commented Apr 11, 2023

@unxavi –– there are no current plans to release other products as binary targets, but we are open to your feedback. Firestore's large codebase and dependency on other large codebases made it a great candidate for swapping its release distro from source to binary. Other Firebase products are comparatively much smaller and might not provide as much of a benefit. But, again, we're always open to feedback and feature requests. 🙂

@Sherlouk
Copy link

Considering the initial scope of this issue was all components, I feel it may be best to keep this issue open to track progress on further products (or perhaps we need to break out a new issue for each product/internal module?)

I did want to share some data from our Grafana dashboard which monitors the clean build times of every module (as reported by Xcode's build logs). This is based on 100s of samples across the past few weeks.

image
image

I believe all of the above are direct dependencies on the Firebase project, and for us (even if these products are "comparatively much smaller") still contribute massively to our project's build times. It still feels like there's a lot of value to be gained here by exploring pre-compiling of other parts of the codebase.


Just on a separate note too, it does not look like the projects use of binary targets is documented - perhaps it's worth updating this SPM doc to explain this for future reference?

@jesus-mg-ios
Copy link

jesus-mg-ios commented Apr 12, 2023

#11104 issue ticket to push for the "feature"

@paulb777
Copy link
Member

@Sherlouk Thanks for sharing the measurements. I would like to better understand the mechanics of how the measurements are made. For example the Firebase target is little more than a header file. How could it take over a minute?

For those asking about documenting the use of binary targets. What is the reason for that? The docs are intended to be usage instructions and how does the use of binary or source impact the usage?

@Sherlouk
Copy link

I would like to better understand the mechanics of how the measurements are made

Data is collected and persisted by XCMetrics which extracts data from XCLogParser and visualised in Grafana. I cannot speak to the reason for any given time, that's simply what the Xcode build logs state.

These metrics are all from our CI environment which uses 2019 Intel Mac Minis with upgraded memory. All CI builds are clean (so no incremental numbers).

I would say that I don't look at the numbers religiously, but rather use them to compare to other dependencies within our products. This allows us to see that Firebase contributes a large number of modules (where we don't currently visualise the linking time but know it's not a small number) but also that relatively speaking it's one of the heavier dependencies.

how does the use of binary or source impact the usage?

For me, it's understanding rationale/context (i.e. linking to this issue) and also future progression towards increasing scope of coverage (i.e. making it as quick and easy as possible to understand which products require compiling source code vs those which are pre-compiled and ready to go).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api: firestore macOS Issues or feature requests for macOS. Swift Package Manager type: feature request zip-builder Tools related to building the zip file.