I am refactoring a project to use SPM. Previously in the “bridging header” I had a #include <abc/abc.h>
which exposed the C static library in abc.xcframework to swift and worked very well.
Now I have the abc.xcframework as a binaryTarget in the SPM Package.swift, but there is no bridging header in a Swift Package and so the library is not found, it’s not getting included anywhere. Neither my swift package or the tests will compile.
Does anyone know how I can solve that? I've been trying to make a module as a target dependencies but it still won't find the structs etc declared in the abc.h
If I understand what you're attempting to do, you are trying to import a C Header and use it in Swift code in your Swift Package. If this is indeed the case then what you need to do is create a separate target in your Package.swift file that includes the C Header and then include that in the target that contains your Swift code.
I've done this in one of my projects which you can find here. The CHalf target is the one that imports the C Header that I created whereas Half is the target that contains all of the Swift sources.
It sounds like the OP has a binaryTarget not a C target like you do in Half.
I was able to get this working without a module map by including an intermediate "dummy" C target. My swift target depends on a C target that has bridge.c and include/bridge.h and then the dummy C target depends on the binaryTarget that represents my xcframework.
If I build the package with swift build, it builds just fine without any complaints.
However, the minute I try to use it in another project, it complains immediately that it's missing header files and it can't build:
swift build
warning: 'swiftclone': dependency 'libswiftclone' is not used by any target
Building for debugging...
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
error: emit-module command failed with exit code 1 (use -v to see invocation)
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/module.modulemap:2:12: error: header '/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h' not found
header "/Users/<USER>/Developer/SwiftClone/.build/arm64-apple-macosx/debug/LibSwiftClone.build/LibSwiftClone-Swift.h"
^
/Users/<USER>/Developer/SwiftClone/Sources/SwiftClone/SwiftClone.swift:2:8: error: could not build Objective-C module 'LibSwiftClone'
import LibSwiftClone
^
error: fatalError
Not being able to find the generated header suggests to me that whatever target contains the import LibSwiftClone has an unexpressed dependency on it. The generated header will be created as part of building that module, so if the dependency is missing, it isn't guaranteed to happen before the client code is built.
But, I don't see anything different, except I define a version constant https://github.com/withuno/UnoSwift/blob/main/Sources/C/include/bridge.h#L6, which I guess could be important for the packaging routine when it decides if it needs to generate a modulemap or not? I don't remember where I found documentation on the conditions required for swift's package tools to generate the modulemap, but I vaguely recall it only happens under certain circumstances.
Other than that, my best guess would be the issue is something in the way you are including or building the package downstream, especially if it builds with swift build/test locally. You could try including mine as a test and see if it works /shrug. And try opening your package in Xcode ($ open Package.swift) and building that way. Xcode should be able to build your swift package and run your tests which would rule out an Xcode issue.Edit: I see you're using swift downstream so ignore the Xcode bit.
Edit2: I just realized changing the swift tools min version probably didn't do anything. You'd have to find a way to build with the older version. But that's probably not the issue regardless so save that as a last resort.
Thanks all for the help. As @NeoNacho suggested, it was simply an obvious omission in my Package.swift file.
Now I'm seeing a new error:
Building for debugging...
ld: warning: '/Users/<USER>/Developer/Test/.build/arm64-apple-macosx/debug/librclone.a[2](go.o)' has malformed LC_DYSYMTAB, expected 146 undefined symbols to start at index 151643, found 167 undefined symbols starting at index 110
ld: Undefined symbols:
_res_9_nclose, referenced from:
_runtime.text in librclone.a[2](go.o)
_res_9_ninit, referenced from:
_runtime.text in librclone.a[2](go.o)
_res_9_nsearch, referenced from:
_runtime.text in librclone.a[2](go.o)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[2/3] Linking Test
Which tells me there's maybe something going on with the library itself? I'm not really familiar with Go, but I will investigate over at the Rclone repo.