004. (KMM Mobile) 4. BuildSrc 적용 및 의존성 설정
4. BuildSrc 적용 및 의존성 설정 이전 포스팅에서 생성한 프로젝트에 의존성 관리는 위한 BuildSrc
모듈을 추가해보자.
참고 프로젝트에 따라 build-logic
으로 생성하기도 한다.
4.1. BuildSrc 모듈 생성 루트 폴더 하위에 buildSrc
폴더와 build.gradle.kts
스크립트 파일을 추가한다.
이후
build.gradle.kts
에 아래 스크립트를 작성한다.
1 2 3 4 5 6 7 8 9 import org.gradle.kotlin.dsl.`kotlin-dsl`repositories { mavenCentral() } plugins { `kotlin-dsl` }
이후 아래와 같이 소스 폴더를 생성한다.
이후 Gradle Sync를 수행하면 .gradle
폴더가 빌드를 수행하면 build
폴더가 생성됨을 확인할 수 있다.
4.2. 의존성 관리를 위한 Deps
클래스 추가 buildSrc/src/main/kotlin
경로에 Deps
오브젝트 클래스 파일을 추가한 뒤 아래 코드를 작성한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 object Deps { private const val activityComposeVersion = "1.7.2" const val activityCompose = "androidx.activity:activity-compose:$activityComposeVersion " const val composeVersion = "1.5.1" const val composeUi = "androidx.compose.ui:ui:$composeVersion " const val composeUiTooling = "androidx.compose.ui:ui-tooling:$composeVersion " const val composeUiToolingPreview = "androidx.compose.ui:ui-tooling-preview:$composeVersion " const val composeFoundation = "androidx.compose.foundation:foundation:$composeVersion " const val composeMaterial = "androidx.compose.material:material:$composeVersion " const val composeIconsExtended = "androidx.compose.material:material-icons-extended:$composeVersion " const val composeMaterial3 = "androidx.compose.material3:material3:1.1.2" private const val composeNavigationVersion = "2.5.3" const val composeNavigation = "androidx.navigation:navigation-compose:$composeNavigationVersion " private const val coilComposeVersion = "2.1.0" const val coilCompose = "io.coil-kt:coil-compose:$coilComposeVersion " private const val dateTimeVersion = "0.4.0" const val kotlinDateTime = "org.jetbrains.kotlinx:kotlinx-datetime:$dateTimeVersion " private const val hiltVersion = "2.42" private const val hiltCompilerVersion = "1.0.0" const val hiltAndroid = "com.google.dagger:hilt-android:$hiltVersion " const val hiltAndroidCompiler = "com.google.dagger:hilt-android-compiler:$hiltVersion " const val hiltCompiler = "androidx.hilt:hilt-compiler:$hiltCompilerVersion " const val hiltNavigationCompose = "androidx.hilt:hilt-navigation-compose:$hiltCompilerVersion " private const val ktorVersion = "2.1.3" const val ktorCore = "io.ktor:ktor-client-core:$ktorVersion " const val ktorSerialization = "io.ktor:ktor-client-content-negotiation:$ktorVersion " const val ktorSerializationJson = "io.ktor:ktor-serialization-kotlinx-json:$ktorVersion " const val ktorAndroid = "io.ktor:ktor-client-android:$ktorVersion " const val ktorIOS = "io.ktor:ktor-client-ios:$ktorVersion " const val kotlinVersion = "1.9.10" const val kotlinGradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion " private const val gradleVersion = "7.3.0" const val androidBuildTools = "com.android.tools.build:gradle:$gradleVersion " private const val sqlDelightGradleVersion = "1.5.3" const val sqlDelightGradlePlugin = "com.squareup.sqldelight:gradle-plugin:$sqlDelightGradleVersion " const val hiltGradlePlugin = "com.google.dagger:hilt-android-gradle-plugin:$hiltVersion " private const val sqlDelightVersion = "1.5.4" const val sqlDelightRuntime = "com.squareup.sqldelight:runtime:$sqlDelightVersion " const val sqlDelightAndroidDriver = "com.squareup.sqldelight:android-driver:$sqlDelightVersion " const val sqlDelightNativeDriver = "com.squareup.sqldelight:native-driver:$sqlDelightVersion " const val sqlDelightCoroutinesExtensions = "com.squareup.sqldelight:coroutines-extensions:$sqlDelightVersion " private const val assertKVersion = "0.25" const val assertK = "com.willowtreeapps.assertk:assertk:$assertKVersion " private const val turbineVersion = "0.7.0" const val turbine = "app.cash.turbine:turbine:$turbineVersion " private const val jUnitVersion = "4.13.2" const val jUnit = "junit:junit:$jUnitVersion " private const val testRunnerVersion = "1.5.1" const val testRunner = "androidx.test:runner:$testRunnerVersion " const val composeTesting = "androidx.compose.ui:ui-test-junit4:$composeVersion " const val composeTestManifest = "androidx.compose.ui:ui-test-manifest:$composeVersion " const val hiltTesting = "com.google.dagger:hilt-android-testing:$hiltVersion " }
4.3. androidApp
모듈 의존성 변경 이제 androidApp
의 의존성을 아래와 같이 교체할 수 있다.
before
1 2 3 4 5 6 7 8 9 dependencies { implementation(projects.shared) implementation(libs.compose.ui) implementation(libs.compose.ui.tooling.preview) implementation(libs.compose.material3) implementation(libs.androidx.activity.compose) debugImplementation(libs.compose.ui.tooling) }
after
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 dependencies { implementation(projects.shared) implementation(Deps.composeUi) implementation(Deps.composeUiTooling) implementation(Deps.composeUiToolingPreview) implementation(Deps.composeFoundation) implementation(Deps.composeMaterial) implementation(Deps.activityCompose) implementation(Deps.composeIconsExtended) implementation(Deps.composeNavigation) implementation(Deps.coilCompose) implementation(Deps.composeMaterial3) implementation(Deps.hiltAndroid) kapt(Deps.hiltAndroidCompiler) kapt(Deps.hiltCompiler) implementation(Deps.hiltNavigationCompose) implementation(Deps.ktorAndroid) androidTestImplementation(Deps.testRunner) androidTestImplementation(Deps.jUnit) androidTestImplementation(Deps.composeTesting) debugImplementation(Deps.composeTestManifest) kaptAndroidTest(Deps.hiltAndroidCompiler) androidTestImplementation(Deps.hiltTesting) }
이때 kapt
와 kaptAndroidTest
에서 오류가 발생하니, plugins
블록에 kapt
관련 코드를 추가한다.
before
1 2 3 4 5 plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.kotlinAndroid) }
after
1 2 3 4 5 6 7 8 plugins { id("com.android.application" ) kotlin("android" ) kotlin("kapt" ) id("dagger.hilt.android.plugin" ) kotlin("plugin.serialization" ) version Deps.kotlinVersion }
4.4. 프로젝트 의존성 변경 위에서 추가한 id("dagger.hilt.android.plugin")
스크립트 때문에 또 오류가 발생할 것이다.
프로젝트의 build.gradle.kts
에서 아래와 같이 의존성을 추가로 설정하자.
before
1 2 3 4 5 6 7 8 plugins { alias(libs.plugins.androidApplication).apply(false ) alias(libs.plugins.androidLibrary).apply(false ) alias(libs.plugins.kotlinAndroid).apply(false ) alias(libs.plugins.kotlinMultiplatform).apply(false ) alias(libs.plugins.kotlinCocoapods).apply(false ) }
after
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 buildscript { repositories { gradlePluginPortal() google() mavenCentral() } dependencies { classpath(Deps.kotlinGradlePlugin) classpath(Deps.androidBuildTools) classpath(Deps.sqlDelightGradlePlugin) classpath(Deps.hiltGradlePlugin) } } allprojects { repositories { google() mavenCentral() } } tasks.register("clean" , Delete::class ) { delete(rootProject.buildDir) }
4.5. shared
모듈 의존성 변경 다시 공용 모듈인 shared
모듈로 돌아와서 의존성을 변경하자.
before
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.kotlinCocoapods) alias(libs.plugins.androidLibrary) } @OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) kotlin { targetHierarchy.default() androidTarget { compilations.all { kotlinOptions { jvmTarget = "1.8" } } } iosX64() iosArm64() iosSimulatorArm64() cocoapods { summary = "Some description for the Shared Module" homepage = "Link to the Shared Module homepage" version = "1.0" ios.deploymentTarget = "14.1" podfile = project.file("../iosApp/Podfile" ) framework { baseName = "shared" } } sourceSets { val commonMain by getting { dependencies { } } val commonTest by getting { dependencies { implementation(libs.kotlin.test) } } } } android { namespace = "com.namhoonkim.kmm.translator" compileSdk = 34 defaultConfig { minSdk = 24 } }
after
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 plugins { kotlin("multiplatform" ) kotlin("native.cocoapods" ) id("com.android.library" ) kotlin("plugin.serialization" ) version Deps.kotlinVersion id("com.squareup.sqldelight" ) } @OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) kotlin { androidTarget { compilations.all { kotlinOptions { jvmTarget = "1.8" } } } iosX64() iosArm64() iosSimulatorArm64() cocoapods { summary = "Some description for the Shared Module" homepage = "Link to the Shared Module homepage" version = "1.0" ios.deploymentTarget = "14.1" podfile = project.file("../iosApp/Podfile" ) framework { baseName = "shared" } } sourceSets { val commonMain by getting { dependencies { implementation(Deps.ktorCore) implementation(Deps.ktorSerialization) implementation(Deps.ktorSerializationJson) implementation(Deps.sqlDelightRuntime) implementation(Deps.sqlDelightCoroutinesExtensions) implementation(Deps.kotlinDateTime) } } val commonTest by getting { dependencies { implementation(kotlin("test" )) implementation(Deps.assertK) implementation(Deps.turbine) } } val androidMain by getting { dependencies { implementation(Deps.ktorAndroid) implementation(Deps.sqlDelightAndroidDriver) } } val androidUnitTest by getting val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this ) iosArm64Main.dependsOn(this ) iosSimulatorArm64Main.dependsOn(this ) dependencies { implementation(Deps.ktorIOS) implementation(Deps.sqlDelightNativeDriver) } } val iosX64Test by getting val iosArm64Test by getting val iosSimulatorArm64Test by getting val iosTest by creating { dependsOn(commonTest) iosX64Test.dependsOn(this ) iosArm64Test.dependsOn(this ) iosSimulatorArm64Test.dependsOn(this ) } } } android { namespace = "com.namhoonkim.kmm.translator" compileSdk = 34 defaultConfig { minSdk = 24 } }
이제 오류 없이 정상적으로 빌드가 되었음을 확인할 수 있다.
References