-
Notifications
You must be signed in to change notification settings - Fork 61
Swift Package Manager distribution via prebuilt xcframework (iOS, macOS, Mac Catalyst, visionOS) #1486
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
Open
bmehta001
wants to merge
31
commits into
microsoft:main
Choose a base branch
from
bmehta001:bhamehta/spm-xcframework-prototype
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Swift Package Manager distribution via prebuilt xcframework (iOS, macOS, Mac Catalyst, visionOS) #1486
Changes from 7 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
0f3e065
Prototype: SPM distribution via prebuilt xcframework (Apple)
bmehta001 5e3687e
Prototype: SPM release workflow + parallel 3-component SemVer tag
bmehta001 ba7ba4c
Fix local SPM xcframework consumption
bmehta001 308e031
Copy only public ObjC headers into xcframework
bmehta001 dd97234
Align SPM package with xcframework contents
bmehta001 accb600
Generate SPM availability from xcframework build
bmehta001 4e03dff
Address SPM prototype review refinements
bmehta001 0edd5f1
Align Apple SPM docs and module availability
bmehta001 6d27fba
Add macOS slice to SPM xcframework
bmehta001 d242830
Add Mac Catalyst slice to SPM xcframework
bmehta001 1d89f6d
Add visionOS slices to SPM xcframework
bmehta001 0246847
Address SPM release review comments
bmehta001 9634894
Address follow-up SPM review comments
bmehta001 5923e5c
Validate SPM Apple platforms in release workflow
bmehta001 ccceaa5
Skip package creation for xcframework slices
bmehta001 5c6f574
Clean up Apple SPM README
bmehta001 79f55fa
Remove status label from Apple SPM README
bmehta001 27049fe
Assert SPM platforms in release workflow
bmehta001 55c4ce5
Clean up xcframework build script comments
bmehta001 9a18330
Use fresh build cache for each xcframework slice
bmehta001 279ffd3
Use portable shell comparison in iOS build
bmehta001 7bc7415
Quote ${IOS_PLAT}/${IOS_ARCH} in Apple if() conditions
bmehta001 9d52266
Rename public Clang module ObjCModule -> MATTelemetryObjC
bmehta001 2b5bdd5
docs(apple): note xcframework expects system sqlite3/zlib
bmehta001 f2c5fc9
Use PIIKind alias in SemanticContext.setUserID signature
bmehta001 06caea2
Fix SemanticContext.setUserID dropping the caller's piiKind
bmehta001 a57c2a1
Address Swift package review refinements
bmehta001 5d73b5d
Merge branch 'main' into bhamehta/spm-xcframework-prototype
bmehta001 3bc7555
Harden the SPM release pipeline: propagate build failures, don't clob…
bmehta001 2f2c7e1
SPM release: fail closed when the "already published" check is indete…
bmehta001 8dc6659
Report visionOS sysinfo distinctly in SPM builds
bmehta001 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| name: SPM release (xcframework) | ||
|
|
||
| # On a published SDK release, build MATTelemetry.xcframework, upload it to the | ||
| # GitHub Release, and publish a 3-component SemVer tag for Swift Package Manager | ||
| # whose Package.swift binaryTarget points at the uploaded artifact + checksum. | ||
| # | ||
| # Why a separate tag: the SDK's own release tags are 4-component (vX.Y.Z.W), | ||
| # which is NOT valid SemVer, so Swift Package Manager ignores them. This derives | ||
| # a 3-component tag (X.Y.Z) from the same release that SPM can resolve. | ||
| # | ||
| # Prerequisites: | ||
| # * The root Package.swift (the SPM manifest) must exist at the release tag | ||
| # (i.e. this prototype merged to main before the release is cut). | ||
| # * Uses the default GITHUB_TOKEN (needs contents: write). No extra secrets. | ||
|
|
||
| on: | ||
| release: | ||
| types: [published] | ||
| workflow_dispatch: | ||
| inputs: | ||
| tag: | ||
| description: "4-component release tag to publish for SPM (e.g. v3.10.161.1)" | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| concurrency: | ||
| group: spm-release-${{ github.event.release.tag_name || inputs.tag }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| spm: | ||
| name: Publish SPM xcframework + tag | ||
| # Skip drafts/pre-releases; always allow manual dispatch. | ||
| if: >- | ||
| ${{ github.event_name == 'workflow_dispatch' || | ||
| (github.event.release.draft == false && github.event.release.prerelease == false) }} | ||
| runs-on: macos-14 # provides Xcode (xcodebuild, swift) | ||
| env: | ||
| ARTIFACT: MATTelemetry.xcframework.zip | ||
| steps: | ||
| - name: Resolve tag and derive SPM version | ||
| id: ver | ||
| env: | ||
| # Pass untrusted tag values through the environment rather than | ||
| # interpolating ${{ ... }} into the script body. | ||
| RELEASE_TAG: ${{ github.event.release.tag_name }} | ||
| INPUT_TAG: ${{ inputs.tag }} | ||
| run: | | ||
| set -euo pipefail | ||
| TAG="${RELEASE_TAG:-$INPUT_TAG}" | ||
| if [ -z "$TAG" ]; then echo "::error::No release tag could be resolved."; exit 1; fi | ||
| # Only act on 4-component version tags vX.Y.Z.W. | ||
| if ! printf '%s' "$TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then | ||
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | ||
| echo "::error::Tag '$TAG' is not a 4-component version tag (expected vX.Y.Z.W)." | ||
| exit 1 | ||
| fi | ||
| echo "::notice::Tag '$TAG' is not a 4-component version tag; nothing to publish." | ||
| echo "skip=true" >> "$GITHUB_OUTPUT" | ||
| exit 0 | ||
| fi | ||
| VERSION="${TAG#v}" # X.Y.Z.W | ||
| SPM_VERSION="${VERSION%.*}" # X.Y.Z (drop the trailing build component) | ||
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | ||
| echo "spm_version=$SPM_VERSION" >> "$GITHUB_OUTPUT" | ||
| echo "Release $TAG -> SPM tag $SPM_VERSION" | ||
|
|
||
| - name: Checkout the release tag | ||
| if: ${{ steps.ver.outputs.skip != 'true' }} | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ steps.ver.outputs.tag }} | ||
| fetch-depth: 0 | ||
| # The private lib/modules submodule is intentionally NOT fetched; the | ||
| # xcframework ships the core SDK + Obj-C wrappers, matching the vcpkg | ||
| # port (the optional modules are excluded there too). | ||
| submodules: false | ||
|
|
||
| - name: Build MATTelemetry.xcframework | ||
| if: ${{ steps.ver.outputs.skip != 'true' }} | ||
| run: | | ||
| set -euo pipefail | ||
| chmod +x tools/apple/build-xcframework.sh | ||
| tools/apple/build-xcframework.sh release | ||
| test -f "build/apple/$ARTIFACT" | ||
|
|
||
| - name: Compute SPM checksum | ||
| id: sum | ||
| if: ${{ steps.ver.outputs.skip != 'true' }} | ||
| run: | | ||
| set -euo pipefail | ||
| echo "checksum=$(swift package compute-checksum "build/apple/$ARTIFACT")" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Upload xcframework to the release | ||
| if: ${{ steps.ver.outputs.skip != 'true' }} | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: gh release upload "${{ steps.ver.outputs.tag }}" "build/apple/$ARTIFACT" --clobber | ||
|
|
||
| - name: Point Package.swift at the released artifact | ||
| if: ${{ steps.ver.outputs.skip != 'true' }} | ||
| env: | ||
| ASSET_URL: https://github.com/${{ github.repository }}/releases/download/${{ steps.ver.outputs.tag }}/MATTelemetry.xcframework.zip | ||
| CHECKSUM: ${{ steps.sum.outputs.checksum }} | ||
| run: | | ||
| set -euo pipefail | ||
| python3 - "$ASSET_URL" "$CHECKSUM" <<'PY' | ||
| import re, sys | ||
| url, checksum = sys.argv[1], sys.argv[2] | ||
| path = "Package.swift" | ||
| src = open(path).read() | ||
| repl = ( | ||
| '.binaryTarget(\n' | ||
| ' name: "MATTelemetry",\n' | ||
| f' url: "{url}",\n' | ||
| f' checksum: "{checksum}")' | ||
| ) | ||
| out = re.sub( | ||
| r'\.binaryTarget\(\s*name:\s*"MATTelemetry",\s*path:\s*"[^"]*"\s*\)', | ||
| repl, src, count=1) | ||
| assert out != src, "binaryTarget(path:) block not found in Package.swift" | ||
| open(path, "w").write(out) | ||
| PY | ||
|
|
||
| - name: Commit manifest and push the 3-component SPM tag | ||
| if: ${{ steps.ver.outputs.skip != 'true' }} | ||
| run: | | ||
| set -euo pipefail | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add Package.swift tools/apple/MATTelemetryAvailability.json | ||
| git commit -m "[spm] ${{ steps.ver.outputs.spm_version }}: pin xcframework url + checksum" | ||
| # The SPM tag points at this commit (release source + resolved | ||
| # binaryTarget). It is published as a tag only, not merged to a branch. | ||
| git tag -a "${{ steps.ver.outputs.spm_version }}" \ | ||
| -m "Swift Package Manager release ${{ steps.ver.outputs.spm_version }} (from ${{ steps.ver.outputs.tag }})" | ||
| git push origin "refs/tags/${{ steps.ver.outputs.spm_version }}" | ||
|
bmehta001 marked this conversation as resolved.
|
||
| echo "Published SPM tag ${{ steps.ver.outputs.spm_version }}" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| // swift-tools-version: 5.9 | ||
| // | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
| // Swift Package Manager manifest for the 1DS C++ SDK (Microsoft Applications | ||
| // Telemetry) on Apple platforms. | ||
| // | ||
| // PROTOTYPE — distribution model: | ||
| // * The compiled C++ core + Obj-C wrappers ship as a prebuilt binary | ||
| // xcframework (built by tools/apple/build-xcframework.sh). This avoids | ||
| // compiling the CMake/Bond/sqlite/zlib C++ tree through SPM, which is not | ||
| // practical. | ||
| // * The thin Swift wrapper (wrappers/swift/Sources/OneDSSwift) is compiled | ||
| // from source on top of the Obj-C module vended by the xcframework. | ||
| // | ||
| // Local development: | ||
| // 1. Run `tools/apple/build-xcframework.sh release` on macOS with Xcode. | ||
| // It produces ./build/apple/MATTelemetry.xcframework. | ||
| // 2. `swift build` (or add this package as a local dependency). | ||
| // | ||
| // Release distribution (so consumers can add the repo by URL in Xcode): | ||
| // 1. Build the xcframework, zip it, and attach it to the GitHub Release. | ||
| // 2. Run `swift package compute-checksum MATTelemetry.xcframework.zip`. | ||
| // 3. Replace the `.binaryTarget(... path:)` below with the `url:`+`checksum:` | ||
| // form shown in the comment. The vcpkg-release-bump workflow pattern can be | ||
| // extended to automate steps 1-3 on each release tag. | ||
|
bmehta001 marked this conversation as resolved.
Outdated
|
||
|
|
||
| import PackageDescription | ||
| import Foundation | ||
|
|
||
| let packageDirectory = URL(fileURLWithPath: #filePath).deletingLastPathComponent() | ||
|
|
||
| func readAvailability() -> [String: Bool] { | ||
| let candidates = [ | ||
| "build/apple/MATTelemetryAvailability.json", | ||
| "tools/apple/MATTelemetryAvailability.json", | ||
| ] | ||
|
|
||
| for relativePath in candidates { | ||
| let url = packageDirectory.appendingPathComponent(relativePath).standardizedFileURL | ||
| guard let data = try? Data(contentsOf: url), | ||
| let object = try? JSONSerialization.jsonObject(with: data) as? [String: Bool] else { | ||
| continue | ||
| } | ||
| return object | ||
| } | ||
|
|
||
| return [:] | ||
| } | ||
|
|
||
| let availability = readAvailability() | ||
| let hasDiagnosticDataViewer = availability["diagnosticDataViewer"] ?? false | ||
| let hasPrivacyGuard = availability["privacyGuard"] ?? false | ||
| let hasSanitizer = availability["sanitizer"] ?? false | ||
|
|
||
| var excludedSources: [String] = [] | ||
| var swiftSettings: [SwiftSetting] = [] | ||
|
|
||
| if !hasDiagnosticDataViewer { | ||
| excludedSources.append("DiagnosticDataViewer.swift") | ||
| } | ||
|
|
||
| if hasPrivacyGuard { | ||
| swiftSettings.append(.define("MATSDK_PRIVACYGUARD_AVAILABLE")) | ||
| } else { | ||
| excludedSources.append(contentsOf: [ | ||
| "CommonDataContext.swift", | ||
| "PrivacyGuard.swift", | ||
| "PrivacyGuardInitConfig.swift", | ||
| ]) | ||
|
bmehta001 marked this conversation as resolved.
|
||
| } | ||
|
|
||
| if !hasSanitizer { | ||
| excludedSources.append(contentsOf: [ | ||
| "Sanitizer.swift", | ||
| "SanitizerInitConfig.swift", | ||
| ]) | ||
| } | ||
|
|
||
| let package = Package( | ||
| name: "OneDSSwift", | ||
| platforms: [ | ||
| .iOS(.v12), | ||
| ], | ||
|
bmehta001 marked this conversation as resolved.
bmehta001 marked this conversation as resolved.
bmehta001 marked this conversation as resolved.
bmehta001 marked this conversation as resolved.
|
||
| products: [ | ||
| .library(name: "OneDSSwift", targets: ["OneDSSwift"]), | ||
| ], | ||
| targets: [ | ||
| // Prebuilt C++ core + Obj-C wrappers. The xcframework's bundled | ||
| // module map vends the Clang module `ObjCModule` (see | ||
| // tools/apple/module.modulemap), which the Swift layer imports. | ||
| // | ||
| // For a tagged release, swap the local path for the hosted artifact: | ||
| // | ||
| // .binaryTarget( | ||
| // name: "MATTelemetry", | ||
| // url: "https://github.com/microsoft/cpp_client_telemetry/releases/download/v3.10.161.1/MATTelemetry.xcframework.zip", | ||
| // checksum: "<output of swift package compute-checksum>"), | ||
| .binaryTarget( | ||
| name: "MATTelemetry", | ||
| path: "build/apple/MATTelemetry.xcframework"), | ||
|
|
||
| // Thin Swift API layer (source). Depends on the Obj-C module from the | ||
| // xcframework. NOTE: the conditional source exclusions in | ||
| // wrappers/swift/Package.swift (PrivacyGuard / Sanitizer / DataViewer | ||
| // when those private modules aren't built) should be carried over here | ||
| // and kept in sync with the headers baked into the xcframework. | ||
|
bmehta001 marked this conversation as resolved.
Outdated
|
||
| .target( | ||
| name: "OneDSSwift", | ||
| dependencies: ["MATTelemetry"], | ||
| path: "wrappers/swift/Sources/OneDSSwift", | ||
| exclude: excludedSources, | ||
| swiftSettings: swiftSettings, | ||
| linkerSettings: [ | ||
| .linkedLibrary("c++"), | ||
| .linkedLibrary("sqlite3"), | ||
| .linkedLibrary("z"), | ||
| .linkedFramework("CFNetwork", .when(platforms: [.iOS])), | ||
| .linkedFramework("CoreFoundation", .when(platforms: [.iOS])), | ||
| .linkedFramework("Foundation", .when(platforms: [.iOS])), | ||
| .linkedFramework("Network", .when(platforms: [.iOS])), | ||
| .linkedFramework("SystemConfiguration", .when(platforms: [.iOS])), | ||
| .linkedFramework("UIKit", .when(platforms: [.iOS])), | ||
| ]), | ||
| ] | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
| // Umbrella header for the Obj-C surface vended by MATTelemetry.xcframework. | ||
| // | ||
| // build-xcframework.sh flattens the ODW*.h headers into the framework's | ||
| // Headers/ directory, so these are imported by bare name (not by the | ||
| // ../../obj-c/ relative path the in-repo Swift bridging header uses). | ||
| // | ||
| // This template intentionally lists only always-available Obj-C headers. | ||
| // build-xcframework.sh appends imports for optional module headers only when | ||
| // those modules were actually built into the binary. | ||
|
|
||
| #import <Foundation/Foundation.h> | ||
|
|
||
| #import "ODWCommonDataContext.h" | ||
| #import "ODWEventProperties.h" | ||
| #import "ODWLogConfiguration.h" | ||
| #import "ODWLogger.h" | ||
| #import "ODWLogManager.h" | ||
| #import "ODWPrivacyGuardInitConfig.h" | ||
| #import "ODWSanitizerInitConfig.h" | ||
| #import "ODWSemanticContext.h" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "diagnosticDataViewer": false, | ||
| "privacyGuard": false, | ||
| "sanitizer": false | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Swift Package Manager (xcframework) — prototype | ||
|
|
||
| **Status: prototype / not yet validated on macOS.** This is a first-pass scaffold | ||
| for distributing the 1DS C++ SDK to Apple app developers via **Swift Package | ||
| Manager (SPM)**, the successor to CocoaPods (the CocoaPods trunk goes read-only | ||
| on 2 Dec 2026, and there is no official in-repo podspec today). | ||
|
bmehta001 marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Approach | ||
|
|
||
| SPM cannot practically compile this SDK's C++ tree from source (CMake build, | ||
| Bond codegen, vendored sqlite3/zlib, heavy platform conditionals). So: | ||
|
|
||
| | Layer | How it ships | | ||
| | --- | --- | | ||
| | C++ core + Obj-C wrappers (`ODW*`) | **Prebuilt binary** — `MATTelemetry.xcframework` (`.binaryTarget`) | | ||
| | Swift API (`OneDSSwift`) | **Source** — `wrappers/swift/Sources/OneDSSwift`, depends on the Obj-C module from the xcframework | | ||
|
|
||
| The Obj-C wrappers already compile into `libmat.a` on Apple | ||
| (`lib/CMakeLists.txt:217`), and the Swift sources already `import ObjCModule`, | ||
| so the xcframework just needs to vend a Clang module named `ObjCModule` | ||
| (`tools/apple/module.modulemap` + `MATTelemetry-umbrella.h`). | ||
|
|
||
| ## Files | ||
|
|
||
| | File | Purpose | | ||
| | --- | --- | | ||
| | `Package.swift` (repo root) | Distributable SPM manifest: `binaryTarget` (xcframework) + `OneDSSwift` source target | | ||
| | `tools/apple/build-xcframework.sh` | Builds a static `libmat.a` per Apple slice via `build-ios.sh`, lipo's the simulator archs, and assembles the xcframework with `xcodebuild -create-xcframework` | | ||
| | `tools/apple/module.modulemap` | Defines the `ObjCModule` Clang module the Swift layer imports | | ||
| | `tools/apple/MATTelemetry-umbrella.h` | Umbrella over the `ODW*.h` headers baked into the xcframework | | ||
|
|
||
| ## Build (on macOS) | ||
|
|
||
| ```bash | ||
| tools/apple/build-xcframework.sh release | ||
| # -> build/apple/MATTelemetry.xcframework | ||
| # -> build/apple/MATTelemetry.xcframework.zip (+ prints the SPM checksum) | ||
| swift build # resolves Package.swift against the local xcframework | ||
| ``` | ||
|
|
||
| ## Consume | ||
|
|
||
| - **Local:** point a sample app at this package directory (path dependency). | ||
| - **Released:** in Xcode *File -> Add Package Dependencies...*, enter the repo | ||
| URL and pick a version. SPM only accepts **3-component SemVer**, and the SDK's | ||
| own `vX.Y.Z.W` tags are not valid SemVer, so consumers pin the **parallel | ||
| 3-component tag** the release workflow publishes: | ||
|
|
||
| ```swift | ||
| .package(url: "https://github.com/microsoft/cpp_client_telemetry.git", from: "3.10.161") | ||
| ``` | ||
|
|
||
| ## Release wiring | ||
|
|
||
| `.github/workflows/spm-release.yml` automates distribution on each published | ||
| release (a 4-component `vX.Y.Z.W` tag). On a macOS runner it: | ||
|
|
||
| 1. Builds `MATTelemetry.xcframework` and zips it. | ||
| 2. Uploads the zip to the GitHub Release. | ||
| 3. Computes the SPM checksum and rewrites the `Package.swift` `binaryTarget` | ||
| from `path:` to `url:`+`checksum:`. | ||
| 4. Commits that manifest and pushes a **3-component SemVer tag** (`X.Y.Z`, | ||
| derived by dropping the trailing build component) that SPM can resolve. | ||
|
|
||
| This mirrors the `vcpkg-release-bump` workflow. It requires the root | ||
| `Package.swift` to already exist at the release tag (i.e. this prototype merged | ||
| before the release is cut). | ||
|
|
||
| ## Known gaps / TODO (validate on macOS) | ||
|
|
||
| - **macOS / Catalyst / visionOS slices** — only iOS device + simulator are wired | ||
| up in this first pass; add the macOS slice (see section 3 of the script). | ||
| - **Conditional modules** — carry over the `moduleExists()` source exclusions | ||
| from `wrappers/swift/Package.swift` (PrivacyGuard / Sanitizer / DataViewer) and | ||
| keep the umbrella header in sync with the headers actually built. | ||
| - **Header flattening** — confirm the `ODW*.h` headers reference each other by | ||
| bare name in the flattened `Headers/` layout (adjust the copy step if not). | ||
| - **Static-lib path** — verify `out/lib/libmat.a` is the actual artifact name and | ||
| that `-DBUILD_SHARED_LIBS=OFF` yields a static archive for every slice. | ||
| - **Code signing** — release xcframeworks are typically signed; add a signing | ||
| step before zipping for distribution. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.