swiftlang / swift-package-manager

The Package Manager for the Swift Programming Language
Apache License 2.0
9.66k stars 1.31k forks source link

Objective-C/C++ module cannot depend on a Swift module #7099

Open code-per-day opened 7 months ago

code-per-day commented 7 months ago

Description

I have a Swift module with classes marked @objc and I'm trying to migrate our C++ library, which depends on the previous module, to build using the Swift Package Manager.

This is possible with Xcode projects and we can access them via the following line.

#include <MySwiftModule/MySwiftModule-Swift.h>

Using swiftpm however this header doesn't seem to exist.

Expected behavior

I'd expect to have access to the generated bridging header in our C++ library.

Actual behavior

There doesn't seem to be any generated bridging headers to import.

Steps to reproduce

With the following package, try to #import <SwiftTarget/SwiftTarget-Swift.h>, it doesn't exist nor does it exist anywhere else.

// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "Example",
    products: [
        .library(name: "Example", targets: ["CxxTarget"]),
    ],
    targets: [
        .target(name: "SwiftTarget"),
        .target(name: "CxxTarget", dependencies: ["SwiftTarget"]),
    ],
    cxxLanguageStandard: .cxx14
)

Swift Package Manager version/commit hash

No response

Swift & OS version (output of swift --version ; uname -a)

swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
Target: arm64-apple-macosx14.0
Darwin macbook.local 23.0.0 Darwin Kernel Version 23.0.0: Fri Sep 15 14:41:43 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T6000 arm64
neonichu commented 7 months ago

That's right, we don't give direct access to the header. The expectation is that one would import the module instead, e.g. @import MySwiftModule; in ObjC. I don't know if that works for C++, might be something that needs to be addressed as part of interop support? cc @hyp

code-per-day commented 7 months ago

None of the following works in C++, I can get away with @import MySwiftModule; for this project but I have personal C and C++ projects with which I'd love two-way interop!

// These ones are the ones I expected to work but didn't
#import <MySwiftModule>
#include <MySwiftModule/MySwiftModule-Swift.h>

// These ones are desperate attempts
#include <MySwiftModule.h>
#include <MySwiftModule-Swift.h>
#include <MySwiftModule/MySwiftModule.h>
#import <MySwiftModule.h>
#import <MySwiftModule-Swift.h>
#import <MySwiftModule/MySwiftModule.h>
#import <MySwiftModule/MySwiftModule-Swift.h>

My next step is figuring out how to include system library headers in C++, trying to access libcurl and it works in Swift but not C++.

code-per-day commented 3 months ago

@hyp @neonichu Using @import MySwiftModule requires unsafe flags (-fmodules, -fcxx-modules) which is now causing major problems, I think either this header should be directly accessible or SwiftPM should have more "safe" flags.

Is there something I can do in the mean time (ideally with the Swift 5.10 toolchain) to work around this issue?