AlecKazakova/kotlin-native-cocoapods

Directories with a dash in their name generate a framework file with an underscore which fails

jrocharodrigues opened this issue · 17 comments

Hi,

I've followed the instructions provided in the README to integrate this plugin in my multiplatform project.

After that, i can build the xcode project with success and import the framework to m xcode project, but i think the task is not compiling my code, because it runs very fast (compared to the old method of using the packForXcode task) and when inspecting the framework headers all i see is the Dummy.h form the dummy framework of the project.

Is there any extra step i need to do in the xcode configuration or something?

Thanks in advance

can you paste your build.gradle and .podspec files here so I can take a look?

Pod::Spec.new do |spec|
  spec.name                     = 'sdk'
  spec.version                  = '0.0.1-ALPHA-LOCAL'
  spec.homepage                 = 'www.mycompany.com'
  spec.source                   = { :git => "Not Published", :tag => "Cocoapods/#{spec.name}/#{spec.version}" }
  spec.ios.deployment_target    = '10.0'
  spec.authors                  = 'Auhtor'
  spec.license                  = ...
  spec.summary                  = '...'
  spec.ios.vendored_frameworks  = "build/#{spec.name}.framework"

  spec.prepare_command = <<-SCRIPT
    set -ev
    ../gradlew  -Pframework=#{spec.name}.framework initializeFramework --stacktrace
  SCRIPT

  spec.script_phases = [
    {
      :name => 'Build sdk',
      :shell_path => '/bin/sh',
      :script => <<-SCRIPT
        set -ev
        REPO_ROOT=`realpath "$PODS_TARGET_SRCROOT"`
        rm -rf "${REPO_ROOT}/#{spec.name}.framework"*
        $REPO_ROOT/../gradlew  -p "$REPO_ROOT" "createIos${CONFIGURATION}Artifacts"
      SCRIPT
    }
  ]
end
apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'
apply plugin: 'com.alecstrong.cocoapods'
apply plugin: 'com.android.library'
apply plugin: 'maven'
apply plugin: 'maven-publish'

android {
    compileSdkVersion 28

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    // TODO replace with https://issuetracker.google.com/issues/72050365 once released.
    libraryVariants.all {
        it.generateBuildConfig.enabled = false
    }


}

task sourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}

artifacts {
    archives sourcesJar
}

publishing {
    publications {
        android(MavenPublication) {
            artifact("$buildDir/../build/outputs/aar/sdk-release.aar")
            artifact sourcesJar
            artifactId 'sdk-android'

            //The publication doesn't know about our dependencies, so we have to manually add them to the pom
            pom.withXml {
                def dependenciesNode = asNode().appendNode('dependencies')

                //Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
                configurations.compile.allDependencies.each {
                    def dependencyNode = dependenciesNode.appendNode('dependency')
                    dependencyNode.appendNode('groupId', it.group)
                    dependencyNode.appendNode('artifactId', it.name)
                    dependencyNode.appendNode('version', it.version)
                }
            }
        }
    }
}

kotlin {
    targets {
        fromPreset(presets.android, 'android')

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

        fromPreset(iOSTarget, 'ios') {
            compilations.main.outputKinds('FRAMEWORK')
        }*/
        targetFromPreset(cocoapodsPreset, 'ios')
    }
    sourceSets {
        commonMain {
            dependencies {
                //implementation "com.jakewharton.timber:timber-common:$timber_version"

               // implementation "com.github.florent37:multiplatform-log:1.0.1"

                implementation 'org.jetbrains.kotlin:kotlin-stdlib'
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
                implementation "io.ktor:ktor-client-core:$ktor_version"
                implementation "io.ktor:ktor-client-json:$ktor_version"
                implementation "io.ktor:ktor-client-logging:$ktor_version"

                api "com.soywiz:klock:$klock_version"


            }
        }
        commonTest {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-test-common"
                implementation "org.jetbrains.kotlin:kotlin-test-annotations-common"
            }
        }
        androidMain {

            dependencies {
               // implementation "com.jakewharton.timber:timber-jdk:$timber_version"

//                implementation "com.github.florent37:multiplatform-log-android:1.0.1"

                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"

                implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
                implementation "io.ktor:ktor-client-json-jvm:$ktor_version"
                implementation "io.ktor:ktor-client-logging-jvm:$ktor_version"


            }
        }
        androidTest {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-test'
                implementation 'org.jetbrains.kotlin:kotlin-test-junit'
            }
        }
        iosMain {
            dependencies {
               // implementation "com.jakewharton.timber:timberNative:$timber_version"
                //implementation "com.github.florent37:multiplatform-log-ios:1.0.1"

                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

                    
                implementation "io.ktor:ktor-client-ios:$ktor_version"
                implementation "io.ktor:ktor-client-core-native:$ktor_version"
                implementation "io.ktor:ktor-client-json-native:$ktor_version"
                implementation "io.ktor:ktor-client-logging-native:$ktor_version"

            }
        }

    }


}

