Build Type — Gradle에서 debug 및 release 설정이란

저자: IT Sectr 게시일: 2026-05-30 읽는 시간: 9 분

Android 개발에서 Build Type은 애플리케이션을 빌드하는 방법(디버깅 유무, 코드 최적화 유무, 사용할 서명 인증서)을 결정하는 Gradle 설정입니다. Android Gradle Plugin은 debug와 release라는 두 가지 표준 Build Type을 제공하며, 개발자는 staging이나 benchmark와 같은 사용자 정의 유형을 추가할 수 있습니다. Google Android Developers, 2025에 따르면, 올바른 Build Type 설정은 minification과 resource shrinking을 통해 APK 크기를 최대 60%까지 줄입니다. 각 Build Type은 Product Flavors와 결합되어 Build Variant를 형성합니다.

주요 내용

  • Build Type — debuggable, minification, signing 매개변수가 있는 빌드 설정입니다.
  • Debug — debuggable=true, minification=false, debug.keystore를 사용한 디버그 빌드입니다.
  • Release — debuggable=false, minification=true, 프로덕션 서명을 사용한 최종 빌드입니다.
  • ProGuard와 R8은 release 빌드에서 난독화, 최적화 및 코드 압축을 수행합니다.
  • BuildConfigField를 사용하면 각 유형별로 코드에서 액세스 가능한 변수를 설정할 수 있습니다.

Build Type이란?

Build Type은 Android 프로젝트의 Gradle 설정 요소로, 애플리케이션의 컴파일 및 패키징 매개변수를 설명합니다. 각 Build Type은 debuggable(디버깅 활성화), minificationEnabled(코드 압축 활성화), shrinkResources(리소스 압축 활성화), proguardFiles(ProGuard 규칙 파일), signingConfig(서명 인증서) 등 명명된 옵션 집합입니다. Build Types는 app 모듈의 build.gradle 파일에 있는 android.buildTypes 블록에서 선언됩니다.

Build Type의 주요 목적은 개발 워크플로우(빠른 빌드, 상세 로그, 디버깅)와 프로덕션 릴리스(최적화된 코드, 최소 크기, 보안)를 분리하는 것입니다. 디버그 빌드는 몇 초 안에 컴파일되어 개발자에게 최대한의 정보를 제공해야 합니다. 릴리스 빌드는 사용자에게 가능한 한 빠르고 컴팩트해야 합니다. Build Type은 인프라 설정이며 애플리케이션의 기능과 관련이 없습니다.

Android Gradle Plugin은 각 Build Type에 대해 자동으로 source setsrc/<buildType>/ 디렉토리(예: src/debug/, src/release/)를 생성합니다. 이 source set에 배치된 리소스, 코드 및 매니페스트 파일은 해당 빌드 유형에만 적용됩니다. 예를 들어, src/debug/에는 ADB 설치 권한이 있는 AndroidManifest.xml을 배치하고 src/release/에는 권한 없이 배치할 수 있습니다. Build Type source set은 Product Flavor source set보다 우선순위가 높습니다.

Build Type과 Product Flavor의 차이

주요 차이점: Build Type은 "어떻게 빌드할까?"라는 질문에 답하고, Product Flavor는 "무엇을 빌드할까?"에 답합니다. Build Type은 debug, release, staging이 될 수 있습니다. Product Flavor는 free, paid, enterprise가 될 수 있습니다. Build Type은 애플리케이션의 기능을 변경하지 않지만(화면을 추가하거나 제거하지 않음), Product Flavor는 변경합니다. Build Type은 디버거를 비활성화하고 난독화를 활성화할 수 있으며, Product Flavor는 applicationId와 리소스를 변경할 수 있습니다. 둘은 함께 작동합니다: 각 Build Type은 각 Product Flavor와 결합되어 Build Variant를 형성합니다.

표준 Build Types: debug와 release

Debug는 AGP가 기본적으로 생성하는 Build Type입니다. debuggable=true이므로 디버거 연결, Log.d 로그 보기, Android Studio 프로파일러 사용이 가능합니다. Minification이 비활성화되어 있으므로 빌드가 빠릅니다. 디버그 빌드에서 applicationId는 ".debug" 접미사를 받으며(재정의되지 않은 경우), 동일한 기기에 디버그 버전과 릴리스 버전을 함께 설치할 수 있습니다. 디버그 빌드는 Android SDK가 자동으로 생성하는 debug.keystore의 인증서로 서명됩니다.

