GitLiveApp / firebase-kotlin-sdk

A Kotlin-first SDK for Firebase
https://gitliveapp.github.io/firebase-kotlin-sdk/
Apache License 2.0
1.09k stars 154 forks source link

"framework not found FirebaseCore" build error #36

Closed agatap2 closed 3 years ago

agatap2 commented 4 years ago

I'm getting such error while trying to build my multiplatform project on macos:

> Task :linkMultiCoreDebugFrameworkIos FAILED
e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors

The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: framework not found FirebaseCore

My build.gradle file:

buildscript {
    ext {
        kotlin_version = "1.3.72"
        coroutine_version = "1.3.2"
        coroutines_play_services = "1.3.5"
        serializer_version = "0.13.0"
        androidx_lifecycle_version = "2.2.0"
        moko_mvvm_version = "0.6.0"
        mockk_version = "1.9.3"
        firebase_auth_version = "0.2.0"
    }
    repositories {
        google()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "com.android.tools.build:gradle:3.6.3"
        classpath 'com.google.gms:google-services:4.3.3'
    }
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android-extensions'

repositories {
    mavenLocal()
    jcenter()
    google()

    maven { url = uri("https://dl.bintray.com/icerockdev/moko") }
}

group 'com.aramso.curtains.backend'
version '0.0.1'

apply plugin: 'maven-publish'

def kotlinPluginId = 'org.jetbrains.kotlin.multiplatform'
final hasPlugin = project.getPlugins().hasPlugin(kotlinPluginId);
if (hasPlugin) {
    final Plugin plugin = project.getPlugins().getPlugin(kotlinPluginId)
    println 'Plugin already applied - version ' + plugin.properties['kotlinPluginVersion']
} else {
    apply plugin: "org.jetbrains.kotlin.multiplatform"
}

android {
    compileSdkVersion(29)

    defaultConfig {
        minSdkVersion(21)
        targetSdkVersion(29)
    }

    sourceSets {
        main {
            manifest.srcFile 'src/androidMain/AndroidManifest.xml'
            java.srcDirs = ['src/androidMain/kotlin']
            res.srcDirs = ['src/androidMain/resources']
        }
        test {
            java.srcDirs = ['src/androidTest/kotlin']
            res.srcDirs = ['src/androidTest/resources']
        }
    }

    testOptions.unitTests.includeAndroidResources = true

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
}

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
                              ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'ios') {
            binaries {
                framework('MultiCore')
            }
        }

        fromPreset(presets.android, 'android')
    }
    sourceSets {
        commonMain {
            dependencies {
                implementation kotlin('stdlib-common')

                // COROUTINES
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutine_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutines_play_services"

                // MOKO - MVVM
                api "dev.icerock.moko:mvvm:$moko_mvvm_version"

                // SERIALIZATION
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializer_version"

                // FIREBASE AUTH
                implementation "dev.gitlive:firebase-auth:$firebase_auth_version"
            }
        }
        commonTest {
            dependencies {
                implementation kotlin('test-common')
                implementation kotlin('test-annotations-common')

                implementation "io.mockk:mockk:$mockk_version"
            }
        }
        androidMain {
            dependencies {
                implementation kotlin('stdlib')

                implementation "androidx.lifecycle:lifecycle-extensions:$androidx_lifecycle_version"
                implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"

                // COROUTINES
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version"

                // SERIALIZATION
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializer_version"
            }
        }
        androidTest {
            dependencies {
                implementation kotlin('test')
                implementation kotlin('test-junit')
            }
        }
        iosMain {
        }
        iosTest {
        }
    }
}

configurations {
    compileClasspath
}

task packForXcode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
    final def framework = kotlin.targets.ios.binaries.getFramework("MultiCore", mode)

    inputs.property "mode", mode
    dependsOn framework.linkTask

    from { framework.outputFile.parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}

tasks.build.dependsOn packForXcode
nbransby commented 4 years ago

I think this is because firebase-auth depends on firebase-common which has this line it its cinterop def file: https://github.com/GitLiveApp/firebase-kotlin-sdk/blob/7ae2717beb27250103ee97459040f8277d429b5c/firebase-app/src/iosMain/c_interop/FirebaseCore.def#L4

