본문 바로가기
안드로이드/Android

[Android] Gradle

by jinwo_o 2024. 8. 6.
 

Gradle의 동작원리 이해하기

안드로이드 개발을 한다면 이 코끼리를 지겹게 보게 됩니다. 다만 이 코끼리에 대해서 자세히 공부해보고 알아본적이 없어서 이번 게시글을 통해 Gradle의 원리를 이해해보고자 합니다. Gradle이란

everyday-develop-myself.tistory.com

  • Groovy 언어를 기반으로 한 오픈소스 빌드 도구
    • 빌드 도구 : 애플리케이션 생성을 자동화 하기 위한 프로그램으로 안드로이드에서는 .apk 파일을 만드는 과정을 자동화한다
  • 모든 종류의 소프트웨어를 빌드할 수 있는 오픈소스 빌드 자동화툴
    • 빌드 : 컴파일을 비롯한 다양한 작업을 통해 최종적으로 배포 가능한 소프트웨어를 생성하는 과정
      • 다양한 작업 : 소스 코드를 컴파일하고, 라이브러리를 추가하고, 리소스 파일을 처리하고, 테스트를 실행하고, 배포를 위한 실행 파일이나 패키지를 생성하는 등의 과정을 포함한다.
      • 안드로이드에서의 빌드 과정은 .apk 파일을 만드는 과정을 의미한다.
  • build.gradle 파일과 setting.gradle 파일을 통해 우리가 원하는 소프트웨어를 빌드할 수 있도록 되어 있다.

Task

  • Gradle 에서는 Task 를 기반으로 빌드를 진행한다.
  • build.gradle 파일에 정의된 가장 작은 작업을 의미한다.
  • 종속된 Task가 없는 특정 Task에 변경 사항이 생겼을 때 다른 Task를 다시 빌드할 필요 없이 해당 Task만 다시 빌드할 수 있기 때문에 빌드 속도를 향상시킬 수 있다. (task dependency mechanism)

Gradle 고정 빌드 단계 (Fixed Build Phases)

Gradle에는 고정 빌드 단계라는 빌드 절차가 있습니다.

  1. 초기화 (Initialization)
  2. 구성 (Configuration)
  3. 실행 (Execution)

 

1. 초기화 단계 (Initialization)

  • 빌드를 진행할 프로젝트를 결정하고 각각에 대한 프로젝트 인스턴스 객체를 생성한다.
  • 최상위 디렉토리에 setting.gradle 파일에서 프로젝트의 모듈을 정의한다.
  • build.gradle 파일에는 해당 파일에서 공통적으로 사용하고 있는 오픈소스들의 버전, applicationId, Gradle 버전, repository 에 대한 정의가 명시 되어 있다. 이를 통해 프로젝트 수준의 설정을 구성한다.
  • 초기화 단계의 구체적인 동작gradle/init/ 경로의 init.gradle + *.gradle 파일을 읽어들여 Gradle 인스턴스를 생성한 다음 프로젝트의 settings.gradle 파일로 Settings 인스턴스를 생성하는 방식으로 이뤄진다.

 

2. 구성 단계(Configuration)

  • 빌드 대상이 되는 모든 프로젝트의 빌드 스크립트를 실행한다.
  • 각 모듈에 정의되어 있는 build.gradle 파일을 실행하여 프로젝트 객체를 구성한다.
  • build.gradle 파일을 바탕으로, Android Gradle Plugin(AGP)를 통해 초기화 단계에서 생성된 Project 인스턴스들에 빌드 설정을 적용한다.
    • Android Gradle Plugin (AGP) : Android 애플리케이션을 지원하는 빌드 시스템으로, 다양한 유형의 소스를 컴파일하고 실제 휴대폰에서 실행할 수 있는 애플리케이션에 컴파일된 소스를 연결하는 지원 기능이 있다.

 

3. 실행 단계(Execution)

  • 구성 단계에서 생성하고 설정된 프로젝트의 태스크 중에서 실행할 task를 결정한다.
  • Gradle은 명령행에서 지정한 task 이름과 현재 디렉토리를 기반으로 실행할 task를 선택하고, 해당 task들을 실행한다.

Gradle Scripts

질문) Kotlin vs Groovy

  • 두 언어 모두 JVM에서 실행 가능하고, 자바와 상호 운용이 가능한다.
  • Kotlin은 정적 타입 언어로 변수 타입이 컴파일 타임에 검사된다.
  • Groovy는 주로 동적 타입 언어로, 타입 검사가 런타임에 이루어지지만 정적 타입 모드로도 실행될 수 있다.
