BuildConfig for Kotlin Multiplatform Project

Overview

BuildKonfig

Maven Central

BuildConfig for Kotlin Multiplatform Project.
It currently supports embedding values from gradle file.

Table Of Contents

Motivation

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.

Usage

Requirements

  • Kotlin 1.4.0 or later
  • Kotlin Multiplatform Project
  • Gradle 6.5 or later

Gradle Configuration

Simple configuration

Groovy DSL
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'
    }
}
Kotlin DSL
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0")
        classpath("com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version")
    }
}

plugins {
    kotlin("multiplatform")
    id("com.codingfeline.buildkonfig")
}

kotlin {
    // your target config...
    android()
    iosX64('ios')
}

buildkonfig {
    packageName = "com.example.app"
    // objectName = "YourAwesomeConfig"
    // exposeObjectWithName = "YourAwesomePublicConfig"

    defaultConfigs {
        buildConfigField(STRING, "name", "value")
    }
}
  • packageName Set the package name where BuildKonfig is being placed. Required.
  • objectName Set the name of the generated object. Defaults to BuildKonfig.
  • exposeObjectWithName Set the name of the generated object, and make it public.
  • defaultConfigs Set values which you want to have in common. Required.

To generate BuildKonfig files, run generateBuildKonfig task.
This task will be automatically run upon execution of kotlin compile tasks.

Above configuration will generate following simple object.

// commonMain
package com.example.app

internal object BuildKonfig {
    val name: String = "value"
}

Configuring target dependent values

If you want to change value depending on your targets, you can use targetConfigs to define target-dependent values.

Groovy DSL
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 the same as target names you specified
        android {
            buildConfigField 'STRING', 'name2', 'value2'
            buildConfigNullableField 'STRING', 'nullableField', 'NonNull-value'
        }
        
        ios {
            buildConfigField 'STRING', 'name', 'valueForNative'
        }
    }
}
Kotlin DSL
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0")
        classpath("com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version")
    }
}

plugins {
    kotlin("multiplatform")
    id("com.codingfeline.buildkonfig")
}

kotlin {
    // your target config...
    android()
    iosX64('ios')
}

buildkonfig {
    packageName = "com.example.app"

    // default config is required
    defaultConfigs {
        buildConfigField(STRING, "name", "value")
    }

    targetConfigs {
        // names in create should be the same as target names you specified
        create("android") {
            buildConfigField(STRING, "name2", "value2")
            buildConfigNullableField(STRING, "nullableField", "NonNull-value")
        }

        create("ios") {
            buildConfigField(STRING, "name", "valueForNative")
        }
    }
}
  • packageName Set the package name where BuildKonfig is being placed. Required.
  • objectName Set the name of the generated object. Defaults to BuildKonfig.
  • exposeObjectWithName Set the name of the generated object, and make it public.
  • defaultConfigs Set values which you want to have in common. Required.
  • targetConfigs Set 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.app

internal expect object BuildKonfig {
    val name: String
    val nullableField: String?
}
// androidMain
package com.example.app

internal actual object BuildKonfig {
    actual val name: String = "value"
    actual val nullableField: String? = "NonNull-value"
    val name2: String = "value2"
}
// iosMain
package com.example.app

internal actual object BuildKonfig {
    actual val name: String = "valueForNative"
    actual val nullableField: String? = null
}

Note about the hierarchical project structure

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 defaultConfigs block. See details and progress at here.

Product Flavor?

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
Groovy DSL
// ./mpp_project/build.gradle

buildkonfig {
    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'
        }
    }
}
Kotlin DSL
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.
import com.codingfeline.buildkonfig.gradle.TargetConfigDsl

buildkonfig {
    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(closureOf<NamedDomainObjectContainer<TargetConfigDsl>> {
        create("android") {
            buildConfigField(STRING, "name2", "value2")
        }

        create("ios") {
            buildConfigField(STRING, "name", "valueIos")
        }
    })
    // flavor is passed as a first argument of targetConfigs
    targetConfigs("dev", closureOf<NamedDomainObjectContainer<TargetConfigDsl>> {
        create("ios") {
            buildConfigField(STRING, "name", "devValueIos")
        }
    })
}

