BuildConfig란?
Gradle은 빌드 시 BuildConfig 클래스를 생성하고, 현재 빌드에 관한 정보를 참조할 수 있다.
buildConfigField() 메서드를 Gradle 스크립트에 선언하는 것으로 BuildConfig 클래스에 커스텀 필드를 추가할 수 있으며 앱 코드에서의 해당 값에 액세스할 수 있다. 마찬가지로, resValue()로 앱 리소스 값을 추가할 수 있다.
android {
...
buildFeatures { buildConfig true }
buildTypes {
release {
// release 빌드에서만 참조되는 값들을 정의한다
buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
resValue("string", "build_time", "${minutesSinceEpoch}")
}
debug {
// 증분빌드를 위해 정적인 값들로 정의한다.
buildConfigField("String", "BUILD_TIME", "\"0\"")
resValue("string", "build_time", "0")
}
}
}
...
앱 코드에서 다음과 같이 BuildConfig 값에 접근할 수 있다.
Log.i(TAG, BuildConfig.BUILD_TIME)
Log.i(TAG, getString(R.string.build_time))
멀티모듈 프로젝트에서 중복 생성되는 BuildConfig
다음과 같이 app 모듈에서 BuildConfig를 생성하면, 앱모듈에서는 BASE_URL과 같은 값을 참조 할 수 있지만, 하위 모듈에서는 이를 참조할 수 없다.
// :app 모듈의 build.gradle
android {
namespace 'com.charlezz.app'
buildFeatures { buildConfig true }
buildTypes {
stage {
buildConfigField "String", "BASE_URL", "String.valueOf(\"https://stage.charlezz.com\")"
}
dev {
buildConfigField "String", "BASE_URL", "String.valueOf(\"https://dev.charlezz.com\")"
}
}
}
이런 경우 하위모듈에서 BASE_URL을 참조하기 위해 buildConfigField(..) 새로 정의한다면, 중복된 값을 갖는다.
중복된 선언을 피하기 위해 BuildConfig를 별도의 모듈을 생성하, build.gradle을 다음과 같이 설정한다.
// :build_config 모듈의 build.gradle
android {
namespace "com.charlezz.build_config"
buildFeatures { buildConfig true }
buildTypes {
stage {
buildConfigField "String", "BASE_URL", "String.valueOf(\"https://stage.charlezz.com\")"
}
dev {
buildConfigField "String", "BASE_URL", "String.valueOf(\"https://dev.charlezz.com\")"
}
}
...
}
이제 다음과 같이 :app모듈 및 기타 하위 모듈에서 build_config 모듈을 참조하면 된다.
// :app 모듈 및 기타 모듈에서 build_config 참조
dependencies {
implementation project(":build_config")
}
지금까지 커스텀 필드를 한 곳에 선언하고, 여러 모듈에서 참조하는 방법에 대해 알아보았다.
BuildConfig Stub 모듈의 필요성
여기까지 진행했다면, 중복되는 BuildConfig 생성을 막고 한곳에서 커스텀 필드를 관리할 수 있었을 것이다.
하지만 한가지 문제점이 있다. 바로 :app 모듈 이외의 모듈에 buildType 및 productFlavors가 전파된다는 점이다.
// :feature 모듈의 build.gradle
android {
namespace 'com.charlezz.feature'
buildTypes {
stage {}
dev {}
}
...
}
이를 해결하기 위해서 stub 모듈을 생성한다.
// :build_config_stub 모듈의 build.gradle
android {
// 주의! namespace는 build_config와 동일하게
namespace "com.charlezz.build_config"
buildFeatures { buildConfig true }
defaultConfig {
buildConfigField "String", "BASE_URL", "String.valueOf(\"https://charlezz.com\")"
}
...
}
stub 모듈 생성 후, app모듈과 기타 하위 모듈에서 build.gradle의 의존성을 다음과 같이 설정한다.
// :app module
dependencies {
implementation project(":build_config")
}
// 하위 모듈
dependencies {
compileOnly project(":build_config_stub")
}
여기서 중요한 점은 app 모듈을 제외한 나머지 모듈은 compileOnly 키워드를 써야 한다.
여기까지 진행했다면 :app 모듈 빌드시에 :feature 모듈에 대한 의존이 build_config로 대체된다.
1개의 댓글
세리나 · 2024년 8월 29일 6:52 오후
잘읽었습니다 감사합니다!