Release는 애플리케이션 게시용 Build Type입니다. debuggable=false, minificationEnabled=true(기본값), shrinkResources=true입니다. 개발자는 프로덕션 인증서로 signingConfig를 지정해야 하며, 그렇지 않으면 빌드가 릴리스로 간주되지 않습니다. 릴리스 빌드는 난독화, 최적화 및 코드 압축을 위해 ProGuard 또는 R8을 사용합니다. Android Studio는 릴리스 빌드에 디버거를 연결할 수 없습니다(debuggable=false인 경우). 적절한 ProGuard 규칙이 설정된 경우 minification 중에 모든 Log.d 및 Log.v 호출이 코드에서 제거됩니다.

중요: 디버그 빌드는 릴리스 동작을 테스트하지 않습니다. Minification은 코드 동작을 변경할 수 있습니다 — 리플렉션, 직렬화, Gson/SQLite 및 기타 라이브러리는 종종 ProGuard 규칙이 필요합니다. 따라서 게시 전에 항상 릴리스 빌드를 만들고 테스트하세요. Google Play Console과 Firebase Test Lab을 사용하면 게시 전에 실제 기기에서 자동화된 테스트를 위해 릴리스 빌드를 업로드할 수 있습니다.

groovy
android {
    buildTypes {
        debug {
            debuggable true
            minification false
            signingConfig signingConfigs.debug
            versionNameSuffix "-debug"
        }

        release {
            debuggable false
            minification true
            shrinkResources true
            proguardFiles "proguard-rules.pro"
            signingConfig signingConfigs.release
            ndk { abiFilters "arm64-v8a", "x86_64" }
        }
    }
}

사용자 정의 Build Types 만들기

initWith를 통한 상속

debug와 release 외에도 사용자 정의 Build Types를 만들 수 있습니다 — 예를 들어 staging(중간 환경) 또는 benchmark(성능 테스트용)입니다. 사용자 정의 Build Type은 debug 및 release와 동일하게 buildTypes 블록에서 선언됩니다. 이름은 무엇이든 가능하지만, 영어로 의미론적으로 명확한 이름을 사용하는 것이 좋습니다. staging의 경우 일반적으로 debuggable=true(staging 환경에서 문제 진단용)와 minification=true(프로덕션 전 난독화 테스트용)로 설정됩니다.

사용자 정의 Build Type은 자동으로 해당 source set(src/staging/)을 받고 assembleStaging과 같은 태스크를 생성합니다. AGP는 사용자 정의 유형 수에 제한을 두지 않지만, 각 새 유형은 Build Variants 수를 곱합니다. 실용적인 한계는 4-5개의 Build Types입니다: debug, staging, benchmark, release, 그리고 필요에 따라 debugMinified(ProGuard 규칙 테스트를 위해 minification이 활성화된 debug)입니다.

사용자 정의 Build Type의 경우 initWith를 사용하여 debug에서 debuggable을 상속할 수 있습니다. initWith 키워드는 지정된 Build Type의 모든 매개변수를 복사한 후 재정의할 수 있습니다. 이는 debug를 기반으로 staging을 만드는 데 편리합니다: initWith debug + 추가로 minification 활성화. initWith가 없으면 기본 유형의 모든 매개변수를 수동으로 나열해야 합니다.

groovy
android {
    buildTypes {
        staging {
            initWith debug
            minification true
            shrinkResources true
            proguardFiles "staging-proguard-rules.pro"
            versionNameSuffix "-staging"
        }

        benchmark {
            initWith release
            signingConfig signingConfigs.debug
            matchingFallbacks = ["release"]
        }
    }
}

// matchingFallbacks — benchmark 유형이 없는 라이브러리용
// 라이브러리에 release만 있는 경우 — AGP가 이를 사용합니다

다양한 빌드 유형의 서명 설정

SigningConfig는 APK 또는 AAB 서명에 사용할 인증서를 결정합니다. Android는 설치 가능한 모든 애플리케이션에 서명을 요구하며, 서명이 없으면 시스템이 설치를 허용하지 않습니다. 디버그 빌드의 경우 AGP는 debug.keystore를 사용합니다 — Android SDK Tools가 생성한 알려진 비밀번호가 있는 사전 설치된 인증서입니다. 릴리스 빌드의 경우 Android Studio(Build → Generate Signed Bundle/APK) 또는 keytool 명령줄을 통해 자체 인증서를 만들어야 합니다.

