https://kotlinlang.org logo
Title
a

Andrew Dunbar

04/20/2023, 10:42 AM
I’m an oldschool programmer wanting to play with Kotlin multiplatform for desktop commandline apps at first I’ve done a little bit of Kotlin and a tiny bit of Kotlin Native but I’ve wasted two days trying to get from there to Kotlin Multiplatform I have no mobile or Android background. I don’t know any of the frameworks nor most of the terminology. Examples/tutorials I can find suffer from various problems for my background I’m looking for a minimal example with no mobile stuff, at least two desktop platforms, not KMM, not a library, not using flutter, not using flow, not including JVM or js Should include a common function and a per-platofrm fuction using `expect`/`actual` I’ve tried starting from scratch with IntelliJ IDEA and starting from a mobile platform but always get stuck somewhere I can’t Google/StackOverflow my way out of AI chatbots that have been amazing for other languages and platforms don’t seem to be able to get me unstuck
k

Konstantin Tskhovrebov

04/20/2023, 10:53 AM
a

Adam S

04/20/2023, 10:55 AM
most AI chatbots are trained on data that’s at least 1 year old, if not more, so they’re not going to know a lot about newer features.
a

Andrew Dunbar

04/20/2023, 10:58 AM
True indeed but most tutorial level stuff I see is about two years old. The AI bot I’m using does seem to know a lot but not enough for my specific problem. Seems like it’s clutching at straws just as I am.
kotlin doctor says it’s for KMM
(i’m also new to slack btw)
k

Konstantin Tskhovrebov

04/20/2023, 11:01 AM
if you want to make K/N application it means you will use kotlin multiplatform build setup.
Kdoctor is a tool only for macos
a

Andrew Dunbar

04/20/2023, 11:08 AM
It could very well be the build.gradle.kts file that’s the problem. I’m quite lost in there. Especially around nativeMain vs commonMain vs macosMain and sourceSets and what to name source files etc. That’s where the bot kept changing things too but making it worse.
Well I am on mac at least
when i start a new proj from idea it only puts a Main.kt in nativeMain, has no commonMain, and the macosX64Main and linuxX64Main have no files in them - many tutorials seems to depend on there being a commonMain and sometimes i think the ai bot expects one too
a

Adam S

04/20/2023, 11:12 AM
yes, configuring Gradle can be really difficult sometimes! Since you’re on Mac, it might be an issue where IntelliJ generates some config that doesn’t work on the newer M1 chips, I think. I’ll try and dig up more info…
a

Andrew Dunbar

04/20/2023, 11:14 AM
i’ve definitely had that too. i am on m1 despite leaving the default dir structure i mentioned with the ‘X86’ naming scheme - i normally have to change that in the build.gradle.kts in my regular kotlin native stuff. though my previous project got stuck where it would build but not run so i started a new project and pasted the source in and then it worked but left me with zero understanding
plugins {
    kotlin("multiplatform") version "1.8.0"
}

group = "me.hippietrail"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

kotlin {
    val hostOs = System.getProperty("os.name")
    val isMingwX64 = hostOs.startsWith("Windows")
    val nativeTarget = when {
        hostOs == "Mac OS X" -> macosArm64("native")
        hostOs == "Linux" -> linuxX64("native")
        isMingwX64 -> mingwX64("native")
        else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
    }

    nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
            }
        }
    }
    linuxX64()
    macosX64()
    sourceSets {
        val nativeMain by getting
        val linuxX64Main by getting
        val macosX64Main by getting
    }
}
that’s the file intellij gave me. i removed only the Test stuff. with this setup i can’t figure out how to get an `expect`/`actual` to work. it always says it can’t find an actual unless I put it straight in the Main.kt
a

Adam S

04/20/2023, 11:19 AM
I can’t find the issue I’m thinking about, but I think the
val nativeTarget = ...
config from here is correct https://kotlinlang.slack.com/archives/C3SGXARS6/p1679899986973039 and it looks like you have that already
a

Andrew Dunbar

04/20/2023, 11:21 AM
oh i just noticed i did update this line but didn’t rename anything else!
hostOs == "Mac OS X" -> macosX64("native")
to
hostOs == "Mac OS X" -> macosArm64("native")
no didn’t fix it )-:
e: file:///Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/src/linuxX64Main/kotlin/Fred.kt:6:12 Actual function 'foo' has no corresponding expected declaration
src/nativeMain/kotlin/Main.kt
package me.hippietrail