// workaround for https://youtrack.jetbrains.com/issue/KT-27170
/*configurations {
    compileClasspath
}*/

cocoapods {
    version = "0.0.1-ALPHA-LOCAL" // Defaults to "1.0.0-LOCAL"
    homepage = "www.mycompany.com"  // Default to empty
    deploymentTarget = "10.0" // Defaults to "10.0"
    authors = "Author" // Defaults to empty
    license = "..." // Defaults to empty
    summary = "..." // Defaults to empty
    daemon = true // Defaults to false
}
/*
task packForXCode(type: Sync) {
   // final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
    final String frameworkDir = project.findProperty("XCODE_BUILD_DIR")

    inputs.property "mode", mode
    dependsOn kotlin.targets.ios.compilations.main.linkTaskName("FRAMEWORK", mode)

    from { kotlin.targets.ios.compilations.main.getBinary("FRAMEWORK", mode).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
*/

can you try removing the

cocoapods {
   ...
}

block entirely from your build.gradle and regenerate the podspec, pod install, xcode build?

ok i'll try that

Hi,
I removed the cocoapods block, form the build.gradle file and generated a new .podspec file.

When i executing pod install i got 3 missing required attribute errors for 'authors', 'homepage' and 'summary'.

I added those fields manually an executed pod install again, this time with success.

I build the xcode project agian but the result was the same, the build was very fast, and the framework headers is the Dummy.h.

hmmm alright.

Next thing would be - can you share what your directory looks like? Specifically curious where the xcodeproj is, where gradlew is and where the build.gradle and .podspec file are.

Another thing, can you try running ./gradlew createIosDebugArtifacts from the command line and see if thats successful. If so check the .framework file in the kotlin projects build directory and see if it still has Dummy.h in it

Hi,

When i run ./gradlew createIosDebugArtifacts from the command line i get this error:

>Task :smartwifi-sdk:createIosDebugArtifacts
fatal error: lipo: can't open input file: /Users/jrodrigues/Documents/iOS/WiFiTest/WiFiTest/External/wifisdk/sdk/build/bin/ios/debugFramework/sdk.framework.dSYM/Contents/Resources/DWARF/sdk (No such file or directory)
fatal error: lipo: can't open input file: /Users/jrodrigues/Documents/iOS/WiFiTest/WiFiTest/External/wifisdk/sdk/build/bin/ios/debugFramework/sdk.framework/sdk (No such file or directory)



BUILD SUCCESSFUL in 1m 16s
3 actionable tasks: 3 executed

When checking the build folder the sdk.framework still has the Dummy.h file.

Inside the folder ios/debugFramework/ the sdk.framework has the correct header file the sdk.h and the file sdk is present

okay good to know, thats getting closer to the problem.

which directory is the .podspec file in, and which directory is build.gradle in?

Hi,
Here's a screenshot of my project dir.
I think all the relevant files are visible, if not i can put another one.

screenshot

Thanks for all the help

can you also expand the build/bin/ directory?

can you try

./gradlew clean createIosDebugArtifacts?

The directories actually all look correct so it's confusing what this error means:
fatal error: lipo: can't open input file: /Users/jrodrigues/Documents/iOS/WiFiTest/WiFiTest/External/wifisdk/sdk/build/bin/ios/debugFramework/sdk.framework/sdk (No such file or directory)

since it looks like /Users/jrodrigues/Documents/iOS/WiFiTest/WiFiTest/External/wifisdk/sdk/build/bin/ios/debugFramework/sdk.framework/sdk exists, unless im reading something wrong. I guess make sure that file does in fact exist after the clean create run?

ok, i'll try that

Hi,

I think i found the "issue".
When i shared the info with you i had to edit some info due to my company restrictions.
Part of the info i edited was the directory name of the multi-platform project, which i thought was not relevant to the issue.

In the info i shared i named the multi-platform project sdk when in reality it was companyproject**-**sdk.
Now when testing ./gradlew clean createIosDebugArtifacts i got the lipo error again:
fatal error: lipo: can't open input file: /Users/jrodrigues/Documents/iOS/WiFiTest/WiFiTest/External/wifisdk/sdk/build/bin/ios/debugFramework/companyproject-sdk.framework/companyproject-sdk (No such file or directory)
But when i look into the bin directory the framework file is named companyproject_sdk.framework with an underscore instead of a dash. The same is true for the file inside the framework.

I renamed the directories inside my project, removing the -, and everything worked as supposed.

I'm sorry for the time you lost due to this omission in the reports, and once againg thanks for all the support.

PS: I didn't close the issue because i don't know if it is supposed to work with '-' or not

I'd still call that an issue! Given it was so hard to track down, we can at least detect this scenario in the plugin and throw an error saying that there shouldn't be a - in the directory name or something else. Thanks for tracking iit down

No problem, thanks for your help :)