For the tests we have this line which means it knows where to find it: https://github.com/GitLiveApp/firebase-kotlin-sdk/blob/7ae2717beb27250103ee97459040f8277d429b5c/firebase-app/build.gradle.kts#L66

@Reedyuk do you think we should include that for release builds too or should clients do some extra setup their end to get it working?

Reedyuk commented 4 years ago

i think we are going to need to, most people wont know to add it independently. The error messages are pretty hard to work out that this is the issue.

agatap2 commented 4 years ago

So for now, what should I do to build my project in IntelliJ?

nbransby commented 4 years ago

I think you need to add the linkerOps to your binaries like

linkerOpts("-F${firebase-kotlin-sdk-folder/build}/Firebase/FirebaseAnalytics")

agatap2 commented 4 years ago

After adding linerOpts I have another problem:

> Task :linkDebugExecutableIos FAILED
e: Could not find 'main' in '<root>' package.

When new release build will be available?

CoreyKaylor commented 4 years ago

I was able to get past this error by using the following. Auth part is just because I'm using both Auth and Core.

iosX64("ios") {
        binaries {
            framework {
                baseName = "shared"
                linkerOpts("-F/path-to-firebase-kotlin-sdk/build/Firebase/FirebaseAnalytics")
                linkerOpts("-F/path-to-firebase-kotlin-sdk/build/Firebase/FirebaseAuth")
            }
        }
    }

I assume the Frameworks get included with the published package? Guessing the real question I'm wondering about is does using this library for ios force us to download our own copy of the Firebase sdk to get things working in our own app? Hopefully not, but I'm not sure what the state of the kotlin native package publishing is.

agatap2 commented 4 years ago

Thanks for your solution but now I receive the same error for another task: :linkDebugTestIos

nbransby commented 4 years ago

I assume the Frameworks get included with the published package? Guessing the real question I'm wondering about is does using this library for ios force us to download our own copy of the Firebase sdk to get things working in our own app? Hopefully not, but I'm not sure what the state of the kotlin native package publishing is.

Yes it's a good question, I would say the state of kotlin native package publishing is fairly non-existent! In fact even using firebase in production code on iOS via Koltin Native presents a challenge at the moment as it's still early days. For example coroutines doesn't really work out of the box in KN.

Truth is, as it stands, I am not sure on the best way to publish and consume this SDK in KN. Would gladly accept guidance and suggestions on this.

CoreyKaylor commented 4 years ago

@nbransby I figured, I'm happy to help if / when I discover good options. It looks like the coroutine in 1.4-M2 for native gets a lot more functional so I'm not too worried about current state limitations as I've got quite a bit of runway and willing to deal with some of the early adoption pain.

nbransby commented 4 years ago

@CoreyKaylor looks like they gave up trying to get corountines to work on the current Kotlin Native memory management implementation.. https://blog.jetbrains.com/kotlin/2020/07/kotlin-native-memory-management-roadmap/

CoreyKaylor commented 4 years ago

I wouldn't say they gave up. They mentioned that they would continue to support what's there, but that they're re-evaluating a better path. All positive from my point of view because it was a bit painful depending on what you were trying to do.

CoreyKaylor commented 4 years ago

I tried out using the cocoapods plugin on 1.4.0-rc and it's much better than previous versions. I would definitely suggest going this route for the iosMain native libs.

https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-rc-released/

nbransby commented 4 years ago

Does it support the !use_frameworks flag now? As it didn't before and the firebase pods use that flag

CoreyKaylor commented 4 years ago

My main application has !use_frameworks in the Podfile. I've added both 'Firebase/Auth' and 'Firebase/Core' as pod dependencies in the gradle file and it's able to compile successfully and get loaded from my ios SwiftUI application.

Reedyuk commented 4 years ago

@CoreyKaylor - we can have a look at moving over to 1.4.0 when one of us gets a second to do it.

The other option is to put a PR with your changes and we can review and merge in.

CoreyKaylor commented 4 years ago

I think there's enough change in the gradle project system for 1.4.0 that will impact this project across JS / Native that it would be a bit much for me to personally take on with the time I have available.

nbransby commented 4 years ago

Ok encouraging news though, switching to pods would make things easier going forward

CoreyKaylor commented 4 years ago

I double checked my setup because I was going from memory. Just so I don't send you down the wrong path. The pod dependencies were 'FirebaseCore', 'FirebaseAuth', and 'FirebaseFirestore'.

