Summary
When a Swift package contains all three targets below in the same package,
Xcode links the macro target's host-only testable object into the iOS Simulator
test bundle when SwiftSyntax prebuilts are enabled:
DemoKitTests (.testTarget) -> DemoKit (.target) -> DemoKitMacros (.macro)
DemoKitTests has no direct dependency on DemoKitMacros. The failure occurs
even when the test does not invoke or reference the macro.
This reproduces with Xcode 26.6 and Xcode 27 beta 4. Moving the macro into a
separate local child package avoids the failure while keeping prebuilts enabled.
Expected behavior
The macro executable and its SwiftSyntax dependencies should be built for and
loaded on the macOS host. Its relocatable/testable macOS object should not be a
link input of the iOS Simulator test bundle.
Actual behavior
The generated target dependency graph makes DemoKitTests-product depend on
DemoKitMacros, and the test bundle's link file list contains the macro's
testable host object:
Target 'DemoKitTests-product' in project 'DemoKit'
-> Explicit dependency on target 'DemoKitMacros' in project 'DemoKit'
-> Explicit dependency on target 'DemoKitMacros' in project 'DemoKit'
-> Explicit dependency on target 'DemoKit' in project 'DemoKit'
The iOS Simulator link then fails:
ld: building for 'iOS-simulator', but linking in object file
(.../Build/Products/Debug/ExecutableModules/
DemoKitMacros--228C090CAA851E1-testable.o) built for 'macOS'
With Xcode 27 beta 4, the log confirms that the SwiftSyntax MacroSupport
prebuilt is selected before the failure:
Downloading package prebuilt
https://download.swift.org/prebuilts/swift-syntax/603.0.2/
swiftlang-6.4.0.27.1-macosx27.0-MacroSupport.zip
Steps to reproduce
-
Download and extract DemoKit.zip.
-
From the extracted DemoKit directory, run against any available iOS
Simulator, starting with clean DerivedData:
xcodebuild test \
-scheme DemoKit \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro' \
-derivedDataPath /tmp/DemoKitDerivedData \
-IDEPackageEnablePrebuilts=YES
Controls and workarounds
-
Passing -IDEPackageEnablePrebuilts=NO makes the same-package layout build
and test successfully, but requires building SwiftSyntax from source.
-
Moving DemoKitMacros into a local child package makes the test pass with
-IDEPackageEnablePrebuilts=YES.
-
Building the same target graph with the SwiftPM CLI succeeds, including an
iOS Simulator cross-build of the test targets:
swift build --build-tests \
--triple arm64-apple-ios18.0-simulator \
--sdk "$(xcrun --sdk iphonesimulator --show-sdk-path)" \
--enable-experimental-prebuilts
This suggests the incorrect testable-object linkage is in the Xcode/Swift
Build package build plan rather than the package's declared dependency graph.
Environment
- macOS 26.5.2 (25F84), Apple silicon
- Xcode 26.6 (17F113), Swift 6.3.3
- Xcode 27 beta 4 (27A5228h), Swift 6.4
- swift-syntax 603.0.2
Related reports
Summary
When a Swift package contains all three targets below in the same package,
Xcode links the macro target's host-only testable object into the iOS Simulator
test bundle when SwiftSyntax prebuilts are enabled:
DemoKitTestshas no direct dependency onDemoKitMacros. The failure occurseven when the test does not invoke or reference the macro.
This reproduces with Xcode 26.6 and Xcode 27 beta 4. Moving the macro into a
separate local child package avoids the failure while keeping prebuilts enabled.
Expected behavior
The macro executable and its SwiftSyntax dependencies should be built for and
loaded on the macOS host. Its relocatable/testable macOS object should not be a
link input of the iOS Simulator test bundle.
Actual behavior
The generated target dependency graph makes
DemoKitTests-productdepend onDemoKitMacros, and the test bundle's link file list contains the macro'stestable host object:
The iOS Simulator link then fails:
With Xcode 27 beta 4, the log confirms that the SwiftSyntax MacroSupport
prebuilt is selected before the failure:
Steps to reproduce
Download and extract DemoKit.zip.
From the extracted
DemoKitdirectory, run against any available iOSSimulator, starting with clean DerivedData:
Controls and workarounds
Passing
-IDEPackageEnablePrebuilts=NOmakes the same-package layout buildand test successfully, but requires building SwiftSyntax from source.
Moving
DemoKitMacrosinto a local child package makes the test pass with-IDEPackageEnablePrebuilts=YES.Building the same target graph with the SwiftPM CLI succeeds, including an
iOS Simulator cross-build of the test targets:
swift build --build-tests \ --triple arm64-apple-ios18.0-simulator \ --sdk "$(xcrun --sdk iphonesimulator --show-sdk-path)" \ --enable-experimental-prebuiltsThis suggests the incorrect testable-object linkage is in the Xcode/Swift
Build package build plan rather than the package's declared dependency graph.
Environment
Related reports
the compiler is unable to use the pre-compiled SwiftCompilerPlugin and
SwiftSyntaxMacros modules, FB21914833. It
reports the same target shape and
IDEPackageEnablePrebuilts=NOworkaround.arch.
variants during build-for-testing. This issue has a different symptom: the
macro is loaded, but its macOS testable object is also linked into the iOS
test bundle.