본문 바로가기

Android

[Android] Build Variant는 왜 필요할까: 안드로이드 빌드 관리하기

 

 

사이드 프로젝트를 진행할 땐 빌드를 debug와 release모드 두개면 충분했습니다.

그런데 실무에서 프로젝트를 진행하다보니 debug, release 외에도 다양한 빌드 환경이 필요함을 느끼게 되었습니다.

 

매번 패키지명, 설정 등을 바꾸면서 빌드하기엔 시간도 오래 걸리고 너무 귀찮은 작업이니 이걸 빌드 관리로 손쉽게 하면 좋겠죠?

먼저 가볍게 빌드 관리와 관련된 개념들을 정리해 보려고 합니다.

 

 

 

🛠️ Build Variants

안드로이드 스튜디오의 Build Variants

 

안드로이드 스튜디오의 다양한 기능들 중 Build Variants 라는 것을 발견할 수가 있는데요,

Android 프로젝트에서 여러 빌드 구성을 조합해 만들어지는 개념으로, 정확히는 안드로이드 Gradle이 만들어내는 실제 빌드 결과물의 단위 입니다.

 

보통 우리가 인식하는 debug, release와 같은 이름은 Variant의 일부입니다. (Variant 그 자체는 아닙니다.)

 

 

Build Variant는 Gradle이 아래 요소들을 조합해서 자동으로 생성해줍니다.

BuildVariant= BuildType × ProductFlavor × (Flavor Dimension)

 

여기에 내부적으로는 ABI, Density, Language 같은 split 요소까지 영향을 줍니다.

이 split 요소들은 보통 개발 과정에서는 잘 드러나지 않지만, 실제 배포 환경에서는 Variant 수보다 더 많은 경우의 수를 만들어냅니다.

 

즉, Variant는 개발자가 직접 만드는 개념이 아니라 빌드 구조가 만들어낸 “옵션의 조합 결과” 라고 할 수 있습니다.

 

그럼 이 Build Variant는 왜 중요할까요??

 

 

 

🪄 왜 Build Variant가 중요할까?

1. Variant마다 “완전히 다른 설정”을 가진다

Variant는 단순한 이름 조합이 아닙니다.

각 Variant는 서로 다른 BuildConfig, resValue, signingConfig, Proguard/R8 설정, native 라이브러리 조합을 가질 수 있습니다.

 

즉, Variant 하나가 곧 하나의 제품이 됩니다.

 

BuildType과 ProductFlavor, 그리고 Flavor Dimension이 늘어날수록 생성되는 Variant 수도 기하급수적으로 증가하게 됩니다.

이 현상을 보통 Variant Explosion이라고 부르며 실무에서는 빌드 시간 증가, 실수로 잘못된 빌드 배포, CI 비용 증가 같은 문제로 이어질 수 있습니다.

 

 

2.Build Variant ≠ APK / AAB

Build Vatiant는 APK/AAB 파일과 다릅니다.

  • Variant : Gradle 논리 단위 (설정 묶음)
  • APK / AAB : Variant를 빌드한 결과물

하나의 Variant라도 여러 ABI APK로 나뉠 수 있고, AAB 하나로 묶일 수 있습니다.

 

그럼 Build Variant가 결정되는 각각의 내용을 더 자세하게 알아봐야겠죠?

 

 

 

🔎 Build Type

Build Type은 기본적으로 앱이 어떤 방식으로 실행·빌드·패키징되는지를 정의합니다.

즉, 실행 방식, 디버깅 가능 여부, 최적화/보안 수준 등을 결정하는 요소입니다.

 

대표적으로 우리가 흔히 아는 debug, release 모드 등이 있습니다.

위와 같은 설정으로 Build Type은 “이 앱을 디버깅용으로 쓸 것인가, 사용자에게 배포할 것인가”를 결정하게 됩니다.

 

BuildType은 기능 차이가 아니라 빌드, 실행 전략의 차이를 만들어냅니다!

 

 

 

🔎 Product Flavor

Product Flavor는 "이 앱은 어떤 앱인가"를 정의합니다.

조금 더 풀어쓰면 동일한 코드 베이스에서 비즈니스적으로 다른 앱 버전을 만들기 위한 개념입니다.

 

대표적인 예로는 무료 / 유료 버전, 개발 서버 / 운영 서버, 스토어용 / 내부 배포용 등이 있습니다.

Product Flavor는 서버 endPoint, 기능 on/off, 리소스 차이, applicationId suffix, 앱 이름 등을 결정합니다.

 

이런 설정들을 통해 Product Flavor는 사용자에게 보이는 차이를 만들어냅니다.

 

 

 

🔎 Flavor Dimension

Flavor Dimension은 "Flavor를 나누는 기준 축"이 됩니다.

 

Product Flavor가 하나일 때는 문제가 없습니다.

그렇지만 서로 다른 기준의 Flavor가 생기면 Gradle은 어떤 조합을 만들어야 할지 모릅니다.

 

예를 들어 아래와 같은 Flavor가 있을 때

  • dev, prod
  • free, paid

 

`dev + free?` `prod + paid?` `dev + paid?` 모든 조합이 가능하지만 Gradle 입장에선 어떤 조합으로 만들어야할지 기준이 없습니다.

 

 

이때 Flavor Dimension은 ProductFlavor를 서로 다른 분류 축으로 나눠줍니다.

예를 들어 

  • dimension : enviroment
    • dev
    • prod
  • dimension : pricing
    • free
    • paid

이렇게 분류를 해둘 경우, Gradle은 이제 enviroment 중 하나를 선택하고, pricing 중에 하나를 선택한다는 기준을 가질 수 있게 됩니다.

그 결과, 아래와 같은 조합을 만들어낼 수 있습니다.

  • devFree
  • devPaid
  • prodFree
  • prodPaid

 

여기서 중요한 점은 Flavor Dimension은 조합 규칙을 정의하는 역할이지, 앱을 직접 구분하지는 않는다는 것입니다!

결국 Flavor Dimension은 "이 Flavor들은 같은 기준이 아니다" 라고 Gradle에게 알려주는 장치라고 볼 수 있습니다.

 

 

🤓 세 요소의 역할을 비교해보면 이렇게 정리할 수 있겠죠?

BuildType 어떻게 실행되는가
ProductFlavor 어떤 앱인가
Flavor Dimension 어떤 기준으로 나뉘는가

 

 

각 요소를 통해 본 Build Variant는 하나의 설정이 아니라, 실행 방식(BuildType)과 비즈니스 맥락(ProductFlavor), 조합 규칙(Flavor Dimension)이 함께 만들어낸 결과물이라고 볼 수 있습니다.

 

 

 

📚 참고

https://developer.android.com/build/build-variants?hl=ko

 

빌드 변형 구성  |  Android Studio  |  Android Developers

빌드 변형을 구성하여 단일 프로젝트에서 여러 버전의 앱을 만드는 방법을 알아보세요.

developer.android.com