chinedufn / swift-bridge

swift-bridge facilitates Rust and Swift interop.
https://chinedufn.github.io/swift-bridge
Apache License 2.0
842 stars 62 forks source link

Xcode reports "Multiple commands produce '...DerivedData...Build/Products/Debug/include/module.modulemap'" #243

Closed jessegrosjean closed 5 months ago

jessegrosjean commented 1 year ago

I'm wrapping a rust crate into a swift package using swift-bridge. On own it's working great. I add the generated package to my macOS App, and it works.

I'm having a problem when I also add another package (https://github.com/MacPaw/Setapp-framework) to my app. As soon as I do that I get Xcode error:

"Multiple commands produce '...DerivedData...Build/Products/Debug/include/module.modulemap'"

Any thoughts on what I need to change to fix this problem?

I have reproduced the problem in an example project here:

https://github.com/jessegrosjean/module-map-error

Thanks, Jesse

jessegrosjean commented 1 year ago

I can reproduce a similar error without requiring Setapp. Instead I just create two separate packages using swift-bridge. When I try to include both packages in Xcode project I get error:

multiple targets named 'RustXcframework' in: 'myotherswiftpackage', 'myswiftpackage'; consider using the `moduleAliases` parameter in manifest to provide unique names

Trying to figure out moduleAliases fix, but no luck so far.

jessegrosjean commented 1 year ago

I have fixed the multiple targets named 'RustXcframework' error by manually renaming the generated framework in my shell script as I saw in another issue. So after call to swift-bridge-cli I do:

mv MyOtherSwiftPackage/RustXcframework.xcframework MyOtherSwiftPackage/MyOtherRust.xcframework
sed -i '' 's/RustXcframework/MyOtherRust/g' ./MyOtherSwiftPackage/Package.swift
sed -i '' 's/RustXcframework/MyOtherRust/g' ./MyOtherSwiftPackage/Package.swift
sed -i '' 's/RustXcframework/MyOtherRust/g' ./MyOtherSwiftPackage/Sources/MyOtherSwiftPackage/*.swift
sed -i '' 's/RustXcframework/MyOtherRust/g' ./MyOtherSwiftPackage/MyOtherRust.xcframework/*/Headers/module.modulemap

Instead of hardcoding framework name to RustXcframework.xcframework would it make sense to use a unique name each time based on the name passed into swift-bridge-cli.?

Once I do these things then the multiple targets named 'RustXcframework' goes away, but I then the original error + 1:

Multiple commands produce '/Users/jessegrosjean/Library/Developer/Xcode/DerivedData/Workspace-hbkovcglkaahjfbtnhikecddkhwb/Build/Products/Debug/include/SwiftBridgeCore.h'
Multiple commands produce '/Users/jessegrosjean/Library/Developer/Xcode/DerivedData/Workspace-hbkovcglkaahjfbtnhikecddkhwb/Build/Products/Debug/include/module.modulemap'

Again this is happening when I use swift-bridge to create two swift packages that wrap rust code, and include them both in the same app.

jessegrosjean commented 1 year ago

I think I found solution and have fully documented at end of README here:

https://github.com/jessegrosjean/swift-cargo-problem

That example is using cargo-swift instead of swift-bridge, but I think both generators have the same problem.

I think the boiled down answer is that if your swift package references a framework, that framework needs to have unique name, plus unique internal names for headers, etc. So if you are generating swift packages that use an XCFramework you nee to make all the generated values are unique, otherwise you can't use two of the generated packages in the same app.

Juanchen1190 commented 5 months ago
Screenshot 2024-05-24 at 10 41 32

create a folder inside Headers can fix this.