Alexandre Gressier
08/21/2022, 1:11 PMxcodebuild -workspace MyLibInterop.xcworkspace -scheme MyLibInterop -sdk $sdk -configuration Release build SYMROOT=$PWD/build OBJROOT=$PWD/build
, and finally creating a cinterop configuration via Gradle and a .def file. It works quite well. My setup is very similar to the one explained here: https://medium.com/kodein-koders/create-a-kotlin-multiplatform-library-with-swift-1a818b2dc1b0 (the ChachaPoly one). However I encounter a problem as soon as I start to add dependencies to this static library: I don’t know how to tell cinterop where to look for the dependency frameworks used by the static library. I used Cocoapods (without Gradle) to define the dependencies. The previous xcodebuild
command then outputs several .framework directories that represent the dependencies in addition to the existing .h and .a files. My exact issue is ``ld: warning: Could not find or use auto-linked framework 'Amplify'` which is one of the .framework directories when running the task shared:linkPodDebugFrameworkIosArm64
. I suppose that I have to define a recursive framework search path within my Kotlin cinterop configuration (i.e., the .def file). I came across the -F
and -framework
linker & compiler options but used them without any success. Thank you in anticipation for any kind of help you will be able to provide me with. I can provide any info or piece of code you need.Rick Clephas
08/22/2022, 6:37 AM-F
and -framework
options?Alexandre Gressier
08/22/2022, 9:44 AM-F
search paths under compilerOpts()
in the Gradle build script using the static library, and -framework
flags under linkerOpts
in my .def file.platform :ios, '13.0'
target 'AmplifyAuthInterop' do
use_frameworks!
pod 'AmplifyPlugins/AWSCognitoAuthPlugin'
end
Here is the content of the build directory (at depth 2) after running `xcodebuild`:
build
├── AWSAuthCore
│ ├── AWSAuthCore.framework
├── AWSCognitoIdentityProvider
│ ├── AWSCognitoIdentityProvider.framework
├── AWSCognitoIdentityProviderASF
│ ├── AWSCognitoIdentityProviderASF.framework
├── AWSCore
│ ├── AWSCore.framework
├── AWSMobileClient
│ ├── AWSMobileClient.framework
├── AWSPluginsCore
│ ├── AWSPluginsCore.framework
├── Amplify
│ ├── Amplify.framework
├── AmplifyAuthInterop.swiftmodule
│ ├── Project
│ ├── arm64-apple-ios.abi.json
│ ├── arm64-apple-ios.swiftdoc
│ └── arm64-apple-ios.swiftmodule
├── AmplifyPlugins
│ ├── AmplifyPlugins.framework
├── Pods_AmplifyAuthInterop.framework
│ ├── Headers
│ ├── Info.plist
│ ├── Modules
│ └── Pods_AmplifyAuthInterop
├── include
│ └── AmplifyAuthInterop
└── libAmplifyAuthInterop.a
I am not sure if -F
works recursively, so I wrote the following:
kotlin {
ios {
val platform = when (name) {
"iosX64" -> "iphonesimulator"
"iosArm64" -> "iphoneos"
else -> error("Unsupported target $name")
}
compilations.getByName("main") {
cinterops.create("AmplifyAuthInterop") {
project(":shared:interop:AmplifyAuthInterop").let {
tasks[interopProcessingTaskName].dependsOn(
it.getTasksByName("build${platform.capitalize()}", false).first().path
)
packageName = "interop.amplifyauth"
includeDirs.headerFilterOnly("${it.buildDir}/Release-$platform/include")
compilerOpts(
listOf(
"AWSAuthCore",
"AWSCognitoIdentityProvider",
"AWSCognitoIdentityProviderASF",
"AWSCore",
"AWSMobileClient",
"AWSPluginsCore",
"Amplify",
"AmplifyPlugins",
).map { framework ->
"-F${it.buildDir}/Release-$platform/$framework"
} + "-F${it.buildDir}/Release-$platform"
)
extraOpts("-libraryPath", "${it.buildDir}/Release-$platform")
}
}
}
}
And I ensured that the framework search paths exist, of course.Rick Clephas
08/22/2022, 11:20 AM.def
file? I vaguely remember something about on of these options not being supported from the Gradle task.kotlin {
iosX64 {
binaries.all {
linkerOpts("-F$frameworkFolder")
}
}
}
Alexandre Gressier
08/22/2022, 3:23 PMbinaries
block but I'll leave the following notes for future reference:
I'm almost certain that you are referring to warning: -linker-option(s)/-linkerOpts option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.
. I suppose it would be fine in the binaries
block though, as opposed to the cinterop
one.
I ended up writing most of my configuration in my .def file instead of the Gradle build script. I also discovered that I only need to use and -F
for the imports I write in Swift (i.e., only Amplify
). Here it is:
package = interop.amplifyauth
language = Objective-C
# Headers
headers = AmplifyAuthInterop/AmplifyAuthInterop-Swift.h
headerFilter = AmplifyAuthInterop/**
# Libraries
staticLibraries = libAmplifyAuthInterop.a
libraryPaths.ios_arm64 = /Users/alex/Projects/MyProject/shared/interop/AmplifyAuthInterop/build/Release-iphoneos
libraryPaths.ios_x64 = /Users/alex/Projects/MyProject/shared/interop/AmplifyAuthInterop/build/Release-iphonesimulator
# Linker
linkerOpts = -L/usr/lib/swift
linkerOpts.ios_arm64 = -iphoneos_version_min 16.0.0 \
-L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/ \
-F/Users/alex/Projects/MyProject/shared/interop/AmplifyAuthInterop/build/Release-iphoneos/Amplify
linkerOpts.ios_x64 = -ios_simulator_version_min 16.0.0 \
-L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/ \
-F/Users/alex/Projects/MyProject/shared/interop/AmplifyAuthInterop/build/Release-iphonesimulator/Amplify
And here is the Gradle build script:
kotlin {
ios {
val platform = when (name) {
"iosX64" -> "iphonesimulator"
"iosArm64" -> "iphoneos"
else -> error("Unsupported target $name")
}
compilations.getByName("main") {
cinterops.create("AmplifyAuthInterop") {
project(":shared:interop:AmplifyAuthInterop").let {
tasks[interopProcessingTaskName].dependsOn(
it.getTasksByName("build${platform.capitalize()}", false).first().path
)
includeDirs.headerFilterOnly("${it.buildDir}/Release-$platform/include")
}
}
}
}
I initially forgot to add a Copy Files build phase to copy Amplify.framework
in the Frameworks directory of my app. After that it ran successfully. There are still nasty absolute paths in my .def file but I don't mind for the time being. Thank you again for your precious help.Rick Clephas
08/22/2022, 3:48 PM