JetBrains / kotlin-native

Kotlin/Native infrastructure
Apache License 2.0
7.02k stars 564 forks source link

Cocoapod sample #3530

Closed dbof10 closed 4 years ago

dbof10 commented 5 years ago

I tried Cocoapod sample

./gradlew build

Execution failed for task ':cinteropAFNetworkingIOS'.
> Cannot perform cinterop processing for AFNetworking: cannot determine headers location.

  Probably the build is executed from command line.
  Note that a Kotlin/Native module using CocoaPods dependencies can be built only from Xcode.

Another issue

my gradle I'm using 5.6.1

plugins {
    id("org.jetbrains.kotlin.multiplatform")
    id("org.jetbrains.kotlin.native.cocoapods")
}
kotlin {
    targets {
        fromPreset(determineIosPreset(), 'ios') {
            binaries {
                framework()
            }
        }

        fromPreset(presets.jvm, 'jvm')
    }

    sourceSets {
        commonMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
            }
        }
        jvmMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
            }
        }
    }
}

it throws

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/.../build.gradle' line: 9

* What went wrong:
A problem occurred evaluating project ':ebisu'.
> Cannot create binary debugFramework: binary with such a name already exists

line 9 which is framework()

 binaries {
                framework()
            }
themartorana commented 5 years ago

Re: Cannot create binary debugFramework - I'm pretty sure the Cocoapods plugin is creating those targets for iOS dynamically, so having them in your build.gradle file specifically is considered a dupe entry.

Re: cinteropAFNetworkingIOS and no headers, I'm running into the same issues using the built-in K/N iOS/Android app template and every Obj-c dependency I've tried.

artdfel commented 5 years ago

Hello there! About the problem with the AFNetworking, what exactly you were trying to do? Step-by-step instruction would help a lot. Also, I can recommend you to have a look at this SO question. And +1 on @themartorana on the framework creation. Cocoapods plugin does it by itself, so there is no need to do it manually in the script.

dbof10 commented 5 years ago

I'm trying to build kotlin native with cocoapod in the sample code. I will try the link you sent later

yurykorzun commented 5 years ago

Based on this https://github.com/JetBrains/kotlin/blob/3a234d46ed6554053fb6a263a017013f0871abea/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/cocoapods/KotlinCocoapodsPlugin.kt

project.findProperty(CFLAGS_PROPERTY)?.toString()?.let { args ->
                        // Xcode quotes around paths with spaces.
                        // Here and below we need to split such paths taking this into account.
                        interop.compilerOpts.addAll(args.splitQuotedArgs())
                    }
                    project.findProperty(HEADER_PATHS_PROPERTY)?.toString()?.let { args->
                        interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" })
                    }
                    project.findProperty(FRAMEWORK_PATHS_PROPERTY)?.toString()?.let { args ->
                        interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-F$it" })
                    }

                    // Show a human-readable error messages if the interop is created
                    // but there are no parameters set by Xcode or manually by user (KT-31062).
                    interopTask.doFirst { _ ->
                        val hasCompilerOpts = interop.compilerOpts.isNotEmpty()
                        val hasHeaderSearchPath = interop.includeDirs.let {
                            !it.headerFilterDirs.isEmpty || !it.allHeadersDirs.isEmpty
                        }

                        check(hasCompilerOpts || hasHeaderSearchPath) {
                            """
                                |Cannot perform cinterop processing for ${pod.name}: cannot determine headers location.
                                |
                                |Probably the build is executed from command line.
                                |Note that a Kotlin/Native module using CocoaPods dependencies can be built only from Xcode.
                                |
                                |See details at https://kotlinlang.org/docs/reference/native/cocoapods.html#interoperability.
                            """.trimMargin()
                        }
                    }

It looks like the gradle plugin cannot find the path to headers. The parameter kotlin.native.cocoapods.paths.headers in the build script is empty.

I added a script build phase to test parameters and headers are indeed not provided.

Any suggestions on how to fix it?

Another question - do we need both to execute both copyFramework and syncFramework tasks in an xcode project?

