{"id":13537397,"url":"https://github.com/yshrsmz/BuildKonfig","last_synced_at":"2025-04-02T04:30:37.900Z","repository":{"id":38310626,"uuid":"166752017","full_name":"yshrsmz/BuildKonfig","owner":"yshrsmz","description":"BuildConfig for Kotlin Multiplatform Project","archived":false,"fork":false,"pushed_at":"2024-04-10T04:15:02.000Z","size":578,"stargazers_count":621,"open_issues_count":23,"forks_count":31,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-10T05:42:18.946Z","etag":null,"topics":["buildconfig","gradle-plugin","kotlin","kotlin-mpp","kotlin-multiplatform"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yshrsmz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"yshrsmz","patreon":null,"open_collective":null,"ko_fi":"yshrsmz","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2019-01-21T05:13:06.000Z","updated_at":"2024-04-15T08:03:49.051Z","dependencies_parsed_at":"2023-10-05T05:57:19.301Z","dependency_job_id":"3830f63f-b1e7-4725-a34a-3885253e41b2","html_url":"https://github.com/yshrsmz/BuildKonfig","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yshrsmz%2FBuildKonfig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yshrsmz%2FBuildKonfig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yshrsmz%2FBuildKonfig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yshrsmz%2FBuildKonfig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yshrsmz","download_url":"https://codeload.github.com/yshrsmz/BuildKonfig/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246756868,"owners_count":20828782,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["buildconfig","gradle-plugin","kotlin","kotlin-mpp","kotlin-multiplatform"],"created_at":"2024-08-01T09:00:58.577Z","updated_at":"2025-04-02T04:30:37.889Z","avatar_url":"https://github.com/yshrsmz.png","language":"Kotlin","funding_links":["https://github.com/sponsors/yshrsmz","https://ko-fi.com/yshrsmz"],"categories":["Kotlin","Libraries"],"sub_categories":["Build \u0026 Development Tools"],"readme":"BuildKonfig\n===\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.codingfeline.buildkonfig/buildkonfig-gradle-plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.codingfeline.buildkonfig/buildkonfig-gradle-plugin)\n\nBuildConfig for Kotlin Multiplatform Project.  \nIt currently supports embedding values from gradle file.\n\n## Table Of Contents\n\n- [Motivation](#motivation)\n- [Usage](#usage)\n    - [Requirements](#requirements)\n    - [Gradle Configuration](#gradle-configuration)\n    - [Product Flavor?](#product-flavor)\n    - [Overwriting Values](#overwriting-values)\n    - [HMPP](#hmpp)\n- [Supported Types](#supported-types)\n- [Try out the sample](#try-out-the-sample)\n\n\u003ca name=\"motivation\"/\u003e\n\n## Motivation\n\nPassing values from Android/iOS or any other platform code should work, but it's a hassle.  \nSetting up Android to read values from properties and add those into BuildConfig, and do the equivalent in iOS?  \nRather I'd like to do it once.\n\n\n\u003ca name=\"usage\"/\u003e\n\n## Usage\n\n\u003ca name=\"requirements\"/\u003e\n\n### Requirements\n\n- Kotlin **1.5.30** or later\n- Kotlin Multiplatform Project\n- Gradle 7 or later\n\n\u003ca name=\"gradle-configuration\"/\u003e\n\n### Gradle Configuration\n\n#### Simple configuration\n\n\u003cdetails open\u003e\n\u003csummary\u003eGroovy DSL\u003c/summary\u003e\n\n```gradle\nbuildScript {\n    repositories {\n        mavenCentral()\n    }\n    dependencies {\n        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0'\n        classpath 'com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version'\n    }\n}\n\napply plugin: 'org.jetbrains.kotlin.multiplatform'\napply plugin: 'com.codingfeline.buildkonfig'\n\nkotlin {\n    // your target config...\n    androidTarget()\n    iosX64('ios')\n}\n\nbuildkonfig {\n    packageName = 'com.example.app'\n    // objectName = 'YourAwesomeConfig'\n    // exposeObjectWithName = 'YourAwesomePublicConfig'\n\n    defaultConfigs {\n        buildConfigField 'STRING', 'name', 'value'\n    }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eKotlin DSL\u003c/summary\u003e\n\n```kotlin\nimport com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING\n\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n    dependencies {\n        classpath(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0\")\n        classpath(\"com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version\")\n    }\n}\n\nplugins {\n    kotlin(\"multiplatform\")\n    id(\"com.codingfeline.buildkonfig\")\n}\n\nkotlin {\n    // your target config...\n    androidTarget()\n    iosX64('ios')\n}\n\nbuildkonfig {\n    packageName = \"com.example.app\"\n    // objectName = \"YourAwesomeConfig\"\n    // exposeObjectWithName = \"YourAwesomePublicConfig\"\n\n    defaultConfigs {\n        buildConfigField(STRING, \"name\", \"value\")\n    }\n}\n```\n\n\u003c/details\u003e\n\n- `packageName` Set the package name where BuildKonfig is being placed. **Required**.\n- `objectName` Set the name of the generated object. Defaults to `BuildKonfig`.\n- `exposeObjectWithName` Set the name of the generated object, and make it public.\n- `defaultConfigs` Set values which you want to have in common. **Required**.\n\nTo generate BuildKonfig files, run `generateBuildKonfig` task.  \nThis task will be automatically run upon execution of kotlin compile tasks.\n\nAbove configuration will generate following simple object.\n\n```kotlin\n// commonMain\npackage com.example.app\n\ninternal object BuildKonfig {\n    val name: String = \"value\"\n}\n```\n\n#### Configuring `target` dependent values\n\nIf you want to change value depending on your targets, you can use `targetConfigs` to define target-dependent values.\n\n\u003cdetails open\u003e\n\u003csummary\u003eGroovy DSL\u003c/summary\u003e\n\n```gradle\nbuildScript {\n    repositories {\n        mavenCentral()\n    }\n    dependencies {\n        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0'\n        classpath 'com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version'\n    }\n}\n\napply plugin: 'org.jetbrains.kotlin.multiplatform'\napply plugin: 'com.codingfeline.buildkonfig'\n\nkotlin {\n    // your target config...\n    androidTarget()\n    iosX64('ios')\n}\n\nbuildkonfig {\n    packageName = 'com.example.app'\n    \n    // default config is required\n    defaultConfigs {\n        buildConfigField 'STRING', 'name', 'value'\n        buildConfigField 'STRING', 'nullableField', null, nullable: true\n    }\n    \n    targetConfigs {\n        // this name should be the same as target names you specified\n        android {\n            buildConfigField 'STRING', 'name2', 'value2'\n            buildConfigField 'STRING', 'nullableField', 'NonNull-value', nullable: true\n        }\n        \n        ios {\n            buildConfigField 'STRING', 'name', 'valueForNative'\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eKotlin DSL\u003c/summary\u003e\n\n```kotlin\nimport com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING\n\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n    dependencies {\n        classpath(\"org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0\")\n        classpath(\"com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version\")\n    }\n}\n\nplugins {\n    kotlin(\"multiplatform\")\n    id(\"com.codingfeline.buildkonfig\")\n}\n\nkotlin {\n    // your target config...\n    androidTarget()\n    iosX64('ios')\n}\n\nbuildkonfig {\n    packageName = \"com.example.app\"\n\n    // default config is required\n    defaultConfigs {\n        buildConfigField(STRING, \"name\", \"value\")\n    }\n\n    targetConfigs {\n        // names in create should be the same as target names you specified\n        create(\"android\") {\n            buildConfigField(STRING, \"name2\", \"value2\")\n            buildConfigField(STRING, \"nullableField\", \"NonNull-value\", nullable = true)\n        }\n\n        create(\"ios\") {\n            buildConfigField(STRING, \"name\", \"valueForNative\")\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\n- `packageName`\n  - Sets the package name where BuildKonfig is being placed. **Required**.\n- `objectName` \n  - Sets the name of the generated object. Defaults to `BuildKonfig`.\n- `exposeObjectWithName`\n  - Sets the name of the generated object, and make it public.\n- `defaultConfigs`\n  - Sets values which you want to have in common. **Required**.\n- `targetConfigs` \n  - Sets target specific values as closure. You can overwrite values specified in `defaultConfigs`.\n- `buildConfigField(type: String, name: String, value: String)`\n  - Adds new value or overwrite existing one.\n- `buildConfigField(type: String, name: String, value: String, nullable: Boolean = false, const: Boolean = false)` \n  - In addition to above method, this can configure `nullable` and `const` declarations.\n\nAbove configuration will generate following codes.\n\n```kotlin\n// commonMain\npackage com.example.app\n\ninternal expect object BuildKonfig {\n    val name: String\n    val nullableField: String?\n}\n```\n\n```kotlin\n// androidMain\npackage com.example.app\n\ninternal actual object BuildKonfig {\n    actual val name: String = \"value\"\n    actual val nullableField: String? = \"NonNull-value\"\n    val name2: String = \"value2\"\n}\n```\n\n```kotlin\n// iosMain\npackage com.example.app\n\ninternal actual object BuildKonfig {\n    actual val name: String = \"valueForNative\"\n    actual val nullableField: String? = null\n}\n```\n\n\u003ca name=\"product-flavor\"/\u003e\n\n### Product Flavor?\n\nYes(sort of).  \nKotlin Multiplatform Project does not support product flavor. Kotlin/Native part of the project has release/debug\ndistinction, but it's not global.  \nSo to mimick product flavor capability of Android, we need to provide additional property in order to determine flavors.\n\nSpecify default flavor in your `gradle.properties`\n\n```properties\n# ROOT_DIR/gradle.properties\nbuildkonfig.flavor=dev\n```\n\n\u003cdetails open\u003e\n\u003csummary\u003eGroovy DSL\u003c/summary\u003e\n\n```gradle\n// ./mpp_project/build.gradle\n\nbuildkonfig {\n    packageName = 'com.example.app'\n    \n    // default config is required\n    defaultConfigs {\n        buildConfigField 'STRING', 'name', 'value'\n    }\n    // flavor is passed as a first argument of defaultConfigs \n    defaultConfigs(\"dev\") {\n        buildConfigField 'STRING', 'name', 'devValue'\n    }\n    \n    targetConfigs {\n        android {\n            buildConfigField 'STRING', 'name2', 'value2'\n        }\n        \n        ios {\n            buildConfigField 'STRING', 'name', 'valueIos'\n        }\n    }\n    // flavor is passed as a first argument of targetConfigs\n    targetConfigs(\"dev\") {\n        ios {\n            buildConfigField 'STRING', 'name', 'devValueIos'\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eKotlin DSL\u003c/summary\u003e\n\n```kotlin\nimport com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING\nimport com.codingfeline.buildkonfig.gradle.TargetConfigDsl\n\nbuildkonfig {\n    packageName = \"com.example.app\"\n\n    // default config is required\n    defaultConfigs {\n        buildConfigField(STRING, \"name\", \"value\")\n    }\n    // flavor is passed as a first argument of defaultConfigs \n    defaultConfigs(\"dev\") {\n        buildConfigField(STRING, \"name\", \"devValue\")\n    }\n\n    targetConfigs {\n        create(\"android\") {\n            buildConfigField(STRING, \"name2\", \"value2\")\n        }\n\n        create(\"ios\") {\n            buildConfigField(STRING, \"name\", \"valueIos\")\n        }\n    }\n    // flavor is passed as a first argument of targetConfigs\n    targetConfigs(\"dev\") {\n        create(\"ios\") {\n            buildConfigField(STRING, \"name\", \"devValueIos\")\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\nIn a development phase you can change value in `gradle.properties` as you like.  \nIn CI environment, you can pass value via CLI `$ ./gradlew build -Pbuildkonfig.flavor=release`\n\n\n\u003ca name=\"overwriting-values\"/\u003e\n\n### Overwriting Values\n\nIf you configure same field across multiple defaultConfigs and targetConfigs, flavored targetConfigs is the strongest.\n\nLefter the stronger.\n\n```\nFlavored TargetConfig \u003e TargetConfig \u003e Flavored DefaultConfig \u003e DefaultConfig\n```\n\n\u003ca name=\"hmpp\"/\u003e\n\n### HMPP Support\n\na.k.a `Intermediate SourceSets`. (see [Share code on platforms](https://kotlinlang.org/docs/mpp-share-on-platforms.html)\nfor detail.)  \nBuildKonfig supports HMPP. However there's some limitations.\n\n**When you add a targetConfigs for a intermediate source set, you can't define another targetConfigs for its children\nsource sets.**\n\nFor example, say your have a source set structure like below.\n\n```\n- commonMain\n  - appMain\n    - androidMain\n    - desktopMain\n      - macosX64Main\n      - linuxX64Main\n      - mingwX64Main\n  - jsCommonMain\n    - browserMain\n    - nodeMain\n  - iosMain\n    - iosArm64Main\n    - iosX64Main\n```\n\nIf you add a targetConfigs for `appMain`, you can't add configs for androidMain, desktopMain, or children of\ndesktopMain. This is because BuildKonfig uses expect/actual to provide different values for each BuildKonfig object.\nWhen you provide a configuration for `appMain`, actual declaration of BuildKonfig object is created in `appMain`. So any\nadditional actual declarations in children SourceSets leads to compile-time error.\n\n\n\u003ca name=\"supported-types\"/\u003e\n\n## Supported Types\n\n- String\n- Int\n- Long\n- Float\n- Boolean\n\n\u003ca name=\"try-out-the-sample\"/\u003e\n\n## Try out the sample\n\nThere are two samples; `sample` and `sample-kts`.\nAs its name implies, `sample-kts` a Kotlin DSL sample, and the other is a traditional Groovy DSL.\n\nHave a look at `./sample` directory.\n\n```\n# Publish the latest version of the plugin to test maven repository(./build/localMaven)\n$ ./gradlew publishAllPublicationsToTestMavenRepository -PRELEASE_SIGNING_ENABLED=false\n\n# Try out the samples.\n# BuildKonfig will be generated in ./sample/build/buildkonfig\n$ ./gradlew -p sample generateBuildKonfig\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyshrsmz%2FBuildKonfig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyshrsmz%2FBuildKonfig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyshrsmz%2FBuildKonfig/lists"}