In a development phase you can change value in gradle.properties as you like.
In CI environment, you can pass value via CLI $ ./gradlew build -Pbuildkonfig.flavor=release

Overwriting Values

If you configure same field across multiple defaultConfigs and targetConfigs, flavored targetConfigs is the strongest.

Lefter the stronger.

Flavored TargetConfig > TargetConfig > Flavored DefaultConfig > DefaultConfig

Supported Types

  • String
  • Int
  • Long
  • Float
  • Boolean

Try out the sample

Have a look at ./sample directory.

# Publish the latest version of the plugin to mavenLocal()
$ ./gradlew publishToMavenLocal

# Try out the samples.
# BuildKonfig will be generated in ./sample/build/buildkonfig
$ ./gradlew -p sample generateBuildKonfig
Comments
  • Merge buildKonfig for native targets

    Merge buildKonfig for native targets

    For iOS, we have to create a target for the simulator (iosX64) and the device (iosArm64/iosArm32). I'm merging them through:

    val iosX64 = iosX64()
    val iosArm64 = iosArm64("ios")
    android()
    
    configure(listOf(iosX64, iosArm64)) {
        binaries {
            framework(frameworkName) {
                baseName = frameworkName
            }
        }
    }
    
    val commonMain by sourceSets.getting {
        dependencies {
            ...
        }
    }
    
    val iosX64Main by sourceSets.getting
    val iosMain by sourceSets.getting {
        iosX64Main.dependsOn(this)
        dependencies {
            ...
        }
    }
    

    Problem is, buildkonfig generates for both the targets but since iosX64 is dependent on iosArm64, it produces an redeclaration error. Is there any way we can ignore some of the targets?

    opened by kuuuurt 17
  • Kotlin/JS IR backend breaks when using BuildKonfig's `exposeObjectWithName` option

    Kotlin/JS IR backend breaks when using BuildKonfig's `exposeObjectWithName` option

    As soon as I enable the Config file generation, even with no fields defined, the task compileProductionExecutableKotlinBrowser yields error:

    java.lang.AssertionError: Unexpected field without property myapp.MyConfig.$stable
    	at org.jetbrains.kotlin.ir.backend.js.export.ExportModelGenerator.exportClass(ExportModelGenerator.kt:177)
    	at org.jetbrains.kotlin.ir.backend.js.export.ExportModelGenerator.exportDeclaration(ExportModelGenerator.kt:58)
    	at org.jetbrains.kotlin.ir.backend.js.export.ExportModelGenerator.generateExport(ExportModelGenerator.kt:34)
    	at org.jetbrains.kotlin.ir.backend.js.export.ExportModelGenerator.generateExport(ExportModelGenerator.kt:47)
    	at org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer.generateModule(IrModuleToJsTransformer.kt:46)
    	at org.jetbrains.kotlin.ir.backend.js.CompilerKt.compile(compiler.kt:123)
    	at org.jetbrains.kotlin.ir.backend.js.CompilerKt.compile$default(compiler.kt:36)
    	at org.jetbrains.kotlin.cli.js.K2JsIrCompiler.doExecute(K2JsIrCompiler.kt:256)
    	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:182)
    	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:75)
    	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:90)
    	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
    	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
    	at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1575)
    	at jdk.internal.reflect.GeneratedMethodAccessor105.invoke(Unknown Source)
    	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    	at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
    	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
    	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
    	at java.base/java.security.AccessController.doPrivileged(Native Method)
    	at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    	at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
    	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
    	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
    	at java.base/java.security.AccessController.doPrivileged(Native Method)
    	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
    	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    	at java.base/java.lang.Thread.run(Thread.java:834)
    
    opened by chris-hatton 12
  • Allow BuildKonfig to be public

    Allow BuildKonfig to be public

    Object is generated as internal. To use it from the iOS or Android app requires adding another layer to expose the values. Add an option to generate it as public.

    enhancement contribution welcome 
    opened by dalewking 12
  • Kotlin v1.5.31, XCFramework: targetConfigs fields not found from iOS

    Kotlin v1.5.31, XCFramework: targetConfigs fields not found from iOS

    First of all, thanks so much for an awesome library!

    I have a KMM project that was upgraded to Kotlin v1.5.31 recently. With that release came support for generating an XCFramework that can be consumed from the iOS app, which is awesome since it lets you bundle up different app variants like one for the simulator and one for physical devices.

    Previously I would use BuildKonfig and its targetConfigs option to create fields for different platforms, ios among them. This worked fine on Kotlin v1.5.10. After upgrading to v1.5.31, the fields in the defaultConfigs are found, but not the ones in targetConfigs.

    • Kotlin: 1.5.31
    • Gradle: 7.0.2
    • BuildKonfig: 0.10.2
    opened by eirikvaa 7
  • Generate: val -> const val

    Generate: val -> const val

    Hi, maybe you can use const for generated config objects? Otherwise, you will not be able to make other constants. Constants will allow you to discard chunks of test code that should not be build for a production code.

    const

    
    internal object BuildKonfig {
      val FLAVOR: String = "dev"
    }
    
    ->
    
    internal object BuildKonfig {
      const val FLAVOR: String = "dev"
    }
    
    opened by Jesus13 7
  • BuildKonfig `0.9.0` -> `0.10.0` breaks Gradle Sync

    BuildKonfig `0.9.0` -> `0.10.0` breaks Gradle Sync

    Thanks for BuildKonfig, it continues to be an essential tool for KMP App Development! ❤️ I was happy to see continued maintenance with a 0.10.0 release:

    Unfortunately, this new version has a bug for my project. Gradle Sync fails with the error:

    Duplicate content roots detected:
    Path [/Users/me/project/client/build/buildkonfig/commonMain] of module 
    [project.client.commonMain] was removed from modules [project.client.materialComposeMain]
    

    (I've redacted my actual username and project name but the pattern is preserved) This prevents working with the project.

    If I change only the BuildKonfig dependency back to 0.9.0, everything works as expected.

    My project has quite a nested module structure; perhaps you've changed some code related to adding source-set paths to modules that has caused it to add to multiple source-sets unnecessarily?

    bug 
    opened by chris-hatton 6
  • Add isDebug to generated class

    Add isDebug to generated class

    In Android, BuildConfig holds a DEBUG variable we can use to check the build type.

    Can we have this? Would be useful for some cases like enabling Ktor's Logging on debug build but not on release builds.

    opened by kuuuurt 6
  • can support kotlin Native ?

    can support kotlin Native ?

    Dear Sir

    as this project - https://github.com/bennyhuo/hello-kni

    can use kotlin native to JNI ( kotlin --> c --> JNI --->Android/JVM)

    when call JNI System.loadLibrary is "knlib" , that define at sharedLib in build.gradle.kts

    https://github.com/bennyhuo/hello-kni/blob/27f787c13c27a2fd2e922b632eee66676761fce6/nativeLib/build.gradle.kts#L17

    if use BuildKonfig to define a String buildConfigField like "JNI_NAME_PREFIX" value is "knlib"

    we will get buildConfigField at app

    but it can not work

    THX

    opened by CMingTseng 5
  • Kotlin/JS Exception: non-flavored defaultConfigs must be provided. Despite is provided.

    Kotlin/JS Exception: non-flavored defaultConfigs must be provided. Despite is provided.

    Hey, Thanks for your effort and great tool. I tried to add to my compose playgrond project JS MPP target, using latest version 0.11.0 of BuildKonfig got this error during project sync: org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':common' Caused by: java.lang.IllegalStateException: non-flavored defaultConfigs must be provided. at com.codingfeline.buildkonfig.gradle.BuildKonfigSpecKt.mergeConfigs(BuildKonfigSpec.kt:29)

    Reproducible on this branch in my project: https://github.com/mariuszmarzec/todo/tree/feature/js_support

    opened by mariuszmarzec 5
  • [java.lang.IllegalArgumentException: packageName must be provided] thrown when adding a js(IR) target

    [java.lang.IllegalArgumentException: packageName must be provided] thrown when adding a js(IR) target

    When adding a js(IR) target

    plugins {
        kotlin("multiplatform")
        id("com.android.library")
        id("com.codingfeline.buildkonfig")
    }
    
    kotlin {
        android()
       
        ...
    
        iosTarget("ios") { ... }
    
        js(IR) {
            browser()
        }
    
        sourceSets {
            val commonMain by getting
            val androidMain by getting
            val iosMain by getting
            val jsMain by getting
        }
    }
    
    configure<com.codingfeline.buildkonfig.gradle.BuildKonfigExtension> {
        packageName = "com.sample.buildkonfig.issues"
    
        defaultConfigs {
            buildConfigField(STRING, "VERSION", "mysupersecretpassword")
        }
    }
    

    throws during sync

    Caused by: java.lang.IllegalArgumentException: packageName must be provided
    

    even when the packageName is provided

    Minimal working example here: https://github.com/xxfast/BuildKonfig-Issues

    Or download here: BuildKonfig-Issues-master.zip

    full sync stacktrace:

    
    org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreationException: Could not create task ':shared:generateBuildKonfig'.
    	at org.gradle.api.internal.tasks.DefaultTaskContainer.taskCreationException(DefaultTaskContainer.java:719)
    	at org.gradle.api.internal.tasks.DefaultTaskContainer.access$600(DefaultTaskContainer.java:77)
    	at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.domainObjectCreationException(DefaultTaskContainer.java:711)
    	at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.tryCreate(DefaultNamedDomainObjectCollection.java:948)
    	at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.access$1401(DefaultTaskContainer.java:658)
    	at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider$1.run(DefaultTaskContainer.java:684)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
    	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
    	at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.tryCreate(DefaultTaskContainer.java:680)
    	at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.calculateOwnValue(DefaultNamedDomainObjectCollection.java:929)
    	at org.gradle.api.internal.provider.AbstractMinimalProvider.calculateValue(AbstractMinimalProvider.java:103)
    	at org.gradle.api.internal.provider.Collectors$ElementFromProvider.collectEntries(Collectors.java:98)
    	at org.gradle.api.internal.provider.Collectors$TypedCollector.collectEntries(Collectors.java:329)
    	at org.gradle.api.internal.provider.Collectors$TypedCollector.collectInto(Collectors.java:324)
    	at org.gradle.api.internal.collections.DefaultPendingSource.realize(DefaultPendingSource.java:61)
    	at org.gradle.api.internal.collections.DefaultPendingSource.realizePending(DefaultPendingSource.java:39)
    	at org.gradle.api.internal.collections.SortedSetElementSource.iterator(SortedSetElementSource.java:63)
    	at org.gradle.api.internal.DefaultDomainObjectCollection.iterator(DefaultDomainObjectCollection.java:130)
    	at org.gradle.api.internal.tasks.DefaultTaskContainer.iterator(DefaultTaskContainer.java:624)
    	at org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder.buildTestRunTasks(KotlinMPPGradleModelBuilder.kt:1114)
    	at org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder.buildTarget(KotlinMPPGradleModelBuilder.kt:340)
    	at org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder.buildTargets(KotlinMPPGradleModelBuilder.kt:258)
    	at org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder.buildAll(KotlinMPPGradleModelBuilder.kt:59)
    	at org.jetbrains.plugins.gradle.tooling.internal.ExtraModelBuilder.buildAll(ExtraModelBuilder.java:115)
    	at org.jetbrains.plugins.gradle.tooling.internal.ExtraModelBuilder.buildAll(ExtraModelBuilder.java:80)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuilderWithParameter.build(DefaultToolingModelBuilderRegistry.java:192)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$LockSingleProjectBuilder.lambda$build$0(DefaultToolingModelBuilderRegistry.java:211)
    	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$withProjectLock$3(DefaultProjectStateRegistry.java:310)
    	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:213)
    	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:310)
    	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:291)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$LockSingleProjectBuilder.build(DefaultToolingModelBuilderRegistry.java:211)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingBuilder$1.call(DefaultToolingModelBuilderRegistry.java:246)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingBuilder.build(DefaultToolingModelBuilderRegistry.java:243)
    	at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getModel(DefaultBuildController.java:102)
    	at org.gradle.tooling.internal.consumer.connection.ParameterAwareBuildControllerAdapter.getModel(ParameterAwareBuildControllerAdapter.java:39)
    	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.getModel(UnparameterizedBuildController.java:113)
    	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.getModel(NestedActionAwareBuildControllerAdapter.java:31)
    	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:97)
    	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
    	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:81)
    	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
    	at org.jetbrains.plugins.gradle.model.ProjectImportAction$MyBuildController.findModel(ProjectImportAction.java:542)
    	at org.jetbrains.plugins.gradle.model.ClassSetProjectImportModelProvider.populateProjectModels(ClassSetProjectImportModelProvider.java:31)
    	at org.jetbrains.plugins.gradle.model.ProjectImportAction.addProjectModels(ProjectImportAction.java:201)
    	at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:114)
    	at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:41)
    	at org.gradle.tooling.internal.consumer.connection.InternalBuildActionAdapter.execute(InternalBuildActionAdapter.java:64)
    	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionRunningListener.runAction(AbstractClientProvidedBuildActionRunner.java:134)
    	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionRunningListener.buildFinished(AbstractClientProvidedBuildActionRunner.java:119)
    	at jdk.internal.reflect.GeneratedMethodAccessor324.invoke(Unknown Source)
    	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    	at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:398)
    	at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:380)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:61)
    	at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:368)
    	at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:355)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:43)
    	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:245)
    	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:157)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:61)
    	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:346)
    	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:249)
    	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:141)
    	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
    	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    	at com.sun.proxy.$Proxy18.buildFinished(Unknown Source)
    	at org.gradle.initialization.DefaultGradleLauncher.finishBuild(DefaultGradleLauncher.java:196)
    	at org.gradle.initialization.DefaultGradleLauncher.finishBuild(DefaultGradleLauncher.java:132)
    	at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:72)
    	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:213)
    	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:67)
    	at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:56)
    	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner.runClientAction(AbstractClientProvidedBuildActionRunner.java:53)
    	at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:47)
    	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:66)
    	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    	at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:90)
    	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter.lambda$execute$0(InProcessBuildActionExecuter.java:59)
    	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:86)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:58)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
    	at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.lambda$execute$0(BuildTreeScopeLifecycleBuildActionExecuter.java:34)
    	at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:53)
    	at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:33)
    	at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:28)
    	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:104)
    	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:55)
    	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:64)
    	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:37)
    	at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.lambda$execute$0(SessionScopeLifecycleBuildActionExecuter.java:54)
    	at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:67)
    	at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:50)
    	at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:36)
    	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
    	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
    	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
    	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
    	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:58)
    	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
    	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
    	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
    	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
    	at org.gradle.util.Swapper.swap(Swapper.java:38)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
    	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    	at java.base/java.lang.Thread.run(Thread.java:834)
    Caused by: java.lang.IllegalArgumentException: packageName must be provided
    	at com.codingfeline.buildkonfig.gradle.BuildKonfigPlugin$configure$3$task$1.execute(BuildKonfigPlugin.kt:68)
    	at com.codingfeline.buildkonfig.gradle.BuildKonfigPlugin$configure$3$task$1.execute(BuildKonfigPlugin.kt:16)
    	at org.gradle.api.internal.DefaultMutationGuard$2.execute(DefaultMutationGuard.java:44)
    	at org.gradle.api.internal.DefaultMutationGuard$2.execute(DefaultMutationGuard.java:44)
    	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext$CurrentApplication$1.execute(DefaultUserCodeApplicationContext.java:100)
    	at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction$1.run(DefaultCollectionCallbackActionDecorator.java:95)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
    	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
    	at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction.execute(DefaultCollectionCallbackActionDecorator.java:92)
    	at org.gradle.internal.ImmutableActionSet$SetWithManyActions.execute(ImmutableActionSet.java:329)
    	at org.gradle.api.internal.DefaultDomainObjectCollection.doAdd(DefaultDomainObjectCollection.java:264)
    	at org.gradle.api.internal.DefaultNamedDomainObjectCollection.doAdd(DefaultNamedDomainObjectCollection.java:113)
    	at org.gradle.api.internal.DefaultDomainObjectCollection.add(DefaultDomainObjectCollection.java:258)
    	at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.tryCreate(DefaultNamedDomainObjectCollection.java:944)
    	... 165 more
    
    opened by xxfast 4
  • `targetConfigs` does not work in Kotlin DSL

    `targetConfigs` does not work in Kotlin DSL

    build.config.kts (:kmm_shared:feature)

    plugins {
        //  ..
        id("com.codingfeline.buildkonfig") version "0.7.0"
    }
    
    buildkonfig {
        packageName = "app.mobius.feature"
    
        defaultConfigs { }
    
        targetConfigs {  // ERROR
            android{ }
        }
    
    }
    
    kotlin {
        android()
    }
    
    

    DefaultConfigs is working but targetConfigs generate the following error:

    ERROR:

     * What went wrong:
    Script compilation errors:
    
      Line 42:     targetConfigs {
                                 ^ Type mismatch: inferred type is () -> Unit but Closure<*> was expected
    
    * Exception is:
    ScriptCompilationException(errors=[ScriptCompilationError(message=Type mismatch: inferred type is () -> Unit but Closure<*> was expected, location=/tmp/gradle-kotlin-dsl-2843013171482525738.tmp/build.gradle.kts (42:19)), ScriptCompilationError(message=Type mismatch: inferred type is () -> Unit but Closure<*> was expected, location=/tmp/gradle-kotlin-dsl-2843013171482525738.tmp/build.gradle.kts (59:19))])
            at org.gradle.kotlin.dsl.support.KotlinCompilerKt.compileKotlinScriptModuleTo(KotlinCompiler.kt:177)
    .....
    
    opened by Coronel-B 3
  • Plugin generates invalid class so build fails

    Plugin generates invalid class so build fails

    Hi. During first build, plugin generates expect object BuildKonfig (commonMain) and actual object BuildKonfig (androidMain+jvmMain) and everything works fine. But during second build (without any changes) it regenerates expect object in commonMain to actual object so build fails due to missing expect object and redeclaration of actual objects. Below is part of my build.gradle file.

    apply plugin: 'org.jetbrains.kotlin.multiplatform'
    apply plugin: 'com.android.library'
    apply plugin: 'com.codingfeline.buildkonfig'
    
    kotlin {
            android {
                compilations.all {
                    kotlinOptions.jvmTarget = rootProject.ext.javaVersion
                }
            }
            jvm()
    
            sourceSets {
                all {
                    languageSettings {
                        optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
                        optIn("kotlin.RequiresOptIn")
                    }
                }
    
                commonMain {}
                jvmMain {}
                androidMain {}
                androidRc {}
                androidRelease {}
            }
    }
    
    buildkonfig {
            packageName = project.PACKAGE
    
            defaultConfigs {
                  buildConfigField "BOOLEAN", "ABC", "true", const: true
            }
    
            targetConfigs {
                android {
                    buildConfigField "BOOLEAN", "ABC", "true", const: true
                }
    
                jvm {
                    buildConfigField "BOOLEAN", "ABC", "false", const: true
                }
            }
    }
    
    opened by MichalKlusak 1
  • Generating Secondary and more BuildKonfig object

    Generating Secondary and more BuildKonfig object

    Currently, everything that is generated is added into a single object. That sounds reasonable but we may want to group certain things and seperate from eachother, maybe we can introduce a name into config and use this name to name generated objects

    like this

    configure<BuildKonfigExtension> {
        packageName = "${ProjectSettings.PROJECT_ID}.common"
        name = "VersionBuildKonfig"
    
        defaultConfigs {
                buildConfigField(STRING, "VERSION", project.getVersion(), const = true)
        }
    }
    
    configure<BuildKonfigExtension> {
        packageName = "${ProjectSettings.PROJECT_ID}.common"
        name = "ApiBuildKonfig"
    
        defaultConfigs {
                buildConfigField(STRING, "BASE_URL", "www.asd.com", const = true)
        }
    }
    

    Additionally, this request will also make sense after we implement: https://github.com/yshrsmz/BuildKonfig/issues/74 Since we may want to make some Konfigs internal while some public

    opened by mustafaozhan 0
  • Support config inheritance

    Support config inheritance

    #61

    copied from https://github.com/yshrsmz/BuildKonfig/pull/61#issuecomment-947685297, by @TobiasPr


    Why did you decide that the hierarchical higher source set always has precedence? I think this is counter intuitive. I think about as inheritance in which lower hierarchical source set inherits the props from the higher source set, but it should still be able to set a more specific value right now we have a sourceset hierarchy like this:

    commonMain/
    ├─ jvmMain/
    │├─ androidMain/
    ├─ iosMain/
    

    for androidMain the buildkonfig is not generated - only for the jvmMain

    opened by yshrsmz 7
  • provide a way to read values from properties file

    provide a way to read values from properties file

    Not sure the DSL below is possible, but something like this

    buildKonfig {
      defaultConfigs {
        // load all values as string
        fromProperties file('./secrets.properties') {
          // specify type
          propertyAs type: 'INT', key: 'KEY_OF_PROPERTY'
    
          // also specify different name
          propertyAs type: 'LONG', key: 'key.of.other', name: 'DIFFERENT_NAME'
        }
    
        // you can also add other stuff as usual
        buildKonfigField('STRING', 'FOO', 'bar')
      }
    }
    
    opened by yshrsmz 7
  • Support other Kotlin plugins

    Support other Kotlin plugins

    Currently the multiplatform plugin is required to use BuildKonfig. It would be nice to be able to use BuildKonfig in non-multiplatform projects as well, namely in standalone JVM, JS, or Native projects that use the other respective Kotlin plugins.

    enhancement help wanted 
    opened by dellisd 1
Releases(v0.13.3)
Owner
Yasuhiro SHIMIZU
Android/Web developer
Yasuhiro SHIMIZU
Mobile client for official Nextcloud News App written as Kotlin Multiplatform Project

Newsout Android and iOS mobile client for Nextcloud news App. The Android client is already available to download in the Play Store. F-Droid and Apple

Simon Schubert 118 Oct 3, 2022
Kotlin Multiplatform project that gets network data from Food2Fork.ca

Food2Fork Recipe App This is the codebase for a Kotlin Multiplatform Mobile course. [Watch the course](https://codingwithmitch.com/courses/kotlin-mult

Mitch Tabian 317 Dec 30, 2022
A sample project that helps to start building a Mobile Kotlin Multiplatform application

Mobile Kotlin multiplatform project template A sample project that helps to start building a Mobile Kotlin Multiplatform application. It establishes a

Dizel 0 Oct 16, 2021
A Kotlin Multiplatform Project using TMDB Api. Currently supports Android,iOS,Desktop and web platforms

A Kotlin Multiplatform Project using TMDB Api(https://www.themoviedb.org/). Currently this project is implemented in following platforms Andr

Jackson E J 11 Nov 10, 2022
A Kotlin Multiplatform and Compose template that allows you to easily set up your project targeting: Android, Desktop, and Web

A Kotlin Multiplatform and Compose template that allows you to easily set up your project targeting: Android, Desktop, and Web

Carlos Mota 3 Oct 27, 2021
This is a Kotlin multiplatform template project used to generate and deploy a natively compiled AWS lambda function using the custom runtime.

Overview This is a Kotlin multiplatform template project used to generate and deploy a natively compiled AWS Lambda function using a custom runtime. U

Greg Steckman 5 Jun 25, 2022
PraxisKmm - A Kotlin multiplatform base project

PraxisKMM Minimal Kotlin Multiplatform project with SwiftUI, Jetpack Compose, Co

Mutual Mobile 45 Nov 15, 2022
Funstuff - Minimal Kotlin Multiplatform project with SwiftUI, Jetpack Compose, Compose for Wear OS, Compose for Desktop

PeopleInSpace Minimal Kotlin Multiplatform project with SwiftUI, Jetpack Compose

Shivam Dhuria 2 Feb 15, 2022
Opinionated Redux-like implementation backed by Kotlin Coroutines and Kotlin Multiplatform Mobile

CoRed CoRed is Redux-like implementation that maintains the benefits of Redux's core idea without the boilerplate. No more action types, action creato

Kittinun Vantasin 28 Dec 10, 2022
An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile.

An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile. 项目架构主要分为原生系统层、Android/iOS业务SDK层、KMM SDK层、KMM业务逻辑SDK层、iOS sdkfra

libill 4 Nov 20, 2022
Skeleton project for show the architecture of Android project using MVVM, Clean Architecture and Kotlin coroutine Flow

ClearScoreDemo Skeleton project for showing the architecture of Android project using MVVM, Clean architecture and Kotlin coroutine Flow App Architect

Plabon Modak 1 Mar 6, 2022
A Bluetooth kotlin multiplatform "Cross-Platform" library for iOS and Android

Blue-Falcon A Bluetooth "Cross Platform" Kotlin Multiplatform library for iOS, Android, MacOS, Raspberry Pi and Javascript. Bluetooth in general has t

Andrew Reed 220 Dec 28, 2022
Kotlin Multiplatform Application to show Crypto Coins

This is the codebase of Crypto currency Tracking Kotlin Multiplatform App. Components Shared Components Ktor (Network Client) SQL Delight (Local DB) A

Aman Bansal 10 Oct 31, 2022
Dependency Injection library for Kotlin Multiplatform, support iOS and Android

Multiplatform-DI library for Kotlin Multiplatform Lightweight dependency injection framework for Kotlin Multiplatform application Dependency injection

Anna Zharkova 32 Nov 10, 2022
Kotlin multiplatform library template.

template-kmp-library Kotlin multiplatform library template. Has a baseline setup for a multiplatform library supporting all kotlin targets except andr

Martynas Petuška 51 Nov 21, 2022
Kotlin multiplatform benchmarking toolkit

NOTE: Starting from version 0.3.0 of the library: The library runtime is published to Maven Central and no longer published to Bintray. The Gradle plu

Kotlin 310 Jan 2, 2023
Gradle plugin for simplify Kotlin Multiplatform mobile configurations

Mobile Multiplatform gradle plugin This is a Gradle plugin for simple setup of Kotlin Multiplatform mobile Gradle modules. Setup buildSrc/build.gradle

IceRock Development 78 Sep 27, 2022
Generic AST parsing library for kotlin multiplatform

kotlinx.ast kotlinx.ast is a generic AST (Abstract Syntax Tree) parsing library, Kotlin is currently the only supported language. The library is desig

null 235 Dec 29, 2022
KaMP Kit by Touchlab is a collection of code and tools designed to get your mobile team started quickly with Kotlin Multiplatform.

KaMP Kit Welcome to the KaMP Kit! About Goal The goal of the KaMP Kit is to facilitate your evaluation of Kotlin Multiplatform (aka KMP). It is a coll

Touchlab 1.7k Jan 3, 2023