BuildConfig for Kotlin Multiplatform Project
BuildConfig for Kotlin Multiplatform Project.
It currently supports embedding values from gradle file.
Passing values from Android/iOS or any other platform code should work, but it's a hassle.
Setting up Android to read values from properties and add those into BuildConfig, and do the equivalent in iOS?
Rather I'd like to do it once.
buildScript { repositories { mavenCentral() } dependencies { classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0' classpath 'com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version' } }apply plugin: 'org.jetbrains.kotlin.multiplatform' apply plugin: 'com.codingfeline.buildkonfig'
kotlin { // your target config... android() iosX64('ios') }
buildkonfig { packageName = 'com.example.app' // objectName = 'YourAwesomeConfig' // exposeObjectWithName = 'YourAwesomePublicConfig'
defaultConfigs { buildConfigField 'STRING', 'name', 'value' }
}
packageNameSet the package name where BuildKonfig is being placed. Required.
objectNameSet the name of the generated object. Defaults to
BuildKonfig.
exposeObjectWithNameSet the name of the generated object, and make it public.
defaultConfigsSet values which you want to have in common. Required.
To generate BuildKonfig files, run
generateBuildKonfigtask.
Above configuration will generate following simple object.
// commonMain package com.example.appinternal object BuildKonfig { val name: String = "value" }
targetdependent values
If you want to change value depending on your targets, you can use
targetConfigsto define target-dependent values.
buildScript { repositories { mavenCentral() } dependencies { classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0' classpath 'com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version' } }apply plugin: 'org.jetbrains.kotlin.multiplatform' apply plugin: 'com.codingfeline.buildkonfig'
kotlin { // your target config... android() iosX64('ios') }
buildkonfig { packageName = 'com.example.app'
// default config is required defaultConfigs { buildConfigField 'STRING', 'name', 'value' buildConfigNullablefield 'STRING', 'nullableField', null } targetConfigs { // this name should be same as target names you specified android { buildConfigField 'STRING', 'name2', 'value2' buildConfigNullablefield 'STRING', 'nullableField', 'NonNull-value' } ios { buildConfigField 'STRING', 'name', 'valueForNative' } }
}
packageNameSet the package name where BuildKonfig is being placed. Required.
objectNameSet the name of the generated object. Defaults to
BuildKonfig.
exposeObjectWithNameSet the name of the generated object, and make it public.
defaultConfigsSet values which you want to have in common. Required.
targetConfigsSet target specific values as closure. You can overwrite values specified in
defaultConfigs.
buildConfigField(String type, String name, String value)Add new value or overwrite existing one.
buildConfigNullableField((String type, String name, String value)Add new nullable value or overwrite existing one.
Above configuration will generate following codes.
// commonMain package com.example.appinternal expect object BuildKonfig { val name: String val nullableField: String? }
// androidMain package com.example.appinternal actual object BuildKonfig { actual val name: String = "value" actual val nullableField: String? = "NonNull-value" val name2: String = "value2" }
// iosMain package com.example.appinternal actual object BuildKonfig { actual val name: String = "valueForNative" actual val nullableField: String? = null }
Kotlin 1.4.0 adds support for the hierarchical project structure, but BuildKonfig currently does not support this. You can use the hierarchical project structure, but intermediate SourceSets can only see fields defined in
defaultConfigsblock. See details and progress at here.
Yes(sort of).
Kotlin Multiplatform Project does not support product flavor. Kotlin/Native part of the project has release/debug distinction, but it's not global.
So to mimick product flavor capability of Android, we need to provide additional property in order to determine flavors.
Specify default flavor in your
gradle.properties
# ROOT_DIR/gradle.properties buildkonfig.flavor=dev
// ./mpp_project/build.gradlebuildkonfig { packageName = 'com.example.app'
// default config is required defaultConfigs { buildConfigField 'STRING', 'name', 'value' } // flavor is passed as a first argument of defaultConfigs defaultConfigs("dev") { buildConfigField 'STRING', 'name', 'devValue' } targetConfigs { android { buildConfigField 'STRING', 'name2', 'value2' } ios { buildConfigField 'STRING', 'name', 'valueIos' } } // flavor is passed as a first argument of targetConfigs targetConfigs("dev") { ios { buildConfigField 'STRING', 'name', 'devValueIos' } }
}
In a development phase you can change value in
gradle.propertiesas you like.
$ ./gradlew build -Pbuildkonfig.flavor=release
If you configure same field across multiple defaultConfigs and targetConfigs, flavored targetConfigs is the strongest.
Lefter the stronger.
Flavored TargetConfig > TargetConfig > Flavored DefaultConfig > DefaultConfig
Have a look at
./sampledirectory.
# Publish the latest version of the plugin to mavenLocal() $ ./gradlew publishToMavenLocalTry out the samples.
BuildKonfig will be generated in ./sample/build/buildkonfig
$ ./gradlew -p sample generateBuildKonfig