yurykorzun commented 5 years ago

It looks like the AFNetworking sample works. In my case, I left copyFramework build step in the main XCode project after I added syncFramework step in the cocoapods project. It would be helpful to have better error messaging in the cocoapods plugin.

ilmat192 commented 5 years ago

I added a script build phase to test parameters and headers are indeed not provided. Any suggestions on how to fix it?

CocoaPods provides the HEADER_SEARCH_PATHS only if use_modular_headers! is specified. But this example uses the use_frameworks! mode so this is ok that HEADER_SEARCH_PATHS is empty and there is no need to fix it. In this mode FRAMEWORK_SEARCH_PATHS is used to determine header location.

Could you please provide more details about your issue? Do you get the message above ("Cannot perform cinterop processing for...") during an Xcode build? If yes, what version of Xcode and CocoaPods do you use?

Another question - do we need both to execute both copyFramework and syncFramework tasks in an xcode project?

No, there is no need in any additional build steps or gradle tasks. All configuration should be performed by CocoaPods when pod install is executed.

fluxxion82 commented 4 years ago

I'm having the same issue with the cinteropAFNetworkingIOS task and AFNetworking headers not being found. I've cloned the repo, and when I try building the kotlin/native code in Intellij, I get the error:

Execution failed for task ':cinteropAFNetworkingIOS'.
> Cannot perform cinterop processing for module AFNetworking: cannot determine headers location.

And when I try to clean and build the iOS app, I get the error

ld: warning: directory not found for option '-F/Users/me/Library/Developer/Xcode/DerivedData/ios-app-bqdkiuwfyvobplgepabxiutmzyqv/Build/Products/Debug-iphonesimulator/AFNetworking'
ld: framework not found AFNetworking

