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로 대체된다.

카테고리: 미분류

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.