Summary
destinationFilters on a TargetSource work for regular (group) sources: each file gets platformFilters on its PBXBuildFile. For type: syncedFolder the same key is silently ignored, so every file in the folder compiles for all destinations of the target.
Xcode itself supports per-file platform filters inside synced folders via platformFiltersByRelativePath on PBXFileSystemSynchronizedBuildFileExceptionSet, and the bundled XcodeProj already models that field (tuist/XcodeProj#1065, in XcodeProj 9.8.0+).
Reproduction
name: Demo
targets:
App:
type: application
supportedDestinations: [iOS, visionOS]
sources:
- path: Sources
type: syncedFolder
excludes:
- VisionOSMain.swift
destinationFilters: [iOS]
- path: Sources
type: syncedFolder
includes:
- VisionOSMain.swift
destinationFilters: [visionOS]
Sources/AppDelegate.swift uses UIScreen, Sources/VisionOSMain.swift is a visionOS @main.
Expected
The generated exception set carries the filters, the way Xcode writes them when you uncheck "Any Supported Platform" in the file inspector:
platformFiltersByRelativePath = {
AppDelegate.swift = (ios, );
VisionOSMain.swift = (xros, );
};
and the visionOS build does not compile AppDelegate.swift.
Actual
membershipExceptions are emitted from excludes/includes, but there is no platformFiltersByRelativePath at all.
Building for visionOS compiles AppDelegate.swift and fails with 'UIScreen' is unavailable in visionOS. No warning that the key is ignored.
I verified that Xcode honors a hand-written platformFiltersByRelativePath in the generated project (Xcode 26.5): the filtered files are skipped on the other platform for both iOS and visionOS builds.
Folder keys are not honored by Xcode, only file paths, so the generator would need to enumerate matching files the same way syncedFolderExceptions already does for excludes.
Environment
- XcodeGen 2.45.4 (same on 2.46.0 / master)
- Xcode 26.5
- macOS 26
Related, but different: #1589 / #1587 (excludes), #1602 / #1604 (includes), #1607 (directory-level exceptions).
Summary
destinationFilterson aTargetSourcework for regular (group) sources: each file getsplatformFilterson itsPBXBuildFile. Fortype: syncedFolderthe same key is silently ignored, so every file in the folder compiles for all destinations of the target.Xcode itself supports per-file platform filters inside synced folders via
platformFiltersByRelativePathonPBXFileSystemSynchronizedBuildFileExceptionSet, and the bundled XcodeProj already models that field (tuist/XcodeProj#1065, in XcodeProj 9.8.0+).Reproduction
Sources/AppDelegate.swiftusesUIScreen,Sources/VisionOSMain.swiftis a visionOS@main.Expected
The generated exception set carries the filters, the way Xcode writes them when you uncheck "Any Supported Platform" in the file inspector:
and the visionOS build does not compile
AppDelegate.swift.Actual
membershipExceptionsare emitted fromexcludes/includes, but there is noplatformFiltersByRelativePathat all.Building for visionOS compiles
AppDelegate.swiftand fails with'UIScreen' is unavailable in visionOS. No warning that the key is ignored.I verified that Xcode honors a hand-written
platformFiltersByRelativePathin the generated project (Xcode 26.5): the filtered files are skipped on the other platform for both iOS and visionOS builds.Folder keys are not honored by Xcode, only file paths, so the generator would need to enumerate matching files the same way
syncedFolderExceptionsalready does for excludes.Environment
Related, but different: #1589 / #1587 (excludes), #1602 / #1604 (includes), #1607 (directory-level exceptions).