expect fun foo(): String

fun main() {
    println("Hello, Kotlin/Native!")
    println(foo())
}

// actual fun foo(): String {
//     return "foobie"
// }
a

Adam S

04/20/2023, 11:24 AM
so if you make a file
src/commonMain/kotlin/foo.kt
, and in that file put something like
expect fun foo(): Unit
Then it will complain unless you add `actual`s in all the other targets. You’ve defined targets
linuxX64
,
macosX64
, and a target that’s dynamic based on the current machine - which in your case will be
macosArm64
The point behind the dynamic ‘native’ target, is that you don’t need to define the other targets - Gradle will automatically switch the target when it’s loaded on another machine. This is good for experimenting, but perhaps not so good if you want to build all the targets on one machine. So I would say, either explicitly add all targets (which can make the Gradle config a little more complicated), or remove the explicit targets and just use the dynamic ‘native’ target
a

Andrew Dunbar

04/20/2023, 11:24 AM
src/linuxX64Main/kotlin/Fred.kt
package me.hippietrail

// actual fun foo(): String {
//     return "foobie fred"
// }
actual fun foo(): String = "Linux implementation of foo"
similar in
src/macosX64Main/kotlin/Barney.kt
ah so is the term ‘native’ kind of overloaded? i assumed it meant the same as in kotlin/native and just that it was an umbrella for the ones that would use llvm to output native code
a

Adam S

04/20/2023, 11:27 AM
hmmmm yes, I think you could see ‘native’ that way!
a

Andrew Dunbar

04/20/2023, 11:27 AM
so that all my linux, macos, windows platforms would each be a native or grouped together a level under native
whereas if i’m following you’re making it sound like native means the one that’s native to the machine i’m developing on and since i’m on mac that the linux part would not be native??
i made
src/nativeMain/kotlin/foo.kt
with just
actual fun foo(): String
in it and still get same build error: e: file😕//Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/src/linuxX64Main/kotlin/Fred.kt:6:12 Actual function ‘foo’ has no corresponding expected declaration
a

Adam S

04/20/2023, 11:32 AM
what might help is looking at the directory structure of the targets you’ve defined
kotlin {
    val hostOs = System.getProperty("os.name")
    val isMingwX64 = hostOs.startsWith("Windows")
    val nativeTarget = when {
        hostOs == "Mac OS X" -> macosArm64("native")
        hostOs == "Linux" -> linuxX64("native")
        isMingwX64 -> mingwX64("native")
        else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
    }

    nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
            }
        }
    }
    linuxX64()
    macosX64()
}
Since you’re on an M1 Mac,
nativeTarget
will be
macosArm64
, and this will have a hardcoded name of
native
so in your src dir you’ll have
src/commonMain/kotlin
src/commonTest/kotlin
src/linuxX64Main/kotlin
src/linuxX64Test/kotlin
src/nativeMain/kotlin
src/nativeTest/kotlin
src/macosX64Main/kotlin
src/macosX64Test/kotlin
Note that because the ‘native’ target might be dynamic, but the directory structure will be the same
because Kotlin Source Sets are hierarchical, and all source sets extend from commonMain, that means that any
expect
in commonMain MUST have an
actual
in nativeMain, and macosX64Main, and linuxX64Main. Which is probably not what you want. What you probably want is to set the targets explicitly, so nativeMain is not dynamic.
kotlin {
    mingwX64()
    macosArm64()
    linuxX64()
    macosX64()
}
Then you can code in commonMain, and write `expect`s in commonMain, and implement the actuals in each target. However, what happens if you want to add a JS or JVM target? That might be annoying because you might end up copy-pasting code between each of the mingw/macos/linux targets. There’s a cool way of fixing that, which I can explain if you want?
a

Andrew Dunbar

04/20/2023, 11:36 AM
src
|____linuxX64Main
| |____resources
| |____kotlin
| | |____Fred.kt
|____nativeMain
| |____resources
| |____kotlin
| | |____foo.kt
| | |____Main.kt
|____macosX64Main
| |____resources
| |____kotlin
| | |____Barney.kt
ah so that’s very confusing that intellij didn’t give me any commonMain and why i was considering the names are arbitrary up to the user and that some just go with nativeMain and no commonMain \-:
let me rename every instance of X64 to Arm64 and see what happens…
ooh well things are changing at least…
this expect
expect fun foo(): String
is not matching this actual now
actual fun foo(): String {
    return "foobie"
}
e: file😕//Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/src/nativeMain/kotlin/Main.kt:3:12 Expected function ‘foo’ has no actual declaration in module <me.hippietrail:kotlin-multiplatform-native> for Native e: file😕//Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/src/nativeMain/kotlin/foo.kt:1:12 Actual function ‘foo’ has no corresponding expected declaration
a

