목차

개발 노트/Android

Gradle: 안드로이드의 빌드 툴킷

천만일 2023. 8. 13. 06:52

Gradle Practice라는 비어있는 안드로이드 프로젝트를 하나 생성해서 Gradle의 구조와 하는 일에 대해 알아보겠습니다.

새로 생성한 안드로이드 프로젝트

gradle wrapper

가장 먼저 gradle wrapper를 살펴보겠습니다.

gradle wrapper는 gradlew라고도 표기합니다.

gradlew는 gradle을 다운로드하고 실행하는 하나의 애플리케이션입니다.

이것이 개발자들이 일관적으로 빌드를 할 수 있게끔 도와줍니다.

graddle-wrapper.properties에는 사용할 버전의 gradle이 저장된 url을 가지고 있습니다.

이를 통해 다수의 개발자들이 빌드할 때 gradle 버전이 변경되지 않도록 보장합니다.

#Sat Aug 12 05:28:21 KST 2023
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

gradle이 작동하는 방식은 각각의 task를 통해 동작합니다.

터미널에 ./gradlewtasks 명령어를 통해 gradle이 제공하는 task를 전부 확인할 수 있습니다.

또한, 직접 task를 생성할 수도 있습니다.

개인적으로는 마치 npm script와도 유사한 느낌을 받았습니다.

조금 더 알아보자면, 안드로이드 스튜디오 메뉴바 > Build > Rebuild Project는 build task를 실행하는 것과 동일합니다.

따라서, 터미널에 ./gradlew build와 동일한 동작을 합니다.

settings.gradle or settings.gradle.kts

다음은 gradle 설정 파일인 settings.gradle입니다.

settings.gradle에서는 프로젝트에서는 크게 다음 2가지 정보를 gradle에게 전달합니다.

  • 플러그인을 가져올 저장소
  • 앱을 빌드할 때 포함해야 할 모듈
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "Gradle Practice"
include ':app'

제가 생성한 안드로이드 프로젝트에서는 google(), mavenCentral(), gradlePluginPortal() 3개의 저장소가 정의되어 있었습니다.

  • google()구글에서 제공하는 플러그인과 라이브러리를 포함하고 있습니다.
    • Google maven repository 플러그인 리스트
    • ex) AndroidX, Jetpack Compose, Firebase 등
    • 구글의 공식 maven repository입니다.
    • Google's Maven Repository
  • mavenCentral()
    • 대표적으로 org.jetbrains.kotlin.android를 제공하는 저장소입니다.
    • sonatype에서 제공하는 central이라는 maven repository입니다.
    • Maven Central
  • gradlePluginPortal()

각각의 저장소가 관리하는 플러그인을 확인할 수 있는 페이지를 제공하고 있지만, 다음 주소에서는 maven에서 제공하는 모든 플러그인, 라이브러리와 제공하는 저장소에 대한 정보를 제공하고 있습니다.

다음 링크에서 확인하실 수 있습니다. => https://mvnrepository.com/

top-level build.gradle

안드로이드 프로젝트에는 2개의 build.gradle이 존재합니다.

프로젝트(최상위) 수준의 build.gradle과, 모듈 수준의 build.gradle입니다.

먼저 프로젝트 단위의 build.gradle부터 알아보겠습니다.

프로젝트 단위의 build.gradle은 프로젝트 최상단에 존재합니다.

다음과 같은 역할을 합니다.

  • 프로젝트의 설정을 관리합니다.
  • 프로젝트의 모든 모듈에서 사용되는 라이브러리 및 플러그인 정보를 포함합니다.
plugins {
    id 'com.android.application' version '7.4.1' apply false
    id 'com.android.library' version '7.4.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
}

build.gradle에는 settings.gradle에 정의된 repository에 존재하는 종속 항목들만 가져올 수 있습니다.

settings.gradle에 정의된 repository에 존재하지 않는 plugin을 추가하면 다음과 같이 빌드를 실패합니다.

repository에서 plugin을 찾을 수 없음

