swiftlang / swift-package-manager

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

Windows SwiftPM with .interoperabilityMode(.Cxx) - C++ Header not generated #7319

Open litewrap opened 9 months ago

litewrap commented 9 months ago

Description

Very basic Swift library build with .interoperabilityMode(.Cxx) Build success on macOS and C++ header generated. Build success on Windows but C++ header not generated.

Expected behavior

C++ header generated.

Actual behavior

C++ header not generated.

Steps to reproduce

// swift-tools-version: 5.11
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "TestCxxToSwift",
    products: [
        // Products define the executables and libraries a package produces, making them visible to other packages.
        .library(
            name: "TestCxxToSwift",
            type: .dynamic,
            targets: ["TestCxxToSwift"]),
    ],
    targets: [
        // Targets are the basic building blocks of a package, defining a module or a test suite.
        // Targets can depend on other targets in this package and products from dependencies.
        .target(
            name: "TestCxxToSwift",
            swiftSettings: [.interoperabilityMode(.Cxx)]
        ),
        .testTarget(
            name: "TestCxxToSwiftTests",
            dependencies: ["TestCxxToSwift"], 
            swiftSettings: [.interoperabilityMode(.Cxx)]
        )
    ]
)
// TestCxxToSwift.swift

import Foundation

public func foo() -> [MyObject] {
    let objects: [MyObject] = []
    return objects
}

public class MyObject {

    var i: Int

    public init(i: Int) {
        self.i = i
    }
}

public class MyModule {
    public init() { }

    public func getArray() -> [MyObject] {
        let objects: [MyObject] = []
        return objects
    }
}
C:\Users\admin\Documents\atwork\SwiftProjects\TestCxxToSwift>swift build
Building for debugging...
[8/8] Linking C:\Users\admin\Documents\atwork\SwiftProjects\TestCxxToSwift\.build\x86_64-unknown-windows-msvc\debug\T…
Build complete! (34.67s)

Swift Package Manager version/commit hash

Building on Windows using DEVELOPMENT-SNAPSHOT-2024-01-30.

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

C:\Users\admin\Documents\atwork\SwiftProjects\TestCxxToSwift>swift --version Swift version 5.11-dev (LLVM 0c7051c13ba8526, Swift 192d275b78109ff) Target: x86_64-unknown-windows-msvc

neonichu commented 9 months ago

Correct, the compatibility header is only generated on Darwin platforms, see https://github.com/apple/swift-package-manager/blob/main/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift#L693

litewrap commented 9 months ago

I find a workaround by passing the following unsafe flag: -emit-clang-header-path

 .target(
            name: "TestCxxToSwift",
            swiftSettings: [.interoperabilityMode(.Cxx),  .unsafeFlags(["-emit-clang-header-path", "MySwiftModule-Swift.h"])]
        ),

I hope a fix for SwiftPM with Cxx interop will behave the same on all platforms.