https://kotlinlang.org logo
#touchlab-tools
Title
# touchlab-tools
d

dephinera

10/12/2023, 10:49 AM
Hello, guys, I can’t build a project containing kermit with crashlytics. Logs in thread
Copy code
The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: Undefined symbols:
  _FIRCLSExceptionRecordNSException, referenced from:
      _co_touchlab_crashkios_crashlytics_FIRCLSExceptionRecordNSException_wrapper0 in libco.touchlab.crashkios:crashlytics-cinterop-crashlytics-cache.a[2](result.o)
  _OBJC_CLASS_$_FIRCrashlytics, referenced from:
       in libco.touchlab.crashkios:crashlytics-cache.a[2](result.o)
  _OBJC_CLASS_$_FIRExceptionModel, referenced from:
       in libco.touchlab.crashkios:crashlytics-cache.a[2](result.o)
  _OBJC_CLASS_$_FIRStackFrame, referenced from:
       in libco.touchlab.crashkios:crashlytics-cache.a[2](result.o)
error: Compilation finished with errors

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':shared:linkPodDebugFrameworkIosSimulatorArm64'.
> Compilation finished with errors
gradle configuration
Copy code
plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    id("com.android.library")
}

@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin {
    targetHierarchy.default()

    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "17"
            }
        }
    }
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "14.1"
        podfile = project.file("../iosApp/Podfile")
        framework {
            baseName = "shared"
            isStatic = false
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                //put your multiplatform dependencies here
                implementation("co.touchlab:kermit:2.0.1")
                implementation("co.touchlab:kermit-crashlytics:2.0.0")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
    }
}

android {
    namespace = "com.example.testanalytics"
    compileSdk = 33
    defaultConfig {
        minSdk = 24
    }
}
I’m using latest xcode (15)
r

Rick Clephas

10/12/2023, 10:52 AM
Making your framework static should solve the issue (as long as the iOS client depends on Crashlytics)
d

dephinera