VS Kotlin Groovy
용도 공식 안드로이드 앱 개발 언어 / 서버 측 프로덕션에 더 적합 스크립트와 도메인 특화 언어에 적합
널 안정성 두 가지 표기법(널 허용 및 널 허용 안 함)을 통해 널 안정성을 보장 널 안정성이 없음
학습 곡선 생산성과 신뢰성을 높이기 위한 간결한 구문 Java와 유사한 구문으로 전환이 쉬움
컴파일 정적 타이핑 언어 동적 및 정적 타입 체크 모두 지원
성능 거의 Java와 비교할 만한 높은 성능 클로저로 인해 성능이 느림
파일 확장자 .kt, .kts 파일 확장자 .groovy 파일 확장

settings.gradle

  • 루트 프로젝트 디렉터리에 있다.
  • 프로젝트 수준 저장소 설정을 정의하고, 앱을 빌드할 때 포함해야 하는 모듈을 Gradle에 알려준다.
pluginManagement {
    repositories {
        google() // Google의 Maven 저장소
        mavenCentral() // Maven Central 저장소
        gradlePluginPortal() // Gradle 플러그인 포털
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "My Application"
include(":app")

 

  • pluginManagement.repositories
    • Gradle 플러그인 및 그들의 종속 항목을 검색하거나 다운로드하는 데 Gradle이 사용하는 저장소를 구성합니다.
    • Gradle은 JCenter, Maven Central 및 Ivy와 같은 원격 저장소를 사전에 구성할 수 있게 지원을 제공합니다. 또한 로컬 저장소를 사용하거나 사용자 정의 원격 저장소를 정의할 수도 있습니다.
  • dependencyResolutionManagement.repositories
    • 프로젝트의 모든 모듈에서 공통적으로 사용되는 저장소 및 종속 항목을 구성하는 곳입니다.
    • 이는 애플리케이션을 만들 때 사용하는 라이브러리와 같은 모든 모듈에 적용됩니다.
  • repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    • 종속성 해결 관리를 위한 설정을 정의합니다.
    • repositoriesMode를 FAIL_ON_PROJECT_REPOS로 설정하여, 프로젝트 수준 저장소가 사용 중지되고 프로젝트 수준 저장소에 종속성을 정의할 경우 오류가 발생하도록 설정합니다.
    • RepositoriesMode 종류

 

[Android] 안드로이드 build.gradle.kts 설정 방법, build.gradle.kts

build.gradle.kts 란?안드로이드 프로젝트를 설정하고 빌드할 때 build.gradle.kts 파일은 중요한 역할을 합니다. Kotlin DSL (KTS)을 사용한 Gradle 스크립트 설정은 더 타입 안전하며, 코드 완

developertools.tistory.com

 

[Android] Build.Gradle(Module)? Build.Gradle(project)?, settings.gradle? , 안드로이드의 "gradle"에 대하여

CHAPTER 1. Android 기초 다지기 안녕하세요~ 습득자와 분실자를 이어주는 로스트파인더 앱을 만들...

blog.naver.com

build.gradle (project)

  • 루트 프로젝트 디렉토리에 있다.
  • 프로젝트의 모든 모듈에 적용되는 빌드 구성을 정의하는 곳
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {

    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN_VERSION}"
    }
}

plugins {
    // 빌드의 하위 프로젝트에 플러그인을 적용하고 싶지만 루트 프로젝트에서는 적용하고 싶지 않을 경우
    // apply false를 통해 현재 프로젝트에서 플러그인을 적용하지 않도록 Gradle에 지시
    // plugins {} 하위 프로젝트의 빌드 스크립트에서 버전 없이 블록을 사용할 수 있다.
    id 'com.android.application' version '8.1.0' apply false
    id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
}

allprojects {
    tasks.register(Delete) {
        // 빌드 디렉토리를 청소하는 작업을 정의
        delete(rootProject.buildDir)
    }
}
  • buildscript : gradle 자체에 대한 저장소와 종속성을 구성하는 곳
  • repositories : gradle이 dependencies를 검색하거나 다운로드하는데 사용하는 저장소를 설정하는 곳
  • dependencies : gradle이 프로젝트를 빌드하는데 필요한 라이브러리를 구성하는 곳
  • plugins
    • 프로젝트에 적용할 플러그인을 정의한다.
    • 플러그인은 Gradle 빌드 시스템의 기능을 확장하거나 설정을 간소화하는 데 사용된다.
    • 안드로이드 애플리케이션이나 라이브러리 프로젝트에 필요한 플러그인을 설정할 수 있다.
  • allprojects : 프로젝트 수준의 build.gradle 뿐만 아니라 해당 프로젝트에 포함된 모든 모듈의 build.gradle을 제어한다.
  • subprojects : 프로젝트 수준의 build.gradle을 제외한 모든 모듈(서브 모듈)의 build.gradle을 제어한다.
  • project : 특정 모듈의 build.gradle에만 스크립트가 추가된다.
  • tasks : Gradle 빌드 시스템에서 실행할 커스텀 작업을 정의한다.

 

