https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
a

Arkadii Ivanov

06/26/2020, 5:59 PM
I'm trying to create the
packForXcode
Gradle task described here. But I'm getting the following error:
Unresolved reference: targets
. Basically
kotlin.targets
is unresolved here 😞 Do you have any ideas how to solve it?
a

Andrea Prearo

06/26/2020, 6:15 PM
You should be able to leverage the
FatFrameworkTask
. There’s an example in the official documentation.
j

John O'Reilly

06/26/2020, 6:18 PM
Also worth looking at https://github.com/JetBrains/kotlin-native/blob/master/COCOAPODS.md . I think it simplifies things a bit
a

Arkadii Ivanov

06/26/2020, 6:21 PM
I'm targeting macOS. But even for iOS I believe it's a bit different. Isn't it?
j

John O'Reilly

06/26/2020, 6:22 PM
fwiw I'm using it for both iOS and macOS in https://github.com/joreilly/PeopleInSpace
a

Andrea Prearo

06/26/2020, 6:26 PM
I never tried macOS so far. You could add
macosX64
to the
FatFrameworkTask
configuration”
Copy code
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask

kotlin {
    // Create and configure the targets.
    val ios32 = iosArm32("ios32")
    val ios64 = iosArm64("ios64")
    val macOS = macosX64()

    configure(listOf(ios32, ios64, macOS)) {
        binaries.framework {
            baseName = "my_framework"
        }
    }

    // Create a task building a fat framework.
    tasks.create("debugFatFramework", FatFrameworkTask::class) {
        // The fat framework must have the same base name as the initial frameworks.
        baseName = "my_framework"

        // The default destination directory is '<build directory>/fat-framework'.
        destinationDir = buildDir.resolve("fat-framework/debug")

        // Specify the frameworks to be merged.
        from(
            ios32.binaries.getFramework("DEBUG"),
            ios64.binaries.getFramework("DEBUG")
            macOS.binaries.getFramework("DEBUG")
        )
    }
}
a

Arkadii Ivanov

06/26/2020, 6:27 PM
@John O'Reilly Thanks! But I don't want to use cocoapods. I used the
packForXcode
a while ago and it worked. But now in an another project it does not.
a

Andrea Prearo

06/26/2020, 6:30 PM
If you need only
macOS
, you can just specify that.
a

Arkadii Ivanov

06/26/2020, 6:31 PM
@Andrea Prearo Yeah! But first I would like to try the
packForXcode
. As far as I understand fat frameworks are much more expensive to build, all architectures multiply debug/release. But normally you need just one, e.g. iosX64/debug. So
packForXcode
does exactly this. It reads current config from Xcode env variables and builds what is required.
So I just copy-pasted the code from official samples and it does not compile. Also I have searched GitHub for samples, and they are same.
a

Andrea Prearo

06/26/2020, 6:36 PM
I see. If you are using a
*.gradle.kts
file,
kotlin.targets
should be available. It’s hard to tell where’s the problem without the full script code.
r

russhwolf

06/26/2020, 6:39 PM
Maybe post your whole build file? If
kotlin.targets
isn't resolving it sounds like the multiplatform plugin isn't being applied correctly, but not sure why that would be.
a

Arkadii Ivanov

06/26/2020, 6:43 PM
So basically the following code works:
Copy code
val packForXcode by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "xcode-frameworks")

    kotlin {
        /// selecting the right configuration for the iOS
        /// framework depending on the environment
        /// variables set by Xcode build
        val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
        val framework = targets
            .getByName<KotlinNativeTarget>("macosX64")
            .binaries.getFramework(mode)
        inputs.property("mode", mode)
        dependsOn(framework.linkTask)

        from({ framework.outputDirectory })
        into(targetDir)
    }
    /// generate a helpful ./gradlew wrapper with embedded Java path
    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText("#!/bin/bash\n"
                + "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
                + "cd '${rootProject.rootDir}'\n"
                + "./gradlew \$@\n")
        gradlew.setExecutable(true)
    }
}
I have replaced the
kotlin.targets
thing with kotlin DSL
kotlin {}
a

Andrea Prearo

06/26/2020, 6:43 PM
Do you have
Copy code
plugins {
    kotlin("multiplatform")
}
?
a

Arkadii Ivanov

06/26/2020, 6:43 PM
Ofcourse
r

russhwolf

06/26/2020, 6:44 PM
It's very strange to me that
kotlin { targets }
would resolve but
kotlin.targets
would not
But I guess if it works...
👍 2
a

Arkadii Ivanov

06/26/2020, 6:47 PM
@russhwolf Exactly, the following is a working workaround:
Copy code
lateinit var kotlin: KotlinMultiplatformExtension
    kotlin { kotlin = this }
After that I can use
kotlin.whatever
Or just put stuff inside
kotlin {}
r

russhwolf

06/26/2020, 6:48 PM
Is it a command-line error or just an IDE thing?
a

Arkadii Ivanov

06/26/2020, 7:08 PM
It's a command-line error