๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Android

๐Ÿ˜ Groovy ์—์„œ KTS๋กœ ์ „ํ™˜ํ•˜๊ธฐ

๐Ÿ˜ ๋ชฉํ‘œ

gradle ๊ด€๋ฆฌ ์–ธ์–ด Groovy -> kts๋กœ ๋ฐ”๊พธ๊ธฐ


๐Ÿ˜ Gradle

์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ์—์„  ๋‹ค์–‘ํ•œ ์˜คํ”ˆ ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ ์žฅ์ ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋งŽ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•œ๋ฐ, Android Studio์—์„œ๋Š” ๊ทธ ๋„๊ตฌ๋กœ Gradle์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

Gradle์€ JVM์—์„œ ๋™์ž‘ํ•˜๋Š” ๋นŒ๋“œ ์ž๋™ํ™” ์‹œ์Šคํ…œ์œผ๋กœ,

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ ๋ฟ ์•„๋‹ˆ๋ผ ์ปดํŒŒ์ผ, ํ…Œ์ŠคํŠธ, ํŒจํ‚ค์ง• ๋“ฑ์˜ ๋นŒ๋“œ ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์กด์— ์กด์žฌํ•˜๋˜ Ant, Maven์— ๋น„ํ•ด ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค๋Š” ๊ฒƒ์ด ์žฅ์ ์ž…๋‹ˆ๋‹ค.

 


๐Ÿ˜ Groovy vs KTS

Gradle์€ ์ž๋ฐ”์™€ ๋น„์Šทํ•œ Groovy ์–ธ์–ด๋กœ ์ž‘์„ฑํ•˜์˜€๋Š”๋ฐ, ์ด์ œ๋Š” KTS(์ฝ”ํ‹€๋ฆฐ ์Šคํฌ๋ฆฝํŠธ)๋กœ ์ด๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Groovy๋ฅผ ๋Œ€์ฒดํ•˜๋Š” KTS์˜ ์žฅ์ ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Groovy ์–ธ์–ด๋ฅผ ๋”ฐ๋กœ ๋ฐฐ์šฐ์ง€ ์•Š์•„๋„ ๋œ๋‹ค. 
  • Groovy๋Š” ํŒŒ์ผ์„ ์‹คํ–‰ํ•ด์•ผ ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๋ฐ˜๋ฉด, KTS๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„์— ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • IDE๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ž๋™์™„์„ฑ์„ ์ง€์›ํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Groovy๋ณด๋‹ค ๋Š๋ฆฌ๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ - https://github.com/gradle/gradle/issues/15886

 

๋น„๋ก ๋Š๋ ค์ง„๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์—ˆ์ง€๋งŒ (์ •๋ง ๊ฝค ๋Š๋ ค์ง‘๋‹ˆ๋‹ค)

๋” ์ž˜ ์•„๋Š” ์ฝ”ํ‹€๋ฆฐ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ๊ณ , gradle ์ฝ”๋“œ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ํ”„๋กœ์ ํŠธ์— KTS๋ฅผ ๋„์ž…ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 


๐Ÿ˜ KTS Migration

KTS๋กœ ์ „ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด์„ 

1. .gradle ํŒŒ์ผ์„ .gradle.kts๋กœ ํŒŒ์ผ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๊ณ 

2. ์ฝ˜ํ…์ธ ๋ฅผ KTS ๋ฌธ๋ฒ•์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

์œ„ ๊ณผ์ •์„ ์ง„ํ–‰ํ•˜๊ธฐ ์•ž์„œ build.gradle ์ฝ”๋“œ๋ฅผ ์ข€ ๋” ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ

buildSrc ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์˜์กด์„ฑ ๊ด€๋ จ ๋‚ด์šฉ์„ ์ƒ์ˆ˜๋กœ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


1. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— buildSrc ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ

buildSrc ๋””๋ ‰ํ† ๋ฆฌ์—์„œ๋Š” KTS ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ ์ „์ฒด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…๊ณผ ๋„๊ตฌ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

1. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— buildSrc ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ (New → Directory)

2. buildSrc ๋””๋ ‰ํ† ๋ฆฌ์— build.gradle.kts ํŒŒ์ผ ์ถ”๊ฐ€ ํ›„ sync

plugins {
    `kotlin-dsl`
}

repositories {
    google()
    mavenCentral()
}

 

2. gradle ๊ด€๋ฆฌ์— ํ•„์š”ํ•œ ์„ค์ • ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ

buildSrc ์šฐํด๋ฆญ ํ›„

new → Directory : src\main\kotlin ์„ ํƒ ํ›„ object ํŒŒ์ผ ์ƒ์„ฑ

 

๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ๊ฐ ํŒŒ์ผ์— ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

 

Configs 

์•ฑ ๊ธฐ๋ณธ ์ •๋ณด ๊ด€๋ฆฌ ํŒŒ์ผ

