Skip to content

Support destinationFilters for synced folders - #1647

Open
anandghegde wants to merge 2 commits into
yonaskolb:masterfrom
anandghegde:synced-folder-destination-filters
Open

anandghegde wants to merge 2 commits into
yonaskolb:masterfrom
anandghegde:synced-folder-destination-filters

Conversation

@anandghegde

Copy link
Copy Markdown

Description

destinationFilters and inferDestinationFiltersByPath were ignored for type: syncedFolder sources. Regular sources get the filters on each PBXBuildFile, but synced folders have no build files, so every file in the folder was compiled for every supported destination.

Xcode stores per-file platform filters for synced folders in platformFiltersByRelativePath on the PBXFileSystemSynchronizedBuildFileExceptionSet, which XcodeProj already supports. This PR fills it in:

  • SourceGenerator.syncedFolderPlatformFilters walks the synced folder (same traversal as syncedFolderExceptions: recurse into plain directories, treat file wrappers like .xcassets as files, skip hidden files) and uses the existing makeDestinationFilters for each file. Xcode only honors file paths here, not folder paths, so folders are expanded into files.
  • configureMembershipExceptions adds those filters to the exception set, leaving out files that are already membership exceptions. An exception set is now also created when there are only platform filters.
targets:
  App:
    type: application
    supportedDestinations: [iOS, visionOS]
    sources:
      - path: iOSSources
        type: syncedFolder
        destinationFilters: [iOS]
platformFiltersByRelativePath = {
    AppDelegate.swift = (
        ios,
    );
};

Note: the example in the issue lists the same synced folder path twice in one target. That already doesn't work on master, separately from filters: only the first source's settings are used, and the group is added to fileSystemSynchronizedGroups twice. I left that out to keep this PR small. Using separate folders, or one folder with inferDestinationFiltersByPath, works with this change.

Testing

  • Added two tests in SourceGeneratorTests (destinationFilters with excludes and a nested folder, and inferDestinationFiltersByPath). Both failed before the change.
  • Added a synced folder with inferDestinationFiltersByPath to App_supportedDestinations in the TestProject fixture and regenerated it. It has SyncedFile_iOS.swift and SyncedFile_tvOS.swift, which declare the same symbol, so the target only builds if the filters are applied.
  • swift test passes, and scripts/gen-fixtures.sh + scripts/diff-fixtures.sh show no changes after the commit.
  • Built App_supportedDestinations with Xcode 26.6 for the iOS Simulator and the tvOS Simulator SDK. Each build compiled only its own SyncedFile_*.swift. With platformFiltersByRelativePath removed from the generated project by hand, the iOS build fails with invalid redeclaration of 'syncedPlatformName'.
  • Generated a sample iOS + visionOS project with destinationFilters on synced folders (like the example above) and built it for iphonesimulator, xros and xrsimulator. Each build compiled only the files for its platform plus the unfiltered shared folder.

Addresses #1646

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant