Tristan
11/26/2024, 8:12 AMld: warning: Could not find or use auto-linked library 'swiftCompatibility56': library 'swiftCompatibility56' not found
ld: warning: Could not find or use auto-linked library 'swiftCompatibilityConcurrency': library 'swiftCompatibilityConcurrency' not found
ld: warning: Could not find or use auto-linked library 'swiftCompatibilityPacks': library 'swiftCompatibilityPacks' not found
ld: warning: Could not find or use auto-linked framework 'CoreAudioTypes': framework 'CoreAudioTypes' not found
ld: warning: Could not find or use auto-linked framework 'UnitySwiftProtobuf': framework 'UnitySwiftProtobuf' not found
Undefined symbols for architecture arm64:
"__swift_FORCE_LOAD_$_swiftCompatibility56", referenced from:
__swift_FORCE_LOAD_$_swiftCompatibility56_$_UnityAds in UnityAds[arm64][2](UnityAds-arm64-master.o)
__swift_FORCE_LOAD_$_swiftCompatibility56_$_UnitySwiftProtobuf in UnityAds[arm64][44](AnyMessageStorage.o)
"__swift_FORCE_LOAD_$_swiftCompatibilityConcurrency", referenced from:
__swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_UnityAds in UnityAds[arm64][2](UnityAds-arm64-master.o)
__swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_UnitySwiftProtobuf in UnityAds[arm64][44](AnyMessageStorage.o)
ld: symbol(s) not found for architecture arm64
I use cocoapods with
pod("UnityAds") {
version = "~> 4.12.5"
extraOpts += listOf("-compiler-option", "-fmodules") // because of clang
}
podfile = project.file("../iosTestApp/Podfile")
framework {
baseName = "SimpleGame"
isStatic = true
}
Do you think it could come from my configuration, or is it their framework that might have an issue?François
11/27/2024, 6:40 AMTimofey Solonin
11/27/2024, 11:27 AMCould not find or use auto-linked framework 'CoreAudioTypes'Please make sure that you have the iOS simulator installed and do a clean build. As a workaround for missing Swift compatibility libraries during test linkage could you please try the following workaround:
kotlin {
abstract class IphoneSimulatorCompatibilityLinkagePath @Inject constructor(): ValueSource<List<String>, ValueSourceParameters.None> {
@get:Inject
abstract val execOperations: ExecOperations
override fun obtain(): List<String> {
val buffer = ByteArrayOutputStream()
execOperations.exec {
commandLine("xcode-select", "-p")
standardOutput = buffer
}.assertNormalExitValue()
val iphoneSimulatorCompatibilityLibrariesPath = File(buffer.toString("UTF-8").dropLast(1))
.resolve("Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator")
return listOf(
"-linker-option",
"-L${iphoneSimulatorCompatibilityLibrariesPath.path}",
)
}
}
targets.withType<KotlinNativeTargetWithSimulatorTests> {
testRuns.all {
executionSource.binary.linkTaskProvider.configure {
toolOptions.freeCompilerArgs.addAll(
providers.of(IphoneSimulatorCompatibilityLinkagePath::class.java) {}
)
}
}
}
}
In any case, could you please create an issue and attach a reproduction project?Tristan
11/27/2024, 8:50 PMval iosTargets = listOf(iosX64(), iosArm64(), iosSimulatorArm64())
iosTargets.forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "Shared"
isStatic = true
binaryOption("bundleId", "com.tristan.game.shared")
}
val baseCinteropPath = "$projectDir/../vendor/UnityAds/UnityAds.xcframework"
val unityAdsPath = when (iosTarget.name) {
"iosSimulatorArm64", "iosX64" -> "${baseCinteropPath}/ios-arm64_x86_64-simulator/"
else -> "${baseCinteropPath}/ios-arm64/"
}
iosTarget.compilations.getByName("main") {
val UnityAds by cinterops.creating {
definitionFile.set(
project.file("$projectDir/../vendor/UnityAds/UnityAds.def"),
)
compilerOpts(
"-fmodules",
"-F$unityAdsPath",
"-rpath", unityAdsPath,
"-framework", "UnityAds",
)
}
}
iosTarget.binaries.all {
linkerOpts(
"-F$unityAdsPath",
"-rpath", unityAdsPath,
"-framework", "UnityAds",
)
}
}
Although it seems that your workaround worked 😮
I'll cleanup the sample and open a ticket as soon as possible.Timofey Solonin
11/27/2024, 9:14 PMI also got the same error without using CocoapodsI am almost sure what is happening is that
UnityAds.xcframework
vendors a static library with some object files that were compiled from Swift code with a deployment target that requires the use of compatibility libraries. When the Kotlin framework builds against UnityAds
with isStatic = true
there is no linkage step in Gradle and the actual linkage happens in the iOS app that consumes both UnityAds and the Kotlin framework. This -L
search path to compatibility libraries is going to be inserted by Xcode's build system, so the app linkage succeeds.
However, when you run K/N tests from Gradle, we link a standalone executable, so we have to receive the compatibility libraries search path somehow. In CocoaPods integration we could likely infer this from build settings generated by CocoaPods, but with pure cinterops you will have to specify it manually. Another option for you could be to prelink UnityAds
into a dynamic library and link the tests executable against the UnityAds
dynamic library with an appropriate rpath
.
I see that in the second build script sample you specify `-rpath`; iiuc your build configuration, this is unlikely to be of use, because UnityAds is not a dynamic library.