[Android] Build.Gradle(Module)? ,buildTypes?, proguard?, Debug/release?, 안드로이드의 "gradle"에 대하여

CHAPTER 1. Android 기초 다지기 안녕하세요~ 습득자와 분실자를 이어주는 로스트파인더 앱을 만들...

blog.naver.com

 

빌드 구성  |  Android Studio  |  Android Developers

Android 빌드 시스템은 앱 리소스 및 소스 코드를 컴파일하고 개발자가 테스트, 구축, 서명 및 배포할 수 있는 APK로 패키징합니다.

developer.android.com

build.gradle (Module)

  • 각 모듈 디렉토리에 있다.
  • 해당 모듈의 빌드 설정을 정의하는 곳
plugins {
    id 'com.android.application' // 안드로이드 애플리케이션 플러그인
    id 'kotlin-kapt' // Kotlin Annotation Processing
}

android {
    namespace = "com.example.myapplication" // 주로 앱 리소스에 액세스하는 데 사용
    compileSdk = 34 // 소스 코드를 컴파일할 때 사용할 수 있는 Android 및 Java API를 결정

    defaultConfig {
        applicationId = "com.example.myapplication"
        minSdk = 24 // 앱에서 지원할 가장 낮은 Android 버전을 지정
        targetSdk = 34 // 애플리케이션의 런타임 동작을 설정하거나 테스트한 Android 버전을 증명
        versionCode = 1
        versionName = "1.0"

        // 계측 테스트를 실행할 때 사용할 테스트 러너
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false // 코드 축소 활성화
            // 코드 축소, 최적화, 난독화 작업을 수행할 때 사용하는 설정 파일을 지정하는 데 사용
            proguardFiles(
                // Android SDK에 포함된 기본 ProGuard 최적화 파일
                getDefaultProguardFile("proguard-android-optimize.txt"),
                // 프로젝트에 포함된 사용자 정의 ProGuard 규칙 파일
                "proguard-rules.pro"
            )
        }
    }
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {

    implementation "androidx.core:core-ktx:1.9.0"
    testImplementation "junit:junit:4.13.2"
    androidTestImplementation "androidx.test.ext:junit:1.1.5"

    // https://developer.android.com/build/migrate-to-ksp?hl=ko
    kapt "androidx.room:room-compiler:$roomVersion"
    ksp "androidx.room:room-compiler:$roomVersion"
}

kapt {
    // 런타임에서 발생할 수 있는 에러에 대한 검사를 컴파일 시점에 체크한다.
    correctErrorTypes true
}
  • plugins : 해당 모듈에 적용할 플러그인으로, Gradle 빌드 시스템의 기능을 확장하거나 설정을 간소화하는 데 사용된다.
    • kapt(kotlin annotation processing tool)
      • Kotlin에서 Java Annotation Processor를 사용하여 Annotation들을 사용할 수 있도록 해준다.
      • 코틀린 프로젝트를 컴파일 할 때는 javac가 아닌 kotlinc로 컴파일을 하기 때문에 Java로 작성한 애노테이션 프로세서가 동작하지 않는다. 그렇기 때문에 코틀린에서는 이러한 애노테이션 처리기를 제공한다.
    • ksp(kotlin symbol processing) : 코틀린에서 경량화 된 컴파일러 플러그인을 개발할 수 있는 API다. 학습곡선을 최소한으로 줄이고, 코틀린의 기능을 활용할 수 있는 단순화된 API를 제공한다.
  • namespace : Android 애플리케이션의 패키지 이름을 정의한다.
  • compileSdk : 컴파일에 사용할 Android API 버전을 지정한다.
  • defaultConfig : 기본 설정을 정의하는 블록으로, 애플리케이션의 기본적인 속성을 설정한다. 애플리케이션 ID, 최소 SDK 버전, 대상 SDK 버전, 버전 코드 및 버전 이름을 여기에서 설정한다.
  • buildTypes : 빌드 유형을 정의하는 블록으로, 여기에서는 릴리스 빌드에 대한 설정을 지정한다. 코드 축소화(minifyEnabled) 설정 및 ProGuard 규칙 파일을 여기에서 정의한다.
  • compileOptions : 컴파일 옵션을 정의하는 블록으로, Java 소스 및 대상 호환성을 설정한다.
  • kotlinOptions : Kotlin 옵션을 정의하는 블록으로, JVM 대상 버전을 설정한다.
  • buildFeatures : 빌드 기능을 활성화 또는 비활성화하는 블록으로, 여기에서 Compose를 활성화한다.
  • composeOptions : Compose 관련 옵션을 정의하는 블록으로, Compose의 Kotlin 컴파일러 확장 버전을 설정한다.
  • packaging : 패키징 옵션을 정의하는 블록으로, 여기에서 리소스를 제외하도록 설정한다.
  • dependencies : 모듈 자체를 빌드하는 데 필요한 종속 항목을 정의하는 블록으로, 외부 라이브러리를 사용하기 위해 종속 항목을 정의한다.