서명 키 저장은 중요한 보안 문제입니다. 릴리스 키는 소스 코드 저장소에 저장하지 않는 것이 좋습니다. 대신 keystore.properties 파일(.gitignore에 추가), CI/CD 환경 변수, 또는 Android Studio의 암호화된 저장소를 사용합니다. CI/CD(GitHub Actions, GitLab CI)에서 서명 키는 secrets에 저장되고 시스템 속성을 통해 build.gradle에 전달됩니다. 예: storePassword = System.getenv("KEYSTORE_PASSWORD").

각 Build Type은 자체 signingConfig를 참조할 수 있습니다. release의 경우 프로덕션 인증서, debug의 경우 debug.keystore, staging의 경우 별도의 staging 인증서입니다. 서명 설정은 애플리케이션 설치 가능성에 직접적인 영향을 미칩니다: debug를 debug.keystore로 서명하고 staging을 프로덕션 키로 서명하면 서명 불일치로 인해 staging을 debug 버전 위에 설치할 수 없습니다. applicationId도 달라야 합니다 — 이를 위해 applicationIdSuffix를 사용합니다.

groovy
android {
    signingConfigs {
        debug {
            storeFile file("debug.keystore")
            storePassword "android"
            keyAlias "androiddebugkey"
            keyPassword "android"
        }
        release {
            storeFile file("release-key.jks")
            storePassword System.getenv("KEYSTORE_PASS")
            keyAlias "my-key"
            keyPassword System.getenv("KEY_PASS")
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

Minification, ProGuard 및 R8

Resource Shrinking

Minification은 사용되지 않는 코드를 제거하고 클래스, 메서드 및 필드의 이름을 짧은 이름으로 변경하는 프로세스입니다. AGP는 ProGuard(레거시) 또는 R8(권장, AGP 버전 3.4부터 내장)을 사용하여 minification을 수행합니다. R8은 네 가지 작업을 수행합니다: shrinking(사용되지 않는 클래스 제거), optimisation(코드 단순화), obfuscation(이름 변경), preverify(호환성 정보 추가). 결과는 더 작고 디컴파일하기 어려운 APK입니다.

Minification 규칙은 ProGuard 규칙 파일에 정의됩니다 — -keep, -dontwarn, -keepclassmembers 등의 구문이 있는 텍스트 파일입니다. 규칙이 없으면 R8은 리플렉션(Gson, Retrofit, Room, Kotlin 직렬화)을 통해 사용되는 클래스를 제거하거나 이름을 변경합니다. Android Studio 프로젝트 템플릿은 특정 라이브러리에 대한 규칙이 추가되는 proguard-rules.pro 파일을 만듭니다. 라이브러리에는 내장 규칙도 포함될 수 있으며 jar/aar에서 자동으로 포함됩니다.

Shrink resources(shrinkResources=true)는 APK에서 사용되지 않는 리소스를 제거합니다. R8은 먼저 코드에서 사용되지 않는 리소스를 확인하고(R.java 및 매니페스트 참조 확인) 최종 빌드에서 제거합니다. getIdentifier() 또는 타사 라이브러리를 통해 사용되는 리소스의 경우 리소스에 tools:keep="@layout/my_layout"을 추가해야 합니다. Minification과 결합하면 resource shrinking으로 APK 크기를 40-60% 줄일 수 있습니다.

text
# proguard-rules.pro — 필수 규칙
# Gson: 직렬화용 클래스 유지
-keepclassmembers class com.example.** {
    <fields>;
}

# Retrofit: API 인터페이스 유지
-keep,allowobfuscation interface com.example.api.*

# Room: DAO 및 Entity 유지
-keep class * extends androidx.room.RoomDatabase
-keep @interface androidx.room.** { *; }

# Kotlin Coroutines: Continuation 제거 방지
-keepnames class kotlinx.coroutines.internal.*

# OkHttp: service loader 보존
-keep class okhttp3.** { *; }

BuildConfigField 및 Build Type 리소스

BuildConfig는 defaultConfig, productFlavors 및 buildTypes에 정의된 상수를 포함하는 자동 생성된 Java/Kotlin 클래스입니다. buildConfigField를 통해 사용자 정의 필드를 추가할 수 있습니다: buildConfigField "String", "API_URL", '"https://api.example.com"'. buildType에서 선언된 BuildConfigField는 해당 유형의 모든 변형에서 사용 가능합니다. buildType의 값은 productFlavor의 값을 재정의하며, productFlavor는 defaultConfig를 재정의합니다.

디버그 빌드의 경우 API_URL을 localhost나 staging 서버로 설정하고 release의 경우 프로덕션으로 설정하는 것이 편리합니다. BuildConfig.FLAVOR와 BuildConfig.BUILD_TYPE도 자동으로 생성되며 현재 flavor와 build type의 이름을 포함합니다. 코드에서 사용할 수 있습니다: if (BuildConfig.DEBUG) { /* 로그 */ } — DEBUG 상수는 debug build type에 대해서만 true입니다. BuildConfig.DEBUG는 AGP가 모든 BuildConfig에 추가하는 표준 필드입니다.

Build Type의 리소스는 source set src/<buildType>/res/를 통해 정의됩니다. 예를 들어, src/debug/res/values/strings.xml에는 "Server: Dev" 문자열이 포함되고 src/release/res/에는 "Server: Prod"가 포함될 수 있습니다. 매니페스트 리소스도 source set을 통해 재정의됩니다: src/debug/AndroidManifest.xml은 디버그 빌드에만 <uses-permission android:name="android.permission.INTERNET" />를 포함할 수 있습니다. 이는 코드에서 BuildConfig를 확인하는 것보다 깔끔하며 프로그래밍 방식으로 설정할 수 없는 속성(networkSecurityConfig 등)에도 작동합니다.

kotlin
// src/debug/kotlin/.../DebugConfig.kt
object DebugConfig {
    val apiUrl = "http://localhost:8080/api"
    val enableLogging = true
    val enableCrashReporting = false
}

// src/release/kotlin/.../ReleaseConfig.kt
object ReleaseConfig {
    val apiUrl = "https://api.production.com/v2"
    val enableLogging = false
    val enableCrashReporting = true
}

// 사용법: 메인 클래스가 리플렉션을 통해 Config를 로드합니다
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
    "debug" -> DebugConfig
    else -> ReleaseConfig
}

자주 묻는 질문

Minification이 활성화된 디버그 빌드를 가질 수 있나요?

네, initWith debug를 사용하여 debugMinified와 같은 사용자 정의 Build Type을 만들고 minification을 활성화하세요: debugMinified { initWith debug; minification true }. 전체 릴리스 버전을 빌드하지 않고 ProGuard 규칙을 테스트하는 데 유용합니다.

릴리스 빌드가 올바르게 서명되었는지 어떻게 확인하나요?

Android SDK의 apksigner를 실행하세요: apksigner verify --print-certs app-release.apk. 인증서가 Google Play Console에 업로드된 것과 일치하면 서명이 올바른 것입니다. 이전 형식의 경우 jarsigner로도 확인할 수 있습니다.

Build Type에서 matchingFallbacks란?

matchingFallbacks는 라이브러리에 필요한 유형이 없을 때 사용할 Build Type을 지정합니다. 예를 들어, 앱에 "staging" 유형이 있지만 라이브러리에 "release"만 있는 경우 AGP는 라이브러리에 release를 사용합니다. 목록으로 지정됩니다: matchingFallbacks = ["release", "debug"].

특정 라이브러리의 minification을 비활성화하려면?

ProGuard 규칙에서 라이브러리 클래스에 -keep을 사용하세요. 예: -keep class com.some.library.** { *; }. 모든 라이브러리에 대해 minification을 완전히 비활성화하려면 proguard-rules.pro에서 -dontobfuscate-dontoptimize를 지정하세요.

Build Type이 Android API 버전에 영향을 미치나요?

Build Type 자체는 minSdk나 targetSdk를 변경하지 않습니다. 그러나 특정 Build Type의 minSdk를 설정할 수 있습니다: debug { minSdk 21 }. 이는 디버그 빌드에 유용합니다 — 빌드 속도를 높이기 위해 API 21+만 지원하고 릴리스 빌드는 minSdk 26을 사용할 수 있습니다.

요약

  • Build Type — 디버깅, 압축 및 서명을 결정하는 인프라 빌드 설정입니다.
  • Debug — 개발용 빠른 빌드, release — 게시용 최적화 빌드입니다.
  • 사용자 정의 Build Types(staging, benchmark)는 initWith를 통해 매개변수를 상속하여 생성됩니다.
  • R8이 minification, 난독화, resource shrinking을 수행하여 APK를 최대 60%까지 줄입니다.
  • BuildConfigFieldsource sets로 각 유형별 변수와 리소스를 설정할 수 있습니다.
  • 릴리스 서명 키는 저장소 외부(CI/CD secrets 또는 암호화된 저장소)에 보관해야 합니다.
  • 권장: 게시 전에 항상 릴리스 빌드를 테스트하세요 — debug는 minification 동작을 보여주지 않습니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기