Libraries 

์•ฑ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ ํŒŒ์ผ

Versions 

์•ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „ ๊ด€๋ฆฌ ํŒŒ์ผ

 

์ƒ์ˆ˜ ํ˜•ํƒœ์˜ ๊ฐ’๋“ค๋กœ ์ด๋ฃจ์–ด์ง„ ์„ค์ •ํŒŒ์ผ์„ ๋งŒ๋“ค ๊ฑด๋ฐ, kotlin ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

object Obj {
    const val value1 = "value"
    const val value2 = 30
}

 

Configs ์˜ˆ์‹œ

// buildSrc/src/main/kotlin/Configs.kt
object Configs {
    const val applicationId = "applicationId"
    const val compileSdkVersion = 31
    const val minSdkVersion = 26
    const val targetSdkVersion = 30
    const val versionCode = 1
    const val versionName = "1.0.0"
}

 

Versions ์˜ˆ์‹œ

// buildSrc/src/main/kotlin/Versions.kt
object Versions {

    // classpath
    const val classPathVersion = "7.2.0"
    const val kotlinVersion = "1.6.21"
    const val hiltVersion = "2.40.1"
    const val navigationVersion = "2.5.0"

    // core
    const val coreKtxVersion = "1.7.0"
    const val coroutineVersion = "1.6.0"

    // .. ์ƒ๋žต

    // test
    const val junit = "4.13.2"
    const val espressoVersion = "3.4.0"
    const val androidxTestVersion = "1.2.0"
    const val mockitoVersion = "2.24.5"
}

Libraries ์˜ˆ์‹œ

object Libraries {

    object CLASSPATH {
        const val classpathGradle = "com.android.tools.build:gradle:${Versions.classPathVersion}"
        const val classpathKotlinGradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlinVersion}"
        const val classpathHilt = "com.google.dagger:hilt-android-gradle-plugin:${Versions.hiltVersion}"
        const val classpathNavigation = "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.navigationVersion}"
    }
    
    object Core {
        const val KOTLIN_STDLIB = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlinVersion}"
        const val COROUTINE = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutineVersion}"
    }

    object UI {
        // ์ƒ๋žต..
    }

    object AndroidX {
        // ์ƒ๋žต..
    }

    object DI {
        // ์ƒ๋žต..
    }

    object ThirdParty {
        // ์ƒ๋žต..
    }

    object Test {
        // ์ƒ๋žต..
    }

    object AndroidTest {
        // ์ƒ๋žต..
    }
}

 


 

2. settings.grade ํŒŒ์ผ ํ™•์žฅ์ž kts๋กœ ๋ณ€๊ฒฝ ํ›„ kotlin ๋ฌธ๋ฒ•์— ๋งž๊ฒŒ ํŒŒ์ผ ์ˆ˜์ •ํ•˜๊ธฐ

 

1. setting.gradle → setting.gradle.kts ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

 

2. kts ๋ฌธ๋ฒ•์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

rootProject.name = "Mindgarden"
include(":app")

 

4. ํ”„๋กœ์ ํŠธ ์ˆ˜์ค€ build.gradle ํŒŒ์ผ ํ™•์žฅ์ž kts๋กœ ๋ณ€๊ฒฝ ํ›„ ๋ฌธ๋ฒ•์— ๋งž๊ฒŒ ์ˆ˜์ •

build.src์— ์ •์˜ํ•œ ๋‚ด์šฉ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

classpath(Libraries.CLASSPATH.classpathHilt)

build.gradle(Project) ์ฝ”๋“œ

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {

    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath(Libraries.CLASSPATH.classpathGradle)
        classpath(Libraries.CLASSPATH.classpathKotlinGradle)

        classpath(Libraries.CLASSPATH.classpathHilt)
        classpath(Libraries.CLASSPATH.classpathNavigation)
    }
}

allprojects {

    repositories {
        google()
        mavenCentral()
    }
}

tasks.register("clean", Delete::class) {
    delete(rootProject.buildDir)
}

 

5. ๋ชจ๋“ˆ ์ˆ˜์ค€ build.gradle ํŒŒ์ผ kts๋กœ ์ด๋ฆ„ ๋ณ€๊ฒฝ ํ›„ ๋ฌธ๋ฒ•์— ๋งž๊ฒŒ ์ˆ˜์ •

plugins {
    id("com.android.application")
    id("kotlin-android")
    id("kotlin-kapt")
    id("androidx.navigation.safeargs.kotlin")
    id("dagger.hilt.android.plugin")
}

android {
    compileSdk = Configs.compileSdkVersion

    defaultConfig {
        applicationId = Configs.applicationId
        minSdk = Configs.minSdkVersion
        targetSdk = Configs.targetSdkVersion
        versionCode = Configs.versionCode
        versionName = Configs.versionName

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
            )
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_11.toString()
    }

    testOptions {
        unitTests {
            isReturnDefaultValues = true
        }
    }

    buildFeatures {
        viewBinding = true
        dataBinding = true
    }

    namespace = "com.app.myapp"
}