nbransby commented 3 years ago

Presuming this can be closed now with the switch to Carthage? @Daeda88

CoreyKaylor commented 3 years ago

I think this is more about consuming the package from a gradle dependency, not local development. The carthage piece doesn't change that. Presumably with the cocoapod enhancements, that should fix the issue if people that depend on this library for iOS also use the cocoapod plugin, or do something similar with carthage on their project.

nbransby commented 3 years ago

Should be solved in 1,0,0

matanmarciano commented 3 years ago

I have this issue on 1.0.0 @nbransby


> Configure project :core
Kotlin Multiplatform Projects are an Alpha feature. See: https://kotlinlang.org/docs/reference/evolution/components-stability.html. To hide this message, add 'kotlin.mpp.stability.nowarn=true' to the Gradle properties.
The Kotlin source set androidAndroidTestRelease was configured but not added to any Kotlin compilation. You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.
See https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#connecting-source-sets
> Task :core:generateDefNTPKit
> Task :core:podDownload UP-TO-DATE
> Task :core:generateDummyFramework
> Task :core:podspec
> Task :core:podGenIOS
> Task :core:podSetupBuildNTPKitIphonesimulator
> Task :core:podBuildNTPKitIphonesimulator
> Task :core:cinteropNTPKitIos
> Task :core:compileKotlinIos
w: /Users/matanmarciano/projects/***/core/src/commonMain/kotlin/com/***/***/core/utilities/PositionSerializer.kt: (8, 2): This declaration is experimental and its usage should be marked with '@kotlinx.serialization.ExperimentalSerializationApi' or '@OptIn(kotlinx.serialization.ExperimentalSerializationApi::class)'
w: /Users/matanmarciano/projects/***/core/src/commonMain/kotlin/com/***/***/core/utilities/RoomStateSerializer.kt: (11, 2): This declaration is experimental and its usage should be marked with '@kotlinx.serialization.ExperimentalSerializationApi' or '@OptIn(kotlinx.serialization.ExperimentalSerializationApi::class)'
> Task :core:iosProcessResources NO-SOURCE
> Task :core:iosMainKlibrary
> Task :core:compileTestKotlinIos
> Task :core:linkDebugTestIos
e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors
The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: framework not found FirebaseDatabase
> Task :core:linkDebugTestIos FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':core:linkDebugTestIos'.
> Compilation finished with errors
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 1m 13s
10 actionable tasks: 10 executed
16:50:37: Task execution finished 'allTests'.
matanmarciano commented 3 years ago

@agatap2 any solution?

alexandru-g commented 3 years ago

@nbransby the issue still exists in 1.2.0.

vase4kin commented 3 years ago

Hello, everyone! Any updates on this? I face the same issue on 1.2.0.

YanivSos commented 3 years ago

I think you need to add the linkerOps to your binaries like

linkerOpts("-F${firebase-kotlin-sdk-folder/build}/Firebase/FirebaseAnalytics")

Hi. any idea where this 'firebase-kotlin-sdk-folder' directory is? I can't find it....

antanas-radzevicius-tg commented 2 years ago

My main application has !use_frameworks in the Podfile. I've added both 'Firebase/Auth' and 'Firebase/Core' as pod dependencies in the gradle file and it's able to compile successfully and get loaded from my ios SwiftUI application.

Hey, maybe you could share working code? I am having really bad days while trying to figure this out :) Thanks!

izadiegizabal commented 1 year ago

Did anyone manage to get this working? I am still encountering the ld: framework not found FirebaseAuth error and I can't really find the path that @CoreyKaylor is suggesting :(

androks commented 1 year ago

@nbransby I am using dev.gitlive:firebase-config:1.7.2 And I got

e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors

The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: framework not found FirebaseABTesting
Panzenbaby commented 1 year ago

I was able to fix it by adding the pod separately (I wanted to use just auth but I had to add core as well).

cocoapods {
    …
    pod("FirebaseCore")
    pod("FirebaseAuth")
}

With that I got an error java.lang.Error: Linking globals named 'kniprot_cocoapods_FirebaseAuth0': symbol multiply defined!

which I could solve by adding a additional parameter linkOnly (that brought me the solution)

cocoapods {
    …
    pod("FirebaseCore", linkOnly = true)
    pod("FirebaseAuth", linkOnly = true)
}