이동식 저장소

[Android] Build variant 기초 본문

Primary/Android

[Android] Build variant 기초

해스끼 2022. 7. 17. 22:16

Build variant란 무엇인가?

Build variant는 빌드될 수 있는 앱의 부분을 말한다. 보통은 코드 전체를 빌드하지만, 필요에 따라 일부 코드를 포함하거나 제거하여 빌드할 수 있다. 예를 들어 디버깅용 코드를 실제 배포판에서 제외하는 경우가 있다. 또는 기능 몇 개를 제외하여 무료 버전을 빌드하고, 모든 기능을 포함하는 유료 버전을 빌드할 수도 있다. 모두 같은 코드를 범위만 달리하여 빌드한 예시이다.

 

Build variant는 build type과 product flavor의 조합(cross product)으로 이루어진다.

Build type?

Build type은 앱을 빌드하고 서명하는 방법을 정의한다. 예를 들어 build type을 debug로 설정하면 디버깅 모드가 활성화되며, release로 설정하면 앱의 코드가 난독화되고 빌드 결과물이 release 전용 key로 서명될 수 있다.

 

앱을 어떻게 빌드할 것인지 결정하는 요소이다.

Product flavor?

Product flavor는 빌드에 포함될 코드와 리소스를 정의한다. 기본적으로 모든 코드와 리소스가 빌드에 포함되며, product flavor를 직접 정의하면 코드 또는 리소스의 일부만을 포함할 수 있다. 앱의 package name 등을 변경할 수도 있다.

 

무엇을 빌드할 것인지 결정하는 요소이다. 그러니까 Build variant는 무엇을 + 어떻게 빌드할지 결정한다고 보면 된다. 

Build type

Module-level ``build.gradle`` 파일에 보면 build type이 정의되어 있다.

android {
    ... 
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        debug {
            testCoverageEnabled true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'proguard-rules-debug.pro'
        }
        benchmark {
            initWith buildTypes.release
            signingConfig signingConfigs.debug
            matchingFallbacks = ['release']
            debuggable false
        }
    }
    ...
}

Android Studio에서 앱을 만들면 기본적으로 debug와 release build type이 정의된다. 위 사진에서는 release, debug, benchmark 3개의 build variant가 정의되어 있는데, benchmark는 앱의 성능 측정을 위해 만들어진 build type이다. 내가 만든 건 아니고 Jetpack Macrobenchmark 라이브러리가 만들었다.

 

Build type을 새로 하나 정의해 보자. 이름은 ``staging``이다.

android {
    ... 
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        debug {
            testCoverageEnabled true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'proguard-rules-debug.pro'
        }
        benchmark {
            initWith buildTypes.release
            signingConfig signingConfigs.debug
            matchingFallbacks = ['release']
            debuggable false
        }
        // New!
        staging {
            initWith debug
            manifestPlaceholders = [hostName:"internal.example.com"]
            applicationIdSuffix '.debugStaging'
        }
    }
    ...
}

``initWith`` 속성을 사용하면 다른 build type의 설정을 복사하여 사용할 수 있다. 다른 build type의 설정을 일부만 변경하여 사용할 때 유용하다. Build type을 설정하는 자세한 방법은 다음 문서를 참고하자.

Product flavors

Product flavor도 같은 방법으로 정의할 수 있다. 사실 ``build.gradle`` 맨 위에 있는 ``defaultConfig``도 product flavor이다. ``defaultConfig``에서 기본으로 사용될 product flavor 값이 정의되고, 정의된 기본값을 다른 flavor에서 덮어쓸 수 있다.

 

직접 정의한 모든 product flavor는 flavor dimension에 속해야 한다. Flavor dimension은 flavor의 그룹이다. 하나라도 속하지 않으면 빌드 에러가 발생한다.

Error:All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.

어떤 심오한 이유 때문에 그렇다고 한다. 아직은 너무 어려워서 패스..

 

Product flavor와 flavor dimension을 정의하는 예시를 보자.

android {
    ...
    defaultConfig {...}
    buildTypes {
        debug{...}
        release{...}
    }
    // Specifies one flavor dimension.
    flavorDimensions "version"
    productFlavors {
        demo {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension "version"
            applicationIdSuffix ".demo"
            versionNameSuffix "-demo"
        }
        full {
            dimension "version"
            applicationIdSuffix ".full"
            versionNameSuffix "-full"
        }
    }
}

Flavor에서 ``applicationIdSuffix``와 ``versionNameSuffix``를 정의하였다. 각각 앱의 ID와 버전 이름의 뒤에 지정된 문자열을 붙인다. 이렇게 하면 ``demo``와 ``full``로 빌드된 앱의 ID를 다르게 할 수 있다. 앱의 ID가 다르다는 말은 두 앱이 하나의 기기에 동시에 설치될 수 있다는 말과 같다. 참고로 build type에도 해당 속성을 모두 정의할 수 있다.

 

Gradle sync를 완료하면 build type과 product flavor를 결합한 bulid variant가 자동으로 정의된다. Variant의 이름은 ``<product-flavor><build-type>`` 포맷으로 정해진다. 

 

위의 예시에서는 ``debug``와 ``release`` 2개의 build type과 ``demo``, ``full`` 2개의 flavor가 존재하므로 다음과 같이 4개의 build variant가 정의된다. 참고: flavor dimension이 존재하는 경우

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

Cross product 맞구만! 이제 Android Studio 좌측 하단의 ``Build Variants`` 메뉴에서 원하는 variant를 적용할 수 있다.

flavor가 없으면 이렇게 정의된다.

정리

  • Build variant는 build type과 product flavor의 결합이다. 원문으로는 cross product of build type and product flavor이다.
    • Build type은 앱을 어떻게 빌드할지 결정한다.
    • Product flavor는 무엇을 빌드할지 결정한다.
  • 즉, build variant는 무엇을 어떻게 빌드할지 결정한다.
Comments