Skip to content

Enable Swift types exposed in Objective-C APIs to be visible to the Swift consumer #9513

@abdulowork

Description

@abdulowork

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:

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_FLAGS in the imparted build properties of the Swift target, passing the -Xcc equivalent of the argument here
  • Emit a $(BUILT_PRODUCTS_DIR)/SwiftTarget directory with the module.modulemap and the SwiftTarget-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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions