build-logic 도 이전 포스팅에 있었던 모듈의 하나다.
다만 이 모듈에는 Version Catalog, Convention Plugin 이라는 개념을 추가해서 설명할것이다.
Version Catalog
는 이름에서 느껴지는것처럼 버전을 관리해준다. 즉 프로젝트 전반에 있는 라이브러리 의존성을 관리하는 방식이다.
libs.versions.tomi 라는 파일이 있을텐데 요놈이 그 역할을 한다.
알아본김에 좀 더 알아보자.
이 파일을 열어보면 크게 네 파트로 나뉘는데
[versions]
[libraries]
[plugins]
[bundles]
가 있다.
versions : 라이브러리의 버전을 정의한다. ex) glide = 5.0.0
libaries : 해당 라이브러리 정보를 적는다. ( group : name : version 형태에 대한 정보)
plugins : 플러그인 id와 버전 정보를 작성한다.
bundles : 함께 묶을 라이브러리들을 정의한다. ex ) [“retrofit”, “okhttp-interceptor”]
[versions]
라이브러리의 버전입니다. 심플하게 아래와 같이 정의할 수 있다.
[versions]
ktx = "1.9.0"
[libraries]
라이브러리에 대한 세부 정보를 정의한다. group : name : version 과 같은 네이밍 컨벤션을 따르며, 영역에 해당하는 라이브러리 정보를 기입해주면된다
[versions]
ktx = "1.9.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "ktx" }
이렇게 정의되었을 때, build.gradle 에서는 아래처럼 접근이 가능한다.
dependencies {
implementation(libs.androidx.core.ktx)
...
}
[plugins]
gradle plugin 버전을 정의
[versions]
androidGradlePlugin = "7.4.1"
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
build.gradle에는 다음과 같이 적용할 수 있다
// Top-level build.gradle.kts
plugins {
alias(libs.plugins.android.application) apply false
}
// module build.gradle.kts
plugins {
alias(libs.plugins.android.application)
}
[bundles]
해당 섹션을 통해 앞서 [libraries] 섹션에 정의한 종속성들을 하나로 묶어서 관리할 수도 있다. 같이 쓰이는 라이브러리들을
이렇게 묶어서 사용하면 편할 것이다,
[versions]
ktx = "1.9.0"
lifecycle = "2.7.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "ktx" }
androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime", version.ref = "lifecycle"}
[bundles]
androidx = ["androidx-core-ktx", "androidx-lifecycle-runtime"]
해당 bundle 라이브러리는 bundles라는 Accessor를 통해 접근가능하다.
dependencies {
implementation(libs.bundles.androidx)
}
이렇게 의존성 관리를 편하게 만들어준다.
또 여기서 관리하면 멀티모듈로 프로젝트를 구성하더라도 이 카탈로그에 적힌대로 가져와서 import 할 수 있다.
앞에 이야기가 길었지만 사실 이번글에서 핵심은
Convention Plugin 을 설명하는것이다.
먼저 추가하기전 build-logic 이라는 모듈을 Java or Kotlin Library로 만들어주자.
그리고 build-logic의 build.gradle 을 아래처럼 만들어주자.
plugins {
`kotlin-dsl`
`kotlin-dsl-precompiled-script-plugins`
}
dependencies {
implementation(libs.android.gradlePlugin)
implementation(libs.kotlin.gradlePlugin)
implementation(libs.verify.detektPlugin)
compileOnly(libs.compose.compiler.gradle.plugin)
}
gradlePlugin {
plugins {
register("androidHilt") {
id = "com.hyoseok.hilt"
implementationClass = "com.hyoseok.samplecleanarchitecture.HiltAndroidPlugin"
}
register("kotlinHilt") {
id = "example.kotlin.hilt"
implementationClass = "com.hyoseok.samplecleanarchitecture.HiltKotlinPlugin"
}
}
}
또 잊지말아야할건 root 수준의 setting.gradle 에서
pluginManagement {
includeBuild("build-logic") // 이 부분 추가
그리고 아래에 자동으로 추가 됐을 build-logic 은 지워준다. 중복해서 적어두면 에러가 발생하는걸 볼 수 있다.
include(":build-logic") // 삭제
그리고 hilt 를 플러그인으로 만들어주는 상황이라고 한다면
build-logic 모듈에 HiltAndroid.kt 를 만들어보자.
gradle 파일에 직접 설정해주는것과 비슷하게 보이지만 코틀린 코드로 작성이 된걸 볼 수 있다.
HiltAndroid.kt
internal fun Project.configureHiltAndroid() {
with(pluginManager) {
apply("dagger.hilt.android.plugin")
apply("org.jetbrains.kotlin.kapt")
}
val libs = extensions.libs
dependencies {
"implementation"(libs.findLibrary("hilt.android").get())
"kapt"(libs.findLibrary("hilt.android.compiler").get())
"kaptAndroidTest"(libs.findLibrary("hilt.android.compiler").get())
}
}
internal class HiltAndroidPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
configureHiltAndroid()
}
}
}
자 이렇게 코드를 만들어준다고 hilt가 적용이 될까? 아니다.
실제로 사용되는곳에 적용될 수 있도록 해줘야하는데 몇가지 작업이 필요하다.
위에 build-logic의 build.gradle를 적용하는 쪽 코드에보면
`kotlin-dsl-precompiled-script-plugins` 라는게 있는데 이걸 알고 넘어가야한다.
kotlin-dsl에 포함된 플러그인인데 이걸 사용하면 원하는대로
configureHiltAndroid 나 다른 확장함수들을 조합해서 하나의 플러그인으로 미리 만들어둘 수 있다.
위 사진에 있는 위치에 ~~.gradle.kts 파일을 생성하자 이름은 원하는대로 만들면된다.
그 아래에 보이는 gradle 이 아닌 파일들은 빌드하고 나면 precomplied 되어 자동으로 생성된다.
hyoseok.android.application.gradle.kts 파일의 내부를 예시로 봐보자.
plugins {
id("com.android.application")
}
configureKotlinAndroid()
configureHiltAndroid()
configureKotestAndroid()
configureCoilAndroid()
dependencies {
}
여길 보면 위에서 우리가 만들어줬던 configureHiltAndroid 가 보인다.
다른 것들도 다 동일한 방식으로 만들어주면 여기에 한번에 포함시킬 수 있게된다.
그럼 이제 실제로 적용을 하는 마지막 부분이다.
app 모듈의 build.gradle에서 (예를 들어서 app 모듈인것이지 실제로 사용할때는 필요한 곳에 맞게 조합해서 쓰면 된다.)
plugins {
id("hyoseok.android.application") // 이런식으로 추가해주면 적용이 완료된다.
id("hyoseok.android.compose")
id("com.google.android.gms.oss-licenses-plugin")
}
이런 방식으로 gradle 을 관리하면 멀티모듈을 사용할때 중복되는 gradle 코드가 많이 줄어든다.
그리고 여러 모듈에 공통적으로 바뀌어야할 상황이 있다면 작성해준 플러그인만 변경하면 된다.
추가로 아래 부분을 위에서 봤을텐데 이건 왜 적어준거냐고 물으신다면
gradlePlugin {
plugins {
register("androidHilt") {
id = "com.hyoseok.hilt"
implementationClass = "com.hyoseok.samplecleanarchitecture.HiltAndroidPlugin"
}
register("kotlinHilt") {
id = "example.kotlin.hilt"
implementationClass = "com.hyoseok.samplecleanarchitecture.HiltKotlinPlugin"
}
}
}
다른 모듈에서 아래처럼 id를 적어주어 적용해줄수도 있다!
plugins {
id("com.hyoseok.hilt")
id("kotlinx-serialization")
}
다음은 어떻게 모듈을 구성할지 알아보자.
'Android' 카테고리의 다른 글
사실 내 로망중엔 OpenGL 도 있었어 (1) | 2024.08.31 |
---|---|
라이브러리를 배포해보자. (0) | 2024.08.24 |
코루틴의 Dispatcher 를 Hilt Singleton으로 주입해보자 (0) | 2024.08.17 |
[다시 만들어보는 클린아키텍쳐] 모듈구성 편 (0) | 2024.08.12 |
[다시 만들어보는 클린아키텍쳐] 모듈분리 편 (1) | 2024.07.25 |
hilt에서 같은 타입의 객체에 대한 디펜던시를 주입할때 (0) | 2024.07.09 |
안드로이드 키보드 높이 구하기 (2) | 2024.04.29 |
안드로이드에서 FFMPEG로 m3u8 to mp4 하기 (1) | 2023.12.02 |