proguard-rules.pro

  • 모듈과 그 모듈의 종속되어 있는 라이브러리의 proguard와 연관되어 있는 규칙을 선언하는 파일이다.

gradle.properties

  • 프로젝트 수준의 그레이들 환경 설정 파일로, 빌드 설정과 관련된 여러가지 옵션을 제공한다.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
kotlin.code.style=official
android.nonTransitiveRClass=true
  • org.gradle.jvmargs : Gradle Daemon에 사용될 JVM 인자를 지정한다. 이 설정은 빌드 성능을 위한 JVM 메모리 세팅에 유용하다.
    • Gradle Daemon : gradle이 실행되는 인스턴스를 유지하고 빌드가 끝난 뒤에도 사라지지 않고 백그라운드에서 대기한다. Gradle 빌드 시간을 단축시키는 역할을 한다.
    • Daemon Process : 서비스의 요청에 응답하기 위해 오랫동안 실행중인 백그라운드 프로세스
  • useAndroidX : support library 대신 적절한 AndroidX 라이브러리를 사용한다.
  • kotlin.code.style : 코틀린 코드 스타일을 지정하는 옵션이다. gradle은 코드를 정렬하는 기능은 하지 않기 때문에, 이 옵션은 Intellij IDE에서 사용하는 옵션이다.
  • android.nonTransitiveRClass : R 클래스(R.xx.xxx 형식으로 안드로이드 리소스를 관리하는 변수들이 모여있는 클래스)에 라이브러리 자체에 선언된 리소스만 포함하고, 라이브러리에 종속되는 항목들은 포함하지 않도록 하는 옵션이다. 이 옵션을 사용하면 APK 빌드시 용량이 크게 줄어든다.

gradle-wrapper.properties

  • gradle 자체와 관련된 설정 파일
  • Gradle Wrapper (gradlew)
    • 소스 코드와 함께 포함된 작은 애플리케이션으로, Gradle을 자동으로 다운로드하고 실행하여 빌드 실행의 일관성을 높여준다.
    • 개발자는 애플리케이션 소스를 다운로드하고 gradlew를 실행하면 필요한 Gradle 배포판이 다운로드되고 애플리케이션이 빌드된다.
  • gradle/wrapper/gradle-wrapper.properties 파일
    • Gradle 버전을 설명하는 distributionUrl 속성이 포함되어 있다.
    • distributionUrl : 빌드를 실행하는 데 사용되는 Gradle 버전을 지정한다.
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

local.properties

  • 안드로이드 프로젝트의 루트 디렉토리에 위치한 설정 파일로, 로컬 개발 환경의 특정 정보를 저장하는 데 사용된다.
  • 안드로이드 스튜디오에서 자동으로 생성되며, 프로젝트의 빌드나 실행에 필요한 SDK 경로와 같은 로컬 설정을 포함한다.
  • 보안에 민감한 정보나 인증 키를 저장할 때도 사용될 수 있다.
  • local.properties를 사용하여 키 관리하는 방법
    • Github Actions secret key

Groovy에서 KTS로 마이그레이션

dependencies {
    def nav_version = "2.5.0"

    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
}
dependencies {
    val navVersion = "2.5.0"

    implementation("androidx.navigation:navigation-fragment-ktx:$navVersion")
}

'안드로이드 > Android' 카테고리의 다른 글

[Android] Activity  (0) 2024.08.09
[Android] App Manifest  (0) 2024.08.08
[Android] Package  (0) 2024.08.01