Any plans for having conditional compiling?

Hi people!

I wonder if there are any plans for introducing features for conditional compiling so we can support both Java and Javascript targets in the same project?

Maybe something like a convention based on file extensions? For example,

  • Canvas.js.kt
  • Canvas.java.kt

and then the compiler choses file accordingly to what the current backend is.

How does this sound? If not, what is/will the standard practice be for this problem?

Regards, Tommy

1 Like

Why not factor platform-specific parts into separate modules?

1 Like

Oddly enough I didn't think of that. :8}

Incidentally I did just that recently on a project (I fixed up the maven plugin so it can support different source paths for different execution phases (JVM 'compile' versus 'js' etc) such as in this pom.xml. I did cheat in the standard library in kotlin and use a naming convention (excluding *JVM.kt files on the JS compile) which lets you keep code closer together; but I guess separate directory trees is maybe cleaner.

It might be nice for IDEA to have a view where the ‘common’, ‘jvm’ and ‘js’ kotlin code could be viewed in a single source tree to avoid having to do too much tree expanding/collapsing.

1 Like

Hi, I’d like kotlin to have some conditional compile control syntax
like #if
from my android developer experience:
I hope i can write such code:

#if DEBUG
open
#endif
class MyActivity:Activity(){}

that means I want a open class in Debug Mode. while a final class in release mode.

is it a library? Why would you need it to be a final class in release mode? Which advantages does it bring?

Would love this for examples like the following

#ifnot java_8
Thread.onSpinWait()
#end

The common answer to this is reflection. I know java 8 code can run on newer versions, but some times its nice to have enhancements based off the version compiled for.

It can be usuful for conditional compilation, when setting constants.

#define TEST_URL true

#ifdef TEST_URL
    const val DOMAIN = "test.com"
    const val URL = "https://test.$DOMAIN/"
#else
    const val DOMAIN = "example.com"
    const val URL = "https://$DOMAIN/"
#endif

compatible with with java 8+

Agrona ThreadHints

JVM:

@JvmField
val option = System.getProperty("my.option")

// JIT removes unnecessary branch at first execution
if (option) {
	// ...
} else {
   // ...
}

Now pass your configurations values to the application using CLI argument -D<option_name>:

java -jar jarName -Dmy.option=true

Initialize “my.option” system property in any way you want, most importantly, do this before loading java class in which option property is defined (JVM loads classes lazily, at first access).

fun main() {
	System.setProperty("my.option", "true")

	// ...
}

Android:

build.gradle:

buildConfigField "boolean", "MY_OPTION", "true" 

In your code:

// unnecessary branch removed at compile time
if (BuildConfig.MY_OPTION) {
	// ...
} else {
	// ...
}

Yes, it is a good variant to set an option in build.gradle. It will be useful for a simple use-case when we want to set constants. In this case we can set several constants (but as variables) eighter with repeating a block, or destructing them:
1.

val const1 = if (BuildConfig.MY_OPTION) {
// ...
} else {
// ...
}
val const2 = ...
val (const1, const2, ...) = if (BuildConfig.MY_OPTION) {
...
} else {
...
}