10/12/2023, 10:54 AM
Thank you for your quick response. Sadly I already tried that and it still doesn’t compile
This is the output when making the framework static
Copy code
ld: Undefined symbols:
  _FIRCLSExceptionRecordNSException, referenced from:
      _co_touchlab_crashkios_crashlytics_FIRCLSExceptionRecordNSException_wrapper0 in shared[5](resulx.o)
  _OBJC_CLASS_$_FIRCrashlytics, referenced from:
       in shared[8](resul{.o)
  _OBJC_CLASS_$_FIRExceptionModel, referenced from:
       in shared[8](resul{.o)
  _OBJC_CLASS_$_FIRStackFrame, referenced from:
       in shared[8](resul{.o)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
r

Rick Clephas

10/12/2023, 10:56 AM
Alright in that case it might be related to how the cocoapods integration works (I haven't used it myself). Have you tried adding Crashlytics as a CocoaPods dependency to your Kotlin module?
k

kpgalligan

10/12/2023, 12:21 PM
Add this:
id("co.touchlab.crashkios.crashlyticslink") version "0.8.5"
That lets dynamic frameworks build
However, the bigger problem now is running tests. If you turned off compiler caching that used to work, but seems to have changed. We're trying to figure out a solution to that, or (possibly) figure out what is incorrect in our config.
It would be helpful to see more of your error. Specifically what task is failing. In the first it was building the framework, but the second doesn't list it. That error can pop up in different places, and they have different solutions
(To @Rick Clephas) recently I've been thinking we might be better off calling into these Objc libraries dynamically rather than using cinterop. Obviously, if they don't exist and you call them it'll fail, but that would avoid the linker issues during build, and assuming the app actually has the library included, it would work.
r

Rick Clephas

10/12/2023, 12:28 PM
Well the whole linking thing is little confusing. Until recently I thought there was a workaround for the dynamic frameworks. However it turned out to blowup once the app was uploaded to the app store (or more specifically once app thinning was involved). But would love to hear more about that dynamic calling if that can allow dynamic libraries.
d

dephinera

10/12/2023, 12:41 PM
okay, so actually the gradle tasks says “successful”. I also run
./gradlew build
successfully. However when trying to launch the app on the simulator from android studio, then I get this error: This is without changing anything else (just made the framework static).
Copy code
> Task :shared:compileKotlinIosSimulatorArm64 UP-TO-DATE
> Task :shared:linkPodDebugFrameworkIosSimulatorArm64 UP-TO-DATE
> Task :shared:syncFramework UP-TO-DATE

BUILD SUCCESSFUL in 449ms
3 actionable tasks: 3 up-to-date


Ld /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app/iosApp normal (in target 'iosApp' from project 'iosApp')
    cd /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -reproducible -target arm64-apple-ios14.1-simulator -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.0.sdk -O0 -L/Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/EagerLinkingTBDs/Debug-iphonesimulator -L/Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator -F/Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/EagerLinkingTBDs/Debug-iphonesimulator -F/Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator -F/Users/bkolarov/Development/blackbird/TestAnalytics/iosApp/Pods/../../shared/build/cocoapods/framework -filelist /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/Objects-normal/arm64/iosApp.LinkFileList -Xlinker -rpath -Xlinker /usr/lib/swift -Xlinker -rpath -Xlinker @executable_path/Frameworks -Xlinker -rpath -Xlinker @loader_path/Frameworks -dead_strip -Xlinker -object_path_lto -Xlinker /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/Objects-normal/arm64/iosApp_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -fobjc-link-runtime -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -L/usr/lib/swift -Xlinker -add_ast_path -Xlinker /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/Objects-normal/arm64/iosApp.swiftmodule -ObjC -lc++ -framework shared -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/iosApp.app-Simulated.xcent -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __ents_der -Xlinker /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/iosApp.app-Simulated.xcent.der -framework Pods_iosApp -Xlinker -no_adhoc_codesign -Xlinker -dependency_info -Xlinker /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/Objects-normal/arm64/iosApp_dependency_info.dat -o /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app/iosApp
ld: Undefined symbols:
  _FIRCLSExceptionRecordNSException, referenced from:
      _co_touchlab_crashkios_crashlytics_FIRCLSExceptionRecordNSException_wrapper0 in shared[5](resulx.o)
  _OBJC_CLASS_$_FIRCrashlytics, referenced from:
       in shared[8](resul{.o)
  _OBJC_CLASS_$_FIRExceptionModel, referenced from:
       in shared[8](resul{.o)
  _OBJC_CLASS_$_FIRStackFrame, referenced from:
       in shared[8](resul{.o)
clang: error: linker command failed with exit code 1 (use -v to see invocation)

CompileAssetCatalog /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp/iosApp/Preview\ Content/Preview\ Assets.xcassets /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp/iosApp/Assets.xcassets (in target 'iosApp' from project 'iosApp')
    cd /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp
    /Applications/Xcode.app/Contents/Developer/usr/bin/actool --output-format human-readable-text --notices --warnings --export-dependency-info /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/assetcatalog_dependencies --output-partial-info-plist /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/assetcatalog_generated_info.plist --app-icon AppIcon --compress-pngs --enable-on-demand-resources YES --development-region en --target-device iphone --target-device ipad --minimum-deployment-target 14.1 --platform iphonesimulator --compile /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp/iosApp/Preview\ Content/Preview\ Assets.xcassets /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp/iosApp/Assets.xcassets
/* com.apple.actool.compilation-results */
/Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/assetcatalog_generated_info.plist


ProcessInfoPlistFile /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app/Info.plist /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp/iosApp/Info.plist (in target 'iosApp' from project 'iosApp')
    cd /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp
    builtin-infoPlistUtility /Users/bkolarov/Development/blackbird/TestAnalytics/iosApp/iosApp/Info.plist -producttype com.apple.product-type.application -genpkginfo /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app/PkgInfo -expandbuildsettings -format binary -platform iphonesimulator -additionalcontentfile /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/iosApp.build/Debug-iphonesimulator/iosApp.build/assetcatalog_generated_info.plist -o /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app/Info.plist

warning: Run script build phase '[CP-User] Build shared' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'shared' from project 'Pods')
** BUILD FAILED **


The following build commands failed:
	Ld /Users/bkolarov/Development/blackbird/TestAnalytics/build/ios/Debug-iphonesimulator/iosApp.app/iosApp normal (in target 'iosApp' from project 'iosApp')
(1 failure)
okay, adding
pod("FirebaseCrashlytics")
fixed it
👍🏻 1
Thank you!
k

kpgalligan

10/12/2023, 1:00 PM
What's in your app
Podfile
?
However it turned out to blowup once the app was uploaded to the app store (or more specifically once app thinning was involved).
I'd like to hear more about that. We're in sort of weird territory here. I really want to figure out how to get the Kotlin side out of the business of enforcing the
FirebaseCrashlytics
dependency and version, as the main app usually does this. This whole thing kind of sucks, and I don't think the Kotlin team really thinks about this scenario much.
there are three issues I can think of with
pod("FirebaseCrashlytics")
. 1 - It will generate cinterop bindings for everything, which is just extra binary (not sure how much), 2 - It forces you to use Cocoapods in the Kotlin build, which is definitely not something everybody wants to do, and 3 - it creates a situation where the Kotlin code may compete with the main code for specifying ``FirebaseCrashlytics` version, which , in a large team/app, will likely create some drama.
23 Views