apply false는 종속 항목에는 추가하지만, 현재 build.grade이 속한 단위에서는 사용하지 않을 경우 사용합니다. 즉, 종속 항목을 build.gradle이 속한 범위에서 사용해야 하는 경우(ex. sub-project) apply false를 사용하지 않습니다.

module-level build.gradle

두 번째 build.gradle은 모듈 수준의 빌드를 설정합니다.

안드로이드 프로젝트를 처음 생성하면 기본적으로 app이라는 이름의 모듈을 만들어줍니다.

app 모듈 내부에 build.gradle이 존재하고 다음과 같은 형태를 가지고 있습니다.

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.example.gradlepractice'
    compileSdk 33

    defaultConfig {
        applicationId "com.example.gradlepractice"
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.7.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.7.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
  • plugins
    • 일반적으로 안드로이드 프로젝트에서는 이후 정의되는 android 블록을 정의할 수 있도록 com.android.application을 적용합니다.
    • 또한, android 블록의 kotlinOptions과 같은 필드는 org.jetbrains.kotlin.android에 정의된 스펙이므로 적용합니다.
    • plugins 블록은 이 모듈이 빌드할 때 사용되는 플러그인들을 정의합니다.
  • android
    • android block 내부에는 안드로이드 앱 빌드 설정이 정의됩니다.
    • namespace
      • 앱의 리소스에 접근할 때 사용되는 네임스페이스를 정의합니다.
    • compileSdk
      • 이는 앱이 compileSdk에 정의된 API 버전 혹은 그 이하의 버전에서 제공하는 기능을 사용할 수 있음을 의미합니다.
      • 앱을 컴파일할 때 사용하는 Android API 버전을 정의합니다.
    • defaultConfig
      • 혹은 main/AndroidManifest.xml에 정의된 값을 동적으로 재정의할 수 있습니다.
      • defaultConfig 블록은 빌드할 때의 기본값을 설정합니다.
    • buildTypes
      • debug build type은 buildTypes 블록에 명시되어있지는 않지만, 디버깅 툴에 포함되어 있습니다.
      • release build type은 안드로이드 스튜디오에서 기본적으로 설정하여 명시해 줍니다.
      • 기본적으로 안드로이드에서는 두 가지의 build type을 제공합니다: debug, release.
    • compileOptions, kotlinOptions
      • 최신 버전에서는 kotlin.jvmToolchain에서 정의하면 생략할 수 있습니다. (확인 필요)
      • 빌드할 때 사용하고자 하는 jvm 버전을 정의합니다.
    • buildFeatures
      • 안드로이드 프로젝트에서의 빌드 기능 활성화 여부를 정의하는 블록입니다.
  • dependencies
    • module 수준의 빌드에서 필요한 종속 항목들을 정의합니다.

다음 문서에서 android 블록에서 제공하는 인터페이스를 확인할 수 있습니다.

 

Class Index  |  Android Developers

com.android.build.api.component

developer.android.com

 

gradle properties

gradle에는 프로젝트 최상단에 두 개의 속성 파일을 가집니다.

  • gradle.properties
  • gradle 설정을 구성하는 파일입니다.
  • local.properties일반적으로 sdk의 경로가 정의되어 있습니다.
  • sdk.dir=/Users/{사용자 이름}/Library/Android/sdk
  • 로컬 빌드 환경을 구성하는 파일입니다.

 

(+추가)

  • gradle script v.s. kotlin
  • kotlin으로 build script를 작성하면 엄격한 타이핑, 고도화된 자동 완성 등으로 인해 장기적으로 긍정적인 요소들이 있다고 합니다.

 

참고 자료

 

Configure your build  |  Android Studio  |  Android Developers

The Android build system compiles app resources and source code and packages them into APKs that you can test, deploy, sign, and distribute.

developer.android.com

 

What is the difference between google() and mavenCentral() in project level gradle file in an android project?

At the project level, the Gradle file of an android project contains google() and mavenCentral() inside the repository block. buildscript { repositories { google() mavenCentral(...

stackoverflow.com