dependencies {
    // core
    implementation(Libraries.Core.KOTLIN_STDLIB)
    implementation(Libraries.Core.COROUTINE)

    // UI
    implementation(Libraries.UI.MATERIAL)
    implementation(Libraries.UI.CONSTRAINT_LAYOUT)
    implementation(Libraries.UI.FRAGMENT_KTX)

    // AndroidX
    implementation(Libraries.AndroidX.CORE_KTX)
    implementation(Libraries.AndroidX.APP_COMPAT)

    // di hilt
    implementation(Libraries.DI.HILT)
    kapt(Libraries.DI.HILT_COMPILER)

    // 3rd
    // glide
    implementation(Libraries.ThirdParty.GLIDE)
    kapt(Libraries.ThirdParty.GLIDE_COMPILER)

    // test
    testImplementation(Libraries.Test.JUNIT)
    androidTestImplementation(Libraries.AndroidTest.JUNIT_KOTLIN)
    androidTestImplementation(Libraries.AndroidTest.ROOM)
    androidTestImplementation(Libraries.AndroidTest.ESPRESSO_CORE)
    androidTestImplementation(Libraries.AndroidTest.COROUTINE)
    androidTestImplementation(Libraries.AndroidTest.TEST_RUNNER)
    androidTestImplementation(Libraries.AndroidTest.TEST_RULES)
    androidTestImplementation(Libraries.AndroidTest.MOCKITO)
}

// Allow references to generated code
kapt {
    correctErrorTypes = true
}

 


๐Ÿ˜ Meaning 

  • Groovy์˜ ์—ญํ• 
  • Groovy์™€ KTS ๋น„๊ต, KTS์˜ ์žฅ์ ๊ณผ ๋‹จ์ 
  • Groovy์—์„œ KTS๋กœ ์ „ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ์žฅ์ 

๋นŒ๋“œ ์†๋„๊ฐ€ ์ƒ๊ฐ๋ณด๋‹ค ๋” ๋Š๋ ค์ง€๊ธด ํ–ˆ์ง€๋งŒ ๐Ÿ˜ง

IDE๋ฅผ ํ†ตํ•ด ์ž๋™ ์™„์„ฑ์ด ์ง€์›๋˜๊ณ  ์ฝ”๋“œ๋ฅผ ๋” ๊ฐ€๋…์„ฑ ์žˆ๊ฒŒ ๋งŒ๋“ค๊ณ  ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ๋งŒ์กฑ์Šค๋Ÿฌ์› ์Šต๋‹ˆ๋‹ค.


๐Ÿ˜ ์ฐธ๊ณ 

https://docs.gradle.org/nightly/userguide/migrating_from_groovy_to_kotlin_dsl.html

 

Migrating build logic from Groovy to Kotlin

Declaring dependencies in existing configurations is similar to the way it’s done in Groovy build scripts, as you can see in this example: build.gradle.kts plugins { `java-library` } dependencies { implementation("com.example:lib:1.1") runtimeOnly("com.e

docs.gradle.org

https://developer.android.com/studio/build/migrate-to-kts?hl=ko 

 

Groovy์—์„œ KTS๋กœ ๋นŒ๋“œ ๊ตฌ์„ฑ ์ด์ „  |  Android ๊ฐœ๋ฐœ์ž  |  Android Developers

Gradle ๊ตฌ์„ฑ ํŒŒ์ผ์„ Groovy์—์„œ KTS๋กœ ์ด์ „ํ•ฉ๋‹ˆ๋‹ค.

developer.android.com

https://blog.kotlin-academy.com/kotlin-dsl-buildsrc-product-flavors-flavor-icon-and-more-abf30c65e8fd

 

Kotlin DSL, BuildSrc, Product Flavors, Flavor Icon and more

I wanted for a long time migrate gradle files to kotlin dsl but i was always procrastinating. I finally put an end to it and also I…

blog.kotlin-academy.com

 https://github.com/gradle/gradle/issues/15886

 

The Kotlin and Groovy DSLs should have similar performance characteristics · Issue #15886 · gradle/gradle

Expected Behavior The Kotlin and Groovy DSLs have as much as possible similar performance characteristics. IOW there's no outlier use case for which the performance characteristics make using o...

github.com

 

'Android' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Compose Tutorial : ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ  (1) 2024.01.14
Compose๋กœ RecyclerView ๋Œ€์ฒดํ•ด๋ณด๊ธฐ  (1) 2023.02.28
Hilt  (0) 2022.03.25
[Android] Very Long Vector Path issue  (0) 2021.08.17
Vector Asset  (0) 2021.07.25