Adam S

04/20/2023, 11:45 AM
Interesting! What is the location of those files? What’s the error message?
a

Andrew Dunbar

04/20/2023, 11:46 AM
see my src tree about 4 comments up
in my opinion as a noob to the system who’s not a noob programmer, this seeming double meaning of ‘native’ is a big problem that’s hard to discover on your own. maybe it’s covered in some introductory text i skimmed over that looked like it was all mobile experience specific etc?
oh i didn’t rename the folders when i did the global search and replace!
a

Adam S

04/20/2023, 11:50 AM
in the context of a Kotlin Multiplatform target called ‘native’, perhaps it helps to think of it as “the Kotlin/Native target for the current machine”?
a

Andrew Dunbar

04/20/2023, 11:50 AM
ok build is going completely differently so far…
perhaps but that’s also confusing because it makes you wonder if anything needs to be editing to build the same source repo on a different machine with different platform
hmm i was hopeful but i still got this build error:
e: file:///Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/src/linuxArm64Main/kotlin/Fred.kt:6:12 Actual function 'foo' has no corresponding expected declaration
a

Adam S

04/20/2023, 11:54 AM
is
expect fun foo()
in
src/nativeMain/kotlin/foo.kt
?
a

Andrew Dunbar

04/20/2023, 11:56 AM
yes should i comment that out? is the error msg misleading?
if i comment out the one in Fred.kt it complains the same about the one in Barney.kt - suggesting it quits on the first error if i then comment out the one in foo.kt it makes no difference and still complains about Barney.kt
a

Adam S

04/20/2023, 11:58 AM
try moving
expect fun foo()
to
src/commonMain/kotlin/foot.kt
The error says that there’s an
actual
in linuxArm64Main, but there’s no
expect
in any ‘parent_‘of linuxArm64Main. In fact, the only ‘parent’ of linuxArm64Main is commonMain.
based on the targets you’ve defined, this is the hierarchy of your project
.
└── commonMain/
    ├── linuxX64Main
    ├── nativeMain
    └── macosX64Main
but you’ve written your expect/actuals like this is the hierarchy
.
└── commonMain/
    ├── nativeMain/
    │   └── linuxX64Main
    └── macosX64Main
which isn’t what you’ve defined in the Gradle config (note this is the model hierarchy, not the directory layout)
a

Andrew Dunbar

04/20/2023, 12:01 PM
really?? how can i see/understand that
i still have no commonMain in my src or my build kts so i’m assuming that’s implied
well i didn’t before but that’s where i feel i’ve arrived at so far …
a

Adam S

04/20/2023, 12:04 PM
if you want to make nativeMain a ‘parent’ of linuxX64 then… don’t! It doesn’t make sense. But if you really wanted to, you’d have to add this in the Gradle config
kotlin {
  macosArm64("native")
  linuxArm64()
  sourceSets {
    val nativeMain by getting
    val nativeTest by getting
    
    val linuxArm64Main by getting { dependsOn(nativeMain)}
    val linuxArm64Test by getting { dependsOn(nativeTest)}
  }
}
a

Andrew Dunbar

04/20/2023, 12:04 PM
so i need to create an explicit commonMain or one is always needed even if IDEA doesn’t make you one… or i need to move my linuxMain up a level in the build system or the macosMain down a level?
a

Adam S

04/20/2023, 12:04 PM
there’s always a commonMain/commonTest, you don’t need to define it explicitly
a

Andrew Dunbar

04/20/2023, 12:05 PM
i don’t know what i “want” to do you due to my very damaged understanding of it all, which is why i set out looking for a clean example to follow (-:
ah ok so instead of that fix that doesn’t make sense what would be the regular fix?
this is what i currently have
kotlin {
    val hostOs = System.getProperty("os.name")
    val isMingwX64 = hostOs.startsWith("Windows")
    val nativeTarget = when {
        hostOs == "Mac OS X" -> macosArm64("native")
        hostOs == "Linux" -> linuxArm64("native")
        isMingwX64 -> mingwX64("native")
        else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
    }

    nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
            }
        }
    }
    linuxArm64()
    macosArm64()
    sourceSets {
        val nativeMain by getting
        val linuxArm64Main by getting
        val macosArm64Main by getting
    }
}
a

Adam S

04/20/2023, 12:06 PM
Here’s the config I use. Note that I explicitly define all targets, but I don’t change the name of them.
hmm that should be a txt file not a binary
build.gradle.kt
a

Andrew Dunbar

04/20/2023, 12:07 PM
thanks very much for your patience by the way!
a

Adam S

04/20/2023, 12:07 PM
my pleasure :)
a

Andrew Dunbar

04/20/2023, 12:08 PM
some forums are so toxic but all the “new” ones i’ve used recently are so much nicer: rust, swift, zig on discord
a

Adam S

04/20/2023, 12:09 PM
so with that config file I shared, what you’ll end up with is the following src directory structure
.
└── src/
    ├── commonMain/
    ├── nativeMain/
    ├── linuxMain/
    ├── windowsMain/
    ├── macosMain/
    └── ...
there’s no ‘dynamic’ native target
so the ideal situation is that you can write pure Kotlin code in commonMain, and all dependencies are compatible with all of your targets, so you won’t even need the other targets. However, what might happen is that you add a a JVM target
kotlin {
  // ...

  jvm()
}
Now your source set hierarchy looks like this
.
└── common/
    ├── native/
    │   ├── windows
    │   ├── mac
    │   └── linux
    └── jvm/
a

Andrew Dunbar

04/20/2023, 12:12 PM
i pasted in your config out mine, commented out the mingw ones for now and renamed the X64 ones to Arm64 and got this error:
FAILURE: Build failed with an exception.

* Where:
Build file '/Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/build.gradle.kts' line: 1

* What went wrong:
Plugin [id: 'org.jetbrains.kotlin.multiplatform'] was not found in any of the following sources:
a

Adam S

04/20/2023, 12:12 PM
kotlin("multiplatform") version "1.8.20"
a

Andrew Dunbar

04/20/2023, 12:15 PM
that should go at the top before everything else or that version part was missing in the
plugins{
stuff?
a

Adam S

04/20/2023, 12:15 PM
I missed out the version because in my config the plugin versions are set in a different file, so just add the version to the end in your build file
a

Andrew Dunbar

04/20/2023, 12:16 PM
ah so should I move Main.kt and foo.kt from nativeMain/kotlin to commonMain/kotlin?
a

Adam S

04/20/2023, 12:16 PM
yes
a

Andrew Dunbar

04/20/2023, 12:16 PM
and nativeMain should remain empty or something of some sort needs to go in there?
a

Adam S

04/20/2023, 12:18 PM
it should remain empty, until you need to write something that’s native-specific
a

Andrew Dunbar

04/20/2023, 12:18 PM
when i get this working sadly it will still be partly magic to me
a

Adam S

04/20/2023, 12:19 PM
have you used dependency inversion much before? It’s a similar principle
a

Andrew Dunbar

04/20/2023, 12:19 PM
yes when this works i will want to move on to the next step where there will be the majority shared between the mac and linux stuff. but i don’t have a way to do windows any more due to stupid unupgradable macbook ssd design, i already got it with the biggest i could afford
no. since i quit being a pro coder in 2000 i’ve only played with toy coding stuff so things like ‘dependency inversion’ are all new to me
a

Adam S

04/20/2023, 12:21 PM
I haven’t used it much either, so I don’t know how analogous it is :)
a

Andrew Dunbar

04/20/2023, 12:23 PM
now i may have messed something up with search and replace but now i’m getting this build error:
FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':compileNativeMainKotlinMetadata'.
> Could not resolve all artifacts for configuration ':nativeMainResolvableDependenciesMetadata'.
   > Cannot resolve external dependency org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20 because no repositories are defined.
     Required by:
         project :
a

Adam S

04/20/2023, 12:25 PM
for me the trick is to think about how commonMain does not care at all about what targets have been set up, all it cares about is “for all targets, is there a concrete implementation?“. Which can be really confusing if the only target is JVM - because then you are ‘allowed’ to use JVM specific code in commonMain. When you add more and more targets, the same is true for each ‘level’. Just because a source set is named ‘native’, that’s just a name. All the compiler cares about is “source set ‘native’ has
expect fun foo()
. Native is used in targets X/Y/Z. Do they all have an implementation?”
you need to add a Maven repo in your
build.gradle.kts
repositories {
  mavenCentral()
}
a

