-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Description
Hi folks. We in the Kotlin team are building support for importing SwiftPM dependencies that expose Objective-C and C APIs for our Kotlin/Native backend in our primary build system: Gradle.
Our Kotlin/Native backend uses libclang to understand Objective-C headers and modulemaps, so to import SwiftPM dependencies, we want to obtain the same arguments the build system with SwiftPM support would pass to clang -x objective-c compilation. Namely, we are interested in:
- Search paths such as
-Iand-F - Modulemap paths such as
-fmodule-map-file= - Macro definitions
A bit beyond regular clang arguments, we are also interested in some prerequisites of the Objective-C compilations in SwiftPM:
- Particularly in the case of Swift, we want to see
TargetName-Swift.hfiles produced by the Swift compiler duringswiftc -emit-objc-header - One of the main use cases we want to support is the import of libraries like
GoogleMaps, so we need some way to get to the proper slice of the headers packaged in SwiftPM’s.binaryTarget
At the moment, what we do is:
- We generate a Package.swift with all the dependencies we want to import in a fake Objective-C SwiftPM target
- Then we run the build:
DUMP_PATH=/path/to/dump_dir xcodebuild -destination “generic/platform=...” ARCHS=... CC=compilerArgumentsDumpScript.shfor each of the target platforms that we are interested in - Finally, we find the right
clangcall, parse all the necessary compiler arguments and call ourlibclangmachinery
This works for us in general; however, there are a couple of issues. First, I don’t understand how reliable this CC override is for inferring the clang arguments. I see that, for example, the SWIFT_EXEC override now also requires SWIFT_USE_INTEGRATED_DRIVER=NO. I imagine the CC override might break for us in the future and could also change the build system behavior.
The second issue is that we want the libclang initialization to be as fast as possible, as we run it in our IDE import pipeline to show completions for Objective-C APIs in the Kotlin code. So, for example, when we run libclang, we don’t need any machine code that is produced by the swiftc/clang compilations, but we do need to see all the headers. I expect we can improve import performance if SwiftPM and Swift Build could disable IDE-irrelevant steps.
Please let me know if an e2e example would be helpful! I can publish a sample of how we do this right now in the Kotlin Gradle Plugin.
Do you think SwiftPM and/or Swift Build could offer APIs to expose all this information and maybe even provide some customization for the IDE use case? I imagine it would also be valuable for any other build systems and/or languages that interoperate with C/Objective-C using libclang. Perhaps a similar mechanism could also help Swift interoperability in the future by exposing the Swift compiler arguments to another build system, allowing it to use parts of the Swift compiler for the interop?
Expected behavior
No response
Actual behavior
No response
Steps to reproduce
No response
Swift Package Manager version/commit hash
No response
Swift & OS version (output of swift --version && uname -a)
No response