-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Description
This issue is a recreation of the issue from the swift-build repository. Initially, I thought it could be addressed there, but after a discussion in this PR, I see this issue needs to be discussed in SwiftPM itself.
This problem has been raised in different places a couple of times:
- [SR-15154] ObjC projects using SPM fail when we expose our models into another module swift#57480
- [SR-15718] Swift references with '@objc' in a swift package cannot be exposed in ObjC headers that are visible to swift. Module not found build error. #4362
- https://forums.swift.org/t/importing-swift-types-exposed-in-an-objective-c-api-back-into-swift/83492
But I thought it made sense to reraise it with some more specific questions. Basically, when building SwiftPM targets in Xcode, it is challenging to enable the Swift consumer to see Swift types from transitive Swift modules when they are exposed through an Objective-C API, and the Objective-C API itself becomes uncallable.
I am also interested in solving this issue in relation to #9511.
After the discussion in the swift-build PR, I see 2 potential ways to support this use case:
- Emit
OTHER_SWIFT_FLAGSin the imparted build properties of the Swift target, passing the-Xccequivalent of the argument here - Emit a
$(BUILT_PRODUCTS_DIR)/SwiftTargetdirectory with themodule.modulemapand theSwiftTarget-Swift.h. From the discussion in the PR, I understand this approach as less desirable, but perhaps some variation of it could be used to implement this feature as an opt-in.
Further, from the discussion in the swift-build PR, I understand that a concern is that either of these changes might affect existing Swift compilations:
- Is there a specific impact on Swift compilations that should be expected if SwiftPM was to pass the generated modulemap in the imparted build properties?
- Is there a suite of integration tests that the SwiftPM team uses to research answers to such questions if the answer is not immediately clear?
Expected behavior
Swift compilations in Xcode can consume Objective-C SwiftPM APIs that expose Swift types
Actual behavior
Swift compilations that try to consume such APIs explode with issues like:
error: Clang dependency scanner failure: While building module 'ObjcTarget' imported from ObjcTarget-41b4bbd9.input:1:
In file included from <module-includes>:1:
/path/to/SwiftPMObjCTransitiveExport/Sources/ObjcTarget/include/ObjcTarget.h:5:9: fatal error: module 'SwiftTarget' not found
ObjcTarget-41b4bbd9.input:1:1: fatal error: could not build module 'ObjcTarget'
Steps to reproduce
Create a Swift type with:
@objc public class SwiftTargetType : NSObject {
@objc public func exposeToObjectiveC() {}
public func exposeToSwift() {}
}
expose it in an Objective-C target:
@import Foundation;
@import SwiftTarget;
SwiftTargetType * useSwiftTargetFromObjC(SwiftTargetType *);
and try to use this Objective-C API in a Swift target:
import ObjcTarget
import SwiftTarget
func consume(arg: SwiftTargetType) {
let foo: SwiftTargetType = useSwiftTargetFromObjC(arg)
foo.exposeToSwift()
}
Please see e2e reproduction in this issue here. Run it with xcodebuild clean build -scheme SwiftPMObjCTransitiveExport -destination 'generic/platform=iOS Simulator' ARCHS=arm64.
Swift Package Manager version/commit hash
SwiftPM shipped with Xcode 26.0.1
Swift & OS version (output of swift --version && uname -a)
swift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)
Target: arm64-apple-macosx15.0
Darwin NVC00511 24.4.0 Darwin Kernel Version 24.4.0: Fri Apr 11 18:33:47 PDT 2025; root:xnu-11417.101.15~117/RELEASE_ARM64_T6000 arm64