Skip to content

rollback(spm): conditional min. OS versions for Xcode 27 - #16443

Merged
ncooke3 merged 4 commits into
mainfrom
nc.reverts
Jul 23, 2026
Merged

rollback(spm): conditional min. OS versions for Xcode 27#16443
ncooke3 merged 4 commits into
mainfrom
nc.reverts

Conversation

@ncooke3

@ncooke3 ncooke3 commented Jul 23, 2026

Copy link
Copy Markdown
Member

Xcode 27 betas have enforced Xcode's minimum deployment targets. We were able to reproduce this on CI, and responded by updating the Package.swift to conditionally compile a higher min. deployment target when Xcode 27 was being used. However, investigating further revealed that the issue isn't our Package.swift's min. OS versions, but how our CI is injecting older deployment versions that Xcode now flags as an error.

Passes (Letting Xcode auto-upgrade the deployment target):

xcodebuild -scheme FirebaseAILogicUnit -destination platform=OS\ X\,arch=x86_64 \
  ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO \
  CODE_SIGNING_ALLOWED=YES COMPILER_INDEX_STORE_ENABLE=NO build

Fails (Forcing the compiler to build for an unsupported macOS version):

xcodebuild -scheme FirebaseAILogicUnit -destination platform=OS\ X\,arch=x86_64 \
  ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=YES \
  COMPILER_INDEX_STORE_ENABLE=NO IPHONEOS_DEPLOYMENT_TARGET=15.0 \
  MACOSX_DEPLOYMENT_TARGET=10.15 TVOS_DEPLOYMENT_TARGET=15.0 \
  WATCHOS_DEPLOYMENT_TARGET=7.0 build

Apple Documentation:
This auto-upgrade behavior is defined in the Swift Package Manager documentation for SupportedPlatform (Apple Developer Docs):

"This predefined deployment version is the oldest deployment target version that the installed SDK supports for a given platform."

Note: There is a "hidden" build setting to turn off the enforcement checks: __DIAGNOSE_INVALID_DEPLOYMENT_TARGET_AS_ERROR=NO.


The "fix" for this issue on our CI will be in the Xcode 27 PR, #16424, adjusting the scripts/build.sh to not pass specific OS versions or pass OS versions that Xcode is happy with (TBD).

#no-changelog

@ncooke3 ncooke3 added this to the 12.17.0 - M184 milestone Jul 23, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

@ncooke3 ncooke3 changed the title rollback: conditional min. OS versions for Xcode 27 rollback(spm): conditional min. OS versions for Xcode 27 Jul 23, 2026
@ncooke3
ncooke3 marked this pull request as ready for review July 23, 2026 20:48
@ncooke3
ncooke3 requested a review from a team as a code owner July 23, 2026 20:48
@ncooke3
ncooke3 requested review from andrewheard and daymxn and removed request for andrewheard and daymxn July 23, 2026 20:48
@ncooke3 ncooke3 self-assigned this Jul 23, 2026
@ncooke3
ncooke3 marked this pull request as draft July 23, 2026 20:49
@ncooke3
ncooke3 marked this pull request as ready for review July 23, 2026 21:04
@ncooke3 ncooke3 removed their assignment Jul 23, 2026
@ncooke3
ncooke3 requested review from andrewheard and daymxn July 23, 2026 21:05

@andrewheard andrewheard left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with rolling back for further investigation but as far as I'm aware, the passing snippet

xcodebuild -scheme FirebaseAILogicUnit -destination platform=OS\ X\,arch=x86_64 \
  ONLY_ACTIVE_ARCH=YES CODE_SIGNING_REQUIRED=NO \
  CODE_SIGNING_ALLOWED=YES COMPILER_INDEX_STORE_ENABLE=NO build

will have a deployment target of the macOS SDK version.

It may behave differently with Swift Packages but not sure if that applies only with swift build or also with xcodebuild.

@andrewheard

Copy link
Copy Markdown
Contributor

At least based on Gemini's assessment, it does pick the lowest supported for Swift Packages:

When you use xcodebuild to build a standalone Swift Package without explicitly specifying IPHONEOS_DEPLOYMENT_TARGET in your build command, xcodebuild relies entirely on the internal build plan generated by the Swift Package Manager (SPM).

In this scenario, the deployment target is chosen in a strict two-step priority:

1. The Package.swift Manifest (Primary)

xcodebuild will first look at the platforms array inside your Package.swift file. If the package explicitly declares an iOS version, that version becomes the IPHONEOS_DEPLOYMENT_TARGET.

// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "MyPackage",
    platforms: [
        .iOS(.v15) // xcodebuild will use 15.0
    ],
    // ...
)

2. The SwiftPM Default Floor (Fallback)

If the Package.swift does not specify a platforms array (or omits iOS from the list), xcodebuild does not default to the latest iOS version. Instead, it falls back to SwiftPM's hardcoded minimum deployment target.

According to Apple's documentation, this is designed to be the oldest deployment target that the installed SDK supports. However, under the hood in the open-source SPM codebase (Platform.swift), this value is actually hardcoded and tied to the // swift-tools-version: declared at the top of your manifest:

  • Swift 5.9+ / Xcode 15+: The default fallback is iOS 12.0.
  • Older Swift tools versions (e.g., 5.3 or 5.4): The default fallback was significantly lower (often iOS 8.0, 9.0, or 11.0).

The Common Xcode Error Gotcha
Because xcodebuild defers to this very low SPM default when the target isn't specified, building older Swift Packages on newer Xcode versions often triggers this familiar warning or build failure:
"The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 12.0 to 17.0.99."
This happens because SPM assigned its fallback default (e.g., 8.0) based on an older swift-tools-version, but your modern xcodebuild toolchain no longer supports compiling for iOS versions that old.

To summarize: If you leave it entirely up to xcodebuild and the package doesn't declare a target, you will get the absolute minimum iOS version supported by the Swift tools version defined at the top of the package.

@ncooke3
ncooke3 merged commit 33a468a into main Jul 23, 2026
113 of 117 checks passed
@ncooke3
ncooke3 deleted the nc.reverts branch July 23, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants