Need in runtime something like this:
when (Platform.FAMILY) {
"windows" -> ...
"linux" -> ...
else -> ...
}
Is it possible?
Ideally it should be like in C:
#if defined(_WIN32)
...
#else
...
#endif
so only one branch is really compiled.
Could you, please, tell us more about the nature and the difference of the code in the branches.
private val FileSeparator = if (IsWindows) "\\" else "/"
if (IsWindows && path.length > 2 && path[0] == '/' && path[2] == ':') {
// remove a leading slash on Windows
path = path.substring(1)
}
For that you could have PlaformLinux.kt with
package mylib
val FileSeparator = "/"
and PlatformWindows.kt with
package mylib
val FileSeparator = "\\"
And use mylib.FileSeparator all over the place.
And include into compilation of your project PlatformLinux.kt or PlaformWindows.kt depending on the target platform. This way, you can encapsulate all your porting layer into this file, which could be compiled to the .klib, or included directly to compilation.
We could create some platform library with runtime detection (across POSIX platforms, uname(3) could be used), but generally some porting layer will usually be needed.
Sure I can workaround this somehow, but in general - analog of Java's System.getProperty("os.name") is needed sometimes.
K/N compiler itself have it in org.jetbrains.kotlin.konan.target.KonanTarget.kt
Maybe make it available from runtime too.
I also need that feature
When working on simple tiny command line tool, having a way to detect platform in a single line is really usefull
fun sleep_ms(time: Int)
{
//usleep(time * 1000) <- linux
Sleep(time) // <- windows
}
You probably need to compile smth like
PortingLinux.kt:
import platform.posix.usleep
fun sleep_ms(time: Int) = usleep(time * 1000)
PortingWindows.kt:
import platform.win32.Sleep
fun sleep_ms(time: Int) = Sleep(time)
And compile different platforms on different targets.
Same approach may work for platform detection, i.e.
enum Platform {
WINDOWS, LINUX, MACOS
}
PorintgWindows.kt
val platform = Platform.WINDOWS
PorintgLinux.kt
val platform = Platform.LINUX
and in common code:
if (platform == Platform.Linux) {
// Something common, but different.
}
i still believe we should be able to get platform right away, having to use 3 different files just to detect OS on desktop is weird, why complicate when can make something simple ?
I have a simple case where I wan't to run an external executable. The path and name to the executable varies between platforms (I need a '.exe' on Windows and different folder).
The module I use has 2 platform specific parts:
I can't really use @olonho solution if I don't wan't copy all posix part twice just for the platform difference. I know that 1.4 will provide source set hierarchy but I don't use it just yet.
Is there a Env variable that could help ? Or another way ?
Thanks
Edit:
I found a solution by running uname on the posix source set to discriminate between Linux and Darwin.
In a case somebody is still searching for a solution, I found sample implementation of "OS" object in the library that I'm currently using to create my game application.
For Kotlin 1.3 it's com.soywiz.korlibs.korio:korio-metadata:1.11.13 ,see its usage in today's commit: https://github.com/andstatus/game2048/commit/2967194225b78298aae14de2872c7fb8473f5e07 (see "if (OS.isAndroid) {")
For Kotlin 1.4 it's here: https://github.com/korlibs/korge-next/blob/master/korio/src/commonMain/kotlin/com/soywiz/korio/util/OS.kt
Most helpful comment
i still believe we should be able to get platform right away, having to use 3 different files just to detect OS on desktop is weird, why complicate when can make something simple ?