Andrew Dunbar

04/20/2023, 12:27 PM
maybe i’ll end up grocking all that if i stick with this (-:
a

Adam S

04/20/2023, 12:27 PM
definitely 👍
a

Andrew Dunbar

04/20/2023, 12:29 PM
well now i’m only getting one tiny build error:
e: file:///Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/src/commonMain/kotlin/Main.kt:5:13 Unresolved reference: foo
that one is because i moved the
expect
from Main.kt into foo.kt
so i either need to move it back or do something like an include/require
a

Adam S

04/20/2023, 12:31 PM
do Main.kt and foo.kt have the same package at the top of the file?
Kotlin will let you have files in directories that don’t match their package
a

Andrew Dunbar

04/20/2023, 12:33 PM
everything but foo.kt as
package me.hippietrail
- i think the code that IDEA made for me didn’t have that but i know the AI kept adding it
well now it builds but the usual path the .kexe ends up in still has an old version. i’m building using ./gradlew build - not IDEA
a

Adam S

04/20/2023, 12:36 PM
try running ./gradlew clean
a

Andrew Dunbar

04/20/2023, 12:36 PM
idea is a mem and cpu pig and drains the battery
hmm so where should i now find the binary to run?
there’s no build/bin dir anymore
a

Adam S

04/20/2023, 12:38 PM
I’ve told IntelliJ to use Gradle commands directly IntelliJ | Preferences | Build, Execution, Deployment | Build Tools | Gradle Build & Run using Gradle, Run tests using Gradle
ohh the config I had didn’t include the executable config
a

Andrew Dunbar

04/20/2023, 12:39 PM
oh so that’s part of what i removed when i pasted your gradle kts in? (-:
a

Adam S

04/20/2023, 12:40 PM
I remember now, this is why the dynamic ‘native’ target is a bit nicer. You end up with a single exe, no matter what machine. I’ll figure out how I did it on my machine…
a

Andrew Dunbar

04/20/2023, 12:41 PM
this was in the original kts
nativeTarget.apply {
        binaries {
            executable {
                entryPoint = "main"
            }
        }
    }
but all kinds of errors if i just dumbly paste that in
a

Adam S

04/20/2023, 12:43 PM
I’m not sure if it will work, but try this - it will add an executable for all Kotlin/Native targets. But you should only run
./gradlew runDebugExecutableMacosArmX64
(or whatever the actual target name is)
kotlin {
  targets.withType<KotlinNativeTarget>().configureEach {
    binaries {
      executable {
        entryPoint = "main"
      }
    }
  }
}
or maybe try only adding the exe for your machine’s target, which for you is macosArm64
kotlin {
  macosArm64 {
    binaries { 
      executable { 
        entryPoint = "main"
      }
    }
  }
}
this is what’s nice about the dynamic nativeMain custom config - you’ll just have one Gradle task you can run
./gradlew runDebugExecutableNative
a

Andrew Dunbar

04/20/2023, 12:45 PM
hmm does that go next to or instead of my current
kotlin {
or does just part of this new one go inside my current one?
a

Adam S

04/20/2023, 12:46 PM
it all works the same - whatever you think looks pretty. You can have as many
kotlin {}
config blocks as you like. I just put it like that so it would be easier to understand :)
a

Andrew Dunbar

04/20/2023, 12:47 PM
i can’t decide on prettiness until it i grok it all so until then whatever most resembles all the stuff already out there so i can compare when i have to google (-:
a

Adam S

04/20/2023, 12:48 PM
almost all config I’ve seen uses a single
kotlin {}
block
a

Andrew Dunbar

04/20/2023, 12:49 PM
tried the second version and got this build error
> Task :linkDebugExecutableMacosArm64 FAILED
e: Could not find 'main' in '<root>' package.

FAILURE: Build failed with an exception.
cafe is about to close i’ll be back in 5-10
back
a

Adam S

04/20/2023, 1:06 PM
since Main.kt is in a package, try changing the entry point
entryPoint = "me.hippietrail.main"
a

Andrew Dunbar

04/20/2023, 1:07 PM
i tried the first version and it spat out this
> Configure project :
e: /Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/build.gradle.kts:9:20: Unresolved reference: KotlinNativeTarget
e: /Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/build.gradle.kts:10:5: Unresolved reference: binaries
e: /Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/build.gradle.kts:11:7: Unresolved reference: executable
e: /Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/build.gradle.kts:12:9: Unresolved reference: entryPoint

The Kotlin source set commonTest 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>

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/hippietrail/IdeaProjects/kotlin-multiplatform-native/build.gradle.kts' line: 9

* What went wrong:
Script compilation errors:

  Line 09:   targets.withType<KotlinNativeTarget>().configureEach {
                              ^ Unresolved reference: KotlinNativeTarget

  Line 10:     binaries {
               ^ Unresolved reference: binaries

  Line 11:       executable {
                 ^ Unresolved reference: executable

  Line 12:         entryPoint = "main"
                   ^ Unresolved reference: entryPoint

4 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 1s
a

Adam S

04/20/2023, 1:07 PM
oh right, add
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
a

Andrew Dunbar

04/20/2023, 1:09 PM
the second version you pasted with your previous fix did work
i’m gonna try the first version even though the second one worked. where do i add that import line? very top or inside the kotlin block?
a

Adam S

04/20/2023, 1:12 PM
at the top - all imports must be at the top in .kt or .kts files
a

Andrew Dunbar

04/20/2023, 1:14 PM
so this version still failing with
> Task :linkDebugExecutableLinuxArm64 FAILED
e: Could not find 'main' in '<root>' package.

FAILURE: Build failed with an exception.
a

Adam S

04/20/2023, 1:15 PM
in the file that contains
fun main()
, what’s the package at the top?
also, linkDebugExecutableLinuxArm64 - you probably don’t want to run the Linux target :)
a

Andrew Dunbar

04/20/2023, 1:18 PM
package me.hippietrail
a

Adam S

04/20/2023, 1:18 PM
okay cool, so the entry point has to include the package
the error
Could not find 'main'
means the entry point is missing the package
a

Andrew Dunbar

04/20/2023, 1:20 PM
sadly i’m well past the eyes glazed over when errors stopped making sense phase. hopefully i’m about to start unglazing (-:
very nice!!
time to see if that linux binary will run from multipass then!
yep both the macos and the linux binaries are building and running! thank you so much good sir!
a

Adam S

04/20/2023, 1:30 PM
amazing!
good to hear
a

Andrew Dunbar

04/20/2023, 1:31 PM
one question: is this the only way to achieve the equivalent to mutiplatform code in C that we’d do with
#ifdef
et al?
a

Adam S

04/20/2023, 1:38 PM
I’ve only done basic C, so I’m not sure what’s possible with `#ifdef`…
a

Andrew Dunbar

04/20/2023, 1:42 PM
well to do a very simple helloworld that printed a different message depending on the OS you would only need one source file
a

Adam S

04/20/2023, 1:43 PM
ahh right, yes with Kotlin Multiplatform you would need a .kt file with an
expect
in commonMain, and then .kt files with
actual
in linuxMain, windowsMain, macosMain, etc…. So it would need multiple files
a

Andrew Dunbar

04/20/2023, 1:44 PM
cool so as we have it then. good to know. otherwise i might feel like i’m getting in deeper than necessary here
a

Adam S

04/20/2023, 1:44 PM
exactly 👍
a

Andrew Dunbar

04/20/2023, 1:46 PM
so I added macosX64 and it’s working with a new binary and the same output. if i wanted to give it its own
actual
should i change my maosMain folder to macosArm64Main and make a second one macosX64Main or should i create two new folders with those names inside my current macosMain?
i guess the build system already has that heirarchy but the src dir structure doesn’t?
a

Adam S

04/20/2023, 2:08 PM
sorry, I’m a little bit lost :) If you told me “you have to create a commonMain function that returns the name of the current Kotlin target” I would… • make
expect fun currentTargetName(): String
in
src/commonMain/kotlin
• and then in each specific target (linuxX64. mingwX64, macosX64), create an
actual fun
• (and so I don’t need to create any `actual fun`s in
src/windowsMain
or
src/linuxMain
) BUT if you said “make a commonMain function that returns the name of the operating system of the target”, then because of the hierarchy I don’t need to make an
actual fun
in each specific target - instead I only have to make an
actual fun
in
src/windowsMain
,
src/linuxMain
,
src/macosMain
a

Andrew Dunbar

04/20/2023, 2:25 PM
got it working using the ai chatbot. didn’t have to change the build file. created two new more specific dirs for macosx64 and macosarm64 directly under
src
and gave each an
actual
and commented out the old `actual`from macosMain
added a unixlike level above both mac and linux with some extra expect/actual pairs - all working - awesome!