버미

[안드로이드] Gradle 이란 본문

안드로이드

[안드로이드] Gradle 이란

Bum_2 2025. 9. 16. 18:13

안드로이드 개발을 하다보면 그래들 파일에 대해서 자주 접하게 되는데 Gradle이 뭔지 알아보자.


Gradle

소프트웨어를 빌드할 수 있는 오픈소스 빌드 자동화 툴이다.

안드로이드에서 빌드란 .apk 파일을 만드는 과정이다.

 

인텔리제이 IDE는 다양한 빌드 자동화 도구(Maven, Ant, Gradle)를 지원하지만, 안드로이드 스튜디오 IDE는 빌드 배포 시스템으로 Gradle만 사용할 수 있다.

 


Gradle 빌드 과정 

Gradle의 빌드 진행 과정은 다음과 같다.

  1. 초기화(Initialization) : 어떤 프로젝트들을 빌드할지 결정하고, 각 프로젝트에 대한 초기 환경을 설정하는 단계이다. 즉, 멀티 모듈 구조에서 어떤 모듈을 빌드에 포함할지 결정하고, 각 모듈의 Gradle Project 객체를 구성하는 단계.
  2. 구성(Configutation) : 초기화 단계에서 생성된 각 모듈의 build.gradle(또는 build.gradle.kts) 파일을 실행해, 빌드에 필요한 Task를 구성하고 의존 관계를 설정하는 단계.
  3. 실행(Execution) : 구성 단계에서 생성된 Task를 기반으로, 사용자가 요청한 Task와 그에 의존하는 Task를 실제로 실행하여 빌드를 수행하는 단계.

1. 초기화 단계

어떤 프로젝트들을 빌드할지 결정하고, 각 프로젝트에 대한 초기 환경을 설정하는 단계이다. 즉, 멀티 모듈 구조에서 어떤 모듈들을 빌드에 포함할지 결정하고, 각 모듈의 Gradle Project 객체를 구성하는 단계이다.

 

첫 번째로, settings.gradle.kts 파일이 실행되어 include(":app", ":data", ":domain") 등의 코드를 통해 빌드에 포함할 모듈을 결정한다.

이 과정에서 Gradle은 각 모듈에 대응하는 Project 객체를 생성하고, 이를 기반으로 전체 빌드의 프로젝트 트리를 구성한다.

//settings.gradle.kts 코드 예시
pluginManagement {
    ...
}
dependencyResolutionManagement {
   ...
}

rootProject.name = "Bum2_tistory"
include(":app")
include(":data")
include(":domain")
include(":core")

 


2. 구성 단계 

Project 객체에 빌드 설정을 적용하는 단계. Gradle은 각 모듈의 build.gradle(또는 build.gradle.kts) 파일을 실행하여, 초기화 단계에서 생성된 Project 객체에 Android Gradle Plugin(AGP)을 포함한 플러그인과 빌드 설정을 적용한다.

// Domain 모듈 build.gradle.kts 예시
plugins {
    alias(libs.plugins.android.library)
    alias(libs.plugins.kotlin.android) 
}

android {
    namespace = "com.tistory.bum2"
    compileSdk = 35

    defaultConfig {
        minSdk = 28

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles("consumer-rules.pro")
    }

    packaging {
        resources.excludes.add("META-INF/gradle/incremental.annotation.processors")
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro",
            )
        }
    }
    buildFeatures {
        buildConfig = true
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

dependencies {
    testImplementation(libs.junit) 
    
    // paging
    implementation(libs.androidx.paging.compose)

    // timber
    implementation(libs.timber)

    implementation(libs.javax.inject)
}

 

 

build.gradle 파일의 각 블럭으로 Project 객체의 메서드가 호출된다. 각 블럭의 속성을 정리해보자면 다음과 같다.

 

  • plugins 블록
    Android Gradle Plugin(AGP)Kotlin Plugin 등 필요한 플러그인을 프로젝트에 적용.
    • id("com.android.application") : Android 애플리케이션 빌드를 위한 플러그인
    • id("org.jetbrains.kotlin.android") : Kotlin 언어를 지원하기 위한 플러그인
    • 여기서는 Android 애플리케이션 빌드를 위한 Android Plugin과 Kotlin 언어를 사용하기 위한 Kotlin Plugin이 적용되어 있습니다. 
  • android 블록
    Android Gradle Plugin(AGP) 이 제공하는 DSL로, 애플리케이션의 전반적인 빌드 설정을 정의하는 핵심 영역
    • namespace: 애플리케이션의 기본 패키지 이름
    • compileSdk: 컴파일 시 사용할 Android API 버전
    • defaultConfig { ... }: 앱의 기본 설정을 정의 (예: applicationId, minSdk, targetSdk, versionCode, versionName)
    • buildTypes { ... }: 빌드 유형 정의 (예: release 빌드에서 isMinifyEnabled, ProGuard 설정 등)
    • compileOptions { ... }: Java 소스 및 대상 호환성 지정
    • kotlinOptions { ... }: Kotlin 컴파일러 옵션 지정. (jvmTarget 등)
    • buildFeatures { ... }: 빌드 기능을 활성화/비활성화 (예: Compose 활성화)
    • composeOptions { ... }: Compose 관련 컴파일러 확장 버전 설정
    • packaging { ... }: 패키징 시 특정 리소스나 파일을 제외하도록 설정  
  • dependencies 블록
    dependencies 블록은 프로젝트가 빌드될 때 필요한 외부 라이브러리나 모듈 의존성을 정의 

3. 실행 단계

구성단계에서 생성·설정된 모든 Project의 Task 그래프 중에서, 사용자가 요청한 Task 및 그 의존 Task를 실제로 실행하는 단계.

 

 

안드로이드 스튜디오에서 ./gradlew build --scan  명령어를 사용하면, 아래와 같이 독자의 프로젝트의 빌드 단계 과정에 따라 시간이 측정된다.

 

 


Gradle이 Task 기반으로 동작하는 이유

Gradle은 작업 단위를 명확히 정의하고, 그들 간의 의존 관계를 그래프 형태로 관리하기 위해 Task 기반으로 설계되었다.

 

Task는 독립적인 빌드 단위다.

예를 들어 다음과 같은 Task가 존재한다.

Task 입력 출력
compileDebugKotlin .kt 파일 .class 파일
mergeResources XML/이미지 등 병합된 리소스 폴더
packageDebug 클래스 .apk

 

위와 같이, 각 Task의 입력과 출력을 명시적으로 추적하기 때문에, 변경이 감지되지 않은 Task는 재실행하지 않고 결과를 재활용할 수 있다. 따라서 이 Task기반 구조 덕분에 변경된 부분만 빌드함으로써 증분 빌드가 가능하다.

 

 

 

 

 

안드로이드 개발자라면 알아야 하는 Gradle 원리