If I run the build.sh script in the root, I get an error about the kotlin.native.home property containing an incorrect path, so I commented it out in the gradle.properties file in the kotlin-library, and then build.sh runs successfully, however, I still get the two errors above when trying to rebuild the projects in the IDEs'. Commenting out this line is the only change I make, although, after running build.sh, some changes are made to the ios-app/ios-app.xcodeproj/project.pbxproj file, which are as follows:

                        files = (
                        );
                        inputFileListPaths = (
-                       );
-                       inputPaths = (
-                               "${PODS_ROOT}/Target Support Files/Pods-ios-app/Pods-ios-app-frameworks.sh",
-                               "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
+                               "${PODS_ROOT}/Target Support Files/Pods-ios-app/Pods-ios-app-frameworks-${CONFIGURATION}-input-files.xcfilelist",
                        );
                        name = "[CP] Embed Pods Frameworks";
                        outputFileListPaths = (
-                       );
-                       outputPaths = (
-                               "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
+                               "${PODS_ROOT}/Target Support Files/Pods-ios-app/Pods-ios-app-frameworks-${CONFIGURATION}-output-files.xcfilelist",
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;

Any ideas?

ilmat192 commented 4 years ago

I've cloned the repo, and when I try building the kotlin/native code in Intellij, I get the error:

Execution failed for task ':cinteropAFNetworkingIOS'.
> Cannot perform cinterop processing for module AFNetworking: cannot determine headers location.

It's an expected error because currently a Kotlin module depending on a CocoaPods library can be built from Xcode only: https://kotlinlang.org/docs/reference/native/cocoapods.html#current-limitations.

And when I try to clean and build the iOS app, I get the error

ld: warning: directory not found for option '-F/Users/me/Library/Developer/Xcode/DerivedData/ios-app-bqdkiuwfyvobplgepabxiutmzyqv/Build/Products/Debug-iphonesimulator/AFNetworking'
ld: framework not found AFNetworking

Did you run pod install before building the iOS app?

fluxxion82 commented 4 years ago

Thanks for the reply.

I've cloned the repo, and when I try building the kotlin/native code in Intellij, I get the error:

Execution failed for task ':cinteropAFNetworkingIOS'.
> Cannot perform cinterop processing for module AFNetworking: cannot determine headers location.

It's an expected error because currently a Kotlin module depending on a CocoaPods library can be built from Xcode only: https://kotlinlang.org/docs/reference/native/cocoapods.html#current-limitations.

Oh, I see. That's unfortunate. Do you think I'll run into similar issues if I can import a library with carthage instead? It looked like someone had used Carthage somehow to use am iOS framework in a Kotlin MPP project, although the write up wasn't super clear, however, it looks like the limitation is only with this CocoaPods plugin and not the cinterop task, is that correct?

And when I try to clean and build the iOS app, I get the error

ld: warning: directory not found for option '-F/Users/me/Library/Developer/Xcode/DerivedData/ios-app-bqdkiuwfyvobplgepabxiutmzyqv/Build/Products/Debug-iphonesimulator/AFNetworking'
ld: framework not found AFNetworking

Did you run pod install before building the iOS app?

Yes, I did try to run that manually but no difference. That command is being calling in the build.sh file, which runs successfully. This build.sh file should handle all the steps, right? I have been trying run all the necessary commands and everything manually but I get the same error.

ilmat192 commented 4 years ago

Hi @fluxxion82. Sorry for the delay with the answer.

Do you think I'll run into similar issues if I can import a library with carthage instead?

We don't provide a plugin for Carthage integration so you'll have to manually configure cinterop tasks. You can manually configure cinterop tasks for CocoaPods too. It's unlikely that you run into the same problems with the manual configuration but it's much more complicated than using the CocoaPods plugin.

the limitation is only with this CocoaPods plugin and not the cinterop task, is that correct?

Yes, the CocoaPods plugin configures the cinterop task based on data obtained from the Xcode project. So you do can build the project from IDEA or from a terminal, if you provide these data manually. To do this, make the following steps:

  1. Run ./gradlew podspec and pod install as said in the readme.

  2. Run the build from Xcode. Open the logs tab and find the line Run custom shell script '[CP-User] Build kotlin_library'

  3. Expand this line as shown in the screenshot and copy values of the following environment variables

    • OTHER_CFLAGS
    • HEADER_SEARCH_PATHS
    • FRAMEWORK_SEARCH_PATHS Screenshot 2020-07-14 at 19 20 08
  4. Specify the copied values to the following Gradle project properties in the gradle.properties file:

    • kotlin.native.cocoapods.cflags=$OTHER_CFLAGS
    • kotlin.native.cocoapods.paths.headers=$HEADER_SEARCH_PATHS
    • kotlin.native.cocoapods.paths.frameworks=$FRAMEWORK_SEARCH_PATHS

After these steps the build can be started from CLI or from IDEA.

We are working on lifting this limitation: https://youtrack.jetbrains.com/issue/KT-30841. With Kotlin 1.4-M3 you already can run a build from CLI or IDEA without this manual build settings magic.

This build.sh file should handle all the steps, right?

Yes, it should. But I failed to reproduce the error with

ld: warning: directory not found for option '-F/Users/me/Library/Developer/Xcode/DerivedData/ios-app-bqdkiuwfyvobplgepabxiutmzyqv/Build/Products/Debug-iphonesimulator/AFNetworking'
ld: framework not found AFNetworking

Could you please share your full build log?

P.S. The changes made to ios-app/ios-app.xcodeproj/project.pbxproj after running pod install are probably ok and caused by using a newer CocoaPods version.

fluxxion82 commented 4 years ago

Yes, the CocoaPods plugin configures the cinterop task based on data obtained from the Xcode project. So you do can build the project from IDEA or from a terminal, if you provide these data manually. To do this, make the following steps:

Run ./gradlew podspec and pod install as said in the readme. Run the build from Xcode. Open the logs tab and find the line Run custom shell script '[CP-User] Build kotlin_library' Expand this line as shown in the screenshot and copy values of the following environment variables OTHER_CFLAGS HEADER_SEARCH_PATHS FRAMEWORK_SEARCH_PATHS

So I still can't successfully fun the iOS app regardless if I run build.sh or manually do the steps that you describe above. However, when I run the steps manually, I get some different errors. I don't remember seeing these before; I pulled changes from the repo and started fresh with latest changes. Here is the build output after manually running the steps, ./gradlew podspec and pod install (basically following all of the readme steps):

build-manual_ios-app_2020-07-14T22-41-07.txt

and here is the build output after running ./build.sh, which runs successfully:

build-sh_ios-app_2020-07-14T22-39-28.txt

In either attempt, I don't see the line Run custom shell script '[CP-User] Build kotlin_library' in the logs. Lastly, I want to show what the diff is on the ios-app project settings when I try to build everything because I really feel like these shouldn't be getting changed:

diff --git a/samples/cocoapods/ios-app/ios-app.xcodeproj/project.pbxproj b/samples/cocoapods/ios-app/ios-app.xcodeproj/project.pbxproj
index fb3aa55d9..3a7f6227f 100644
--- a/samples/cocoapods/ios-app/ios-app.xcodeproj/project.pbxproj
+++ b/samples/cocoapods/ios-app/ios-app.xcodeproj/project.pbxproj
@@ -164,16 +164,11 @@
                        files = (
                        );
                        inputFileListPaths = (
-                       );
-                       inputPaths = (
-                               "${PODS_ROOT}/Target Support Files/Pods-ios-app/Pods-ios-app-frameworks.sh",
-                               "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
+                               "${PODS_ROOT}/Target Support Files/Pods-ios-app/Pods-ios-app-frameworks-${CONFIGURATION}-input-files.xcfilelist",
                        );
                        name = "[CP] Embed Pods Frameworks";
                        outputFileListPaths = (
-                       );
-                       outputPaths = (
-                               "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
+                               "${PODS_ROOT}/Target Support Files/Pods-ios-app/Pods-ios-app-frameworks-${CONFIGURATION}-output-files.xcfilelist",
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
fluxxion82 commented 4 years ago

My Xcode was out of date, which I noticed after looking at your screen shot in more detail, so I was hoping maybe that had something to do with not being able to run the ios app, but still the same errors. Here are the build logs: Build-sh_ios-app_2020-07-14T23-53-37.txt

ilmat192 commented 4 years ago

In either attempt, I don't see the line Run custom shell script '[CP-User] Build kotlin_library' in the logs.

It seems that for some reason the Xcode doesn't build dependencies of ios-app: AFNetworking and kotlin_lib. I mean the compile task was not even started in your logs.

Your build.sh log contains only the part related to Xcode build. Could you please provide the full build.sh log with first two steps (./gradlew podspec and pod install)?

When you run the build manually, do you open ios-app.xcodeproj or ios-app.xcworkspace?

Lastly, I want to show what the diff is on the ios-app project settings when I try to build everything because I really feel like these shouldn't be getting changed:

No, it seems ok. I observe the same changes while the build finishes successfully. I suppose it's caused by a newer CocoaPods version that the version used when this sample was created. BTW what CocoaPods version do you use?

fluxxion82 commented 4 years ago

Your build.sh log contains only the part related to Xcode build. Could you please provide the full build.sh log with first two steps (./gradlew podspec and pod install)?

Ah, right, sorry. Here is the logs from the build.sh script:

build-sh_logs_200719.txt

When you run the build manually, do you open ios-app.xcodeproj or ios-app.xcworkspace?

I've been opening ios-app.xcodeproj. I just tried to open ios-app.xcworkspace and build that, and I see the "Build kotlin_library", although it seems it's the only build target that is run. It looks like the task :cinteropAFNetworkingIOS is failing because of an "Unresolved reference: UIAxis", which I don't know what means yet. Here are the logs from this build:

Build_ios_xcworkspace_2020-07-19T13-25-17.txt

I see the lines kotlin.native.cocoapods.cflags=$OTHER_CFLAGS kotlin.native.cocoapods.paths.headers=$HEADER_SEARCH_PATHS kotlin.native.cocoapods.paths.frameworks=$FRAMEWORK_SEARCH_PATHS

but I don't see the values for those variables set anywhere. Should I be opening the .xcworkspace files? Thanks for your help.

ilmat192 commented 4 years ago

Here is the logs from the build.sh script:

This log seems ok. I see that both Gradle and Xcode builds finishes successfully.

Should I be opening the .xcworkspace files?

Yes, just like in any project with CocoaPods. Otherwise Xcode will not be able to build pods you depends on.

It looks like the task :cinteropAFNetworkingIOS is failing because of an "Unresolved reference: UIAxis", which I don't know what means yet.

It's a known problem observed on K/N 1.3.7x with Xcode 11.4. You can workaround it by adding the following snippet to kotlin-library/build.gradle.kts:

repositories {
    maven {
        setUrl("https://kotlin.bintray.com/native-xcode")
    }
}

kotlin.sourceSets["commonMain"].dependencies {
    implementation("org.jetbrains.kotlin.native.xcode:kotlin-native-xcode-11-4-workaround:1.3.72.0")
}

I see the lines kotlin.native.cocoapods.cflags=$OTHER_CFLAGS kotlin.native.cocoapods.paths.headers=$HEADER_SEARCH_PATHS kotlin.native.cocoapods.paths.frameworks=$FRAMEWORK_SEARCH_PATHS but I don't see the values for those variables set anywhere

There are many lines like

export ACTION=build
export AD_HOC_CODE_SIGNING_ALLOWED=YES
export ALTERNATE_GROUP=staff
export ALTERNATE_MODE=u+w,go-w,a+rX
...

in the log. This list contains values for these variables too.

fluxxion82 commented 4 years ago

It looks like the task :cinteropAFNetworkingIOS is failing because of an "Unresolved reference: UIAxis", which I don't know what means yet.

It's a known problem observed on K/N 1.3.7x with Xcode 11.4. You can workaround it by adding the following snippet to kotlin-library/build.gradle.kts:


repositories {
    maven {
        setUrl("https://kotlin.bintray.com/native-xcode")
    }
}

kotlin.sourceSets["commonMain"].dependencies {
    implementation("org.jetbrains.kotlin.native.xcode:kotlin-native-xcode-11-4-workaround:1.3.72.0")
}

Awesome, this does the trick. Thanks for your help.

fluxxion82 commented 4 years ago

Sorry, there is one thing to note; when I rebuild the project in Intellij, I still get `Execution failed for task ':submodulea:cinteropAFNetworkingIos'.

Cannot perform cinterop processing for module AFNetworking: cannot determine headers location.`

Running the build.sh script and running the iOS app works fine, but I can't rebuild the project properly. Is this expected? Is there a 1.4 version of this library too or is this workaround expected to be fixed in that version?

ilmat192 commented 4 years ago

when I rebuild the project in Intellij, I still get `Execution failed for task ':submodulea:cinteropAFNetworkingIos'.

Yes, this is expected because only building from Xcode is supported in Kotlin 1.3.x.

But this limitation will be lifted in 1.4 and you'll be able to build such projects from IDEA too. You already can try this by updating to 1.4-RC. See more in the RC blog post.

Running the build.sh script and running the iOS app works fine, but I can't rebuild the project properly.

Do you mean rebuilding from IDEA or rebuilding from Xcode/build.sh?

Is there a 1.4 version of this library too or is this workaround expected to be fixed in that version?

This problem is fixed in 1.4.

yackermann commented 4 years ago

@ilmat192

I am facing similar issues even with 1.4-rc

> Configure project :kotlin-library
Kotlin Multiplatform Projects are an experimental feature.

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/herrjemand/Github/LoginID/samples/kotlin-with-cocoapods-sample/kotlin-library/build.gradle.kts' line: 48

* What went wrong:
Cannot create binary debugFramework: binary with such a name already exists

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
java.lang.IllegalArgumentException: Cannot create binary debugFramework: binary with such a name already exists
    at org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer.createBinaries(KotlinNativeBinaryContainer.kt:132)
    at org.jetbrains.kotlin.gradle.dsl.AbstractKotlinNativeBinaryContainer.framework(AbstractKotlinNativeBinaryContainer.kt:274)
    at org.jetbrains.kotlin.gradle.dsl.AbstractKotlinNativeBinaryContainer.framework$default(AbstractKotlinNativeBinaryContainer.kt:273)
    at Build_gradle$2$2$1.invoke(build.gradle.kts:48)
    at Build_gradle$2$2$1.invoke(build.gradle.kts:1)
    at org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetWithBinaries.binaries(KotlinTargetWithBinaries.kt:22)
    at Build_gradle$2$2.invoke(build.gradle.kts:47)
    at Build_gradle$2$2.invoke(build.gradle.kts:1)
    at org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtensionKt.configureOrCreate(KotlinMultiplatformExtension.kt:75)
    at org.jetbrains.kotlin.gradle.dsl.KotlinTargetContainerWithPresetFunctions$DefaultImpls.iosX64(KotlinTargetContainerWithPresetFunctions.kt:137)
    at org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension.iosX64(KotlinMultiplatformExtension.kt:15)
    at Build_gradle$2$iOSTarget$2.invoke(build.gradle.kts:44)
    at Build_gradle$2$iOSTarget$2.invoke(build.gradle.kts:1)
    at Build_gradle$2.execute(build.gradle.kts:46)
    at Build_gradle$2.execute(build.gradle.kts:1)
    at org.gradle.internal.extensibility.ExtensionsStorage$ExtensionHolder.configure(ExtensionsStorage.java:173)
    at org.gradle.internal.extensibility.ExtensionsStorage.configureExtension(ExtensionsStorage.java:64)
    at org.gradle.internal.extensibility.DefaultConvention.configure(DefaultConvention.java:194)
    at org.gradle.kotlin.dsl.Accessors8rihyt52ywg47pk3ez2ijmcwzKt.kotlin(Unknown Source)
    at Build_gradle.<init>(Unknown Source)
    at Program.execute(Unknown Source)
    at org.gradle.kotlin.dsl.execution.Interpreter$ProgramHost.eval(Interpreter.kt:502)
    at org.gradle.kotlin.dsl.execution.Interpreter$ProgramHost.evaluateSecondStageOf(Interpreter.kt:418)
    at Program.execute(Unknown Source)
    at org.gradle.kotlin.dsl.execution.Interpreter$ProgramHost.eval(Interpreter.kt:502)
    at org.gradle.kotlin.dsl.execution.Interpreter.eval(Interpreter.kt:200)
    at org.gradle.kotlin.dsl.provider.StandardKotlinScriptEvaluator.evaluate(KotlinScriptEvaluator.kt:119)
    at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:51)
    at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:36)
    at org.gradle.kotlin.dsl.provider.KotlinScriptPlugin.apply(KotlinScriptPlugin.kt:34)
    at org.gradle.configuration.BuildOperationScriptPlugin$1$1.run(BuildOperationScriptPlugin.java:69)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:395)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:387)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:84)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:66)
    at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:63)
    at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:49)
    at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:63)
    at org.gradle.configuration.project.BuildScriptProcessor$1.run(BuildScriptProcessor.java:45)
    at org.gradle.internal.Factories$1.create(Factories.java:26)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:245)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:226)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:42)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
    at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:35)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:102)
    at org.gradle.internal.Factories$1.create(Factories.java:26)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:180)
    at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:271)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:265)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:226)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:91)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:395)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:387)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:84)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:63)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:710)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:145)
    at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:36)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:64)
    at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:61)
    at org.gradle.configuration.BuildOperatingFiringProjectsPreparer$ConfigureBuild.run(BuildOperatingFiringProjectsPreparer.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:395)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:387)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:84)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.configuration.BuildOperatingFiringProjectsPreparer.prepareProjects(BuildOperatingFiringProjectsPreparer.java:40)
    at org.gradle.initialization.DefaultGradleLauncher.prepareProjects(DefaultGradleLauncher.java:220)
    at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:155)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:140)
    at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:120)
    at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:74)
    at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:67)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:180)
    at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
    at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:67)
    at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:56)
    at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:60)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
    at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:51)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:45)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
    at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:80)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:87)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:55)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:60)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:38)
    at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
    at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:56)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:68)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)

* Get more help at https://help.gradle.org

BUILD FAILED in 3s

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warnings

And my build.gradle.kts

plugins {
    kotlin("multiplatform") version "1.4.0-rc"
    kotlin("native.cocoapods") version "1.4.0-rc"
}

group = "org.jetbrains.kotlin.sample"
version = "1.0-SNAPSHOT"

repositories {
    jcenter()
    mavenCentral()
    maven { setUrl("https://kotlin.bintray.com/kotlin/kotlinx") }
    maven { setUrl("https://dl.bintray.com/kotlin/kotlin-dev") }
    maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
    maven { setUrl("https://dl.bintray.com/kotlin/ktor") }
}
kotlin {
    ios()

    cocoapods {
        summary = "Kotlin sample project with CocoaPods dependencies"
        homepage = "https://github.com/Kotlin/kotlin-with-cocoapods-sample"

        ios.deploymentTarget = "13.5"

        //Example of usage remote Cocoapods dependency from Cocoapods repository
        pod("AFNetworking", "~> 4.0.0")

        //Example of usage remote Pod declared as Subspec
        pod("SDWebImage/MapKit")

        //Example of usage local Cocoapods dependency
        pod("pod_dependency", "1.0", project.file("../pod_dependency/pod_dependency.podspec"))

        //Example of usage local Pod declared as Subspec
        pod("subspec_dependency/Core", "1.0", project.file("../subspec_dependency/subspec_dependency.podspec"))

    }

    val iOSTarget: (String, org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget.() -> Unit) -> org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget =
            if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
                ::iosArm64
            else
                ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "SharedCode"
            }
        }
    }

}
ilmat192 commented 4 years ago

@herrjemand this is another error. The CocoaPods plugin automatically creates a framework so additional construction

binaries {
    framework { ... }
}

causes the error

binary with such a name already exists

To fix this error, remove the binaries block from your build script. You also can remove the ios() call because iOSTarget("ios") already creates a needed iOS target.

Unfortunately in 1.4.0-RC you cannot specify a custom name for the Kotlin framework due to KT-40801. But this issue is already fixed and the fix will be included into 1.4.0. So, in 1.4.0 you will be able to specify a custom framework name using the kotlin.cocoapods.frameworkName property:

kotlin {
    cocoapods {
        frameworkName = "SharedCode"
    }
}
xiaobailong24 commented 4 years ago

https://kotlinlang.org/docs/reference/native/cocoapods.html#current-limitations

If a Kotlin/Native module uses a CocoaPods library, you can built this module only from an Xcode project. Otherwise the CocoaPods library cannot be resolved by the Kotlin/Native infrastructure.

mathemandy commented 4 years ago

https://github.com/JetBrains/kotlin-native/issues/4339#issuecomment-679206375

i tried to build this sample and i get Showing All Messages The Kotlin/Native distribution used in this build does not provide the standard library. Make sure that the 'kotlin.native.home' property points to a valid Kotlin/Native distribution.

ilmat192 commented 4 years ago

@mathemandy, All samples in the Kotlin/Native repository are configured to be built by a compiler that is built from sources instead of a compiler provided along with the Gradle plugin. This error says that the Gradle plugin was not able to find the compiler so most probably you just need to build it from sources. See readme for details.

Alternatively you can just comment out the kotlin.native.home=... line in the gradle.properties file of this sample. In this case the Gradle plugin will download and use a release compiler.

ilmat192 commented 4 years ago

Since 1.4.0 we lifted the limitation that caused the initial issue. Now a Kotlin module depending on pods can be built not only from Xcode but also directly from Gradle.

Thus closing this issue.

See KT-30841 for directions of the further work.

epool commented 4 years ago

you may need to remove

binaries {
    framework()
}

from

fromPreset(determineIosPreset(), 'ios') {
    binaries {
        framework()
    }
}

and just left

fromPreset(determineIosPreset(), 'ios') {}

since you are using the cocoapods plugin that part is not required.