Gradle 기본

뾰족머리삼돌이·2025년 1월 25일
0

기타

목록 보기
5/7

Gradle과 Maven은 빌드 자동화 도구로 Task 단위로 빌드과정을 나누고, 각 Task간의 의존관계를 이용하여 빌드에 필요한 일련의 과정들이 순차적으로 실행되도록 자동화한다. 예를든다면 테스트작업이 성공해야만 다음 Task가 실행되도록 빌드루틴을 짤 수 있다.

보통 Spring 프로젝트를 생성할 때 Maven이나 Gradle 중 하나를 선택하도록 소개된다.

Maven은 pom.xml에서 프로젝트에 필요한 설정들을 작성하며,
Gradle은 build.gradle이라는 파일에 Groovy 또는 Kotlin을 이용해 스크립트를 작성한다.

Gradle 디렉토리 구조

Gradle은 크게 유저 홈 디렉토리프로젝트 루트 디렉토리, 총 두개의 메인 디렉토리로 구성된다.

유저 홈 디렉토리는 보통 C:\Users\<USERNAME>\.gradle 경로에 위치하며 전역적인 설정 값과 초기화 스크립트, 캐시, 로그파일이 위치한다.

이 경로는 GRADLE_USER_HOME 라는 환경변수에 세팅된다.

├── caches  
│   ├── 4.8 
│   ├── 4.9 
│   ├── ⋮
│   ├── jars-3  
│   └── modules-2   
├── daemon 
│   ├── ⋮
│   ├── 4.8
│   └── 4.9
├── init.d  
│   └── my-setup.gradle
├── jdks    
│   ├── ⋮
│   └── jdk-14.0.2+12
├── wrapper
│   └── dists   
│       ├── ⋮
│       ├── gradle-4.8-bin
│       ├── gradle-4.9-all
│       └── gradle-4.9-bin
└── gradle.properties   

위 형태의 디렉토리 구조를 가지고 있으며, Gradle 버전에 따른 캐시 디렉토리와 공유 캐시, 로그 등의 정보가 저장되어있다.


프로젝트 루트 디렉토리는 프로젝트 생성과 함께 만들어진다. Gradle Wrapper 설정 디렉토리인 gradle과 빌드 관련 디렉토리인 .gradle, build 등이 포함된다.

├── .gradle 
│   ├── 4.8 
│   ├── 4.9 
│   └── ⋮
├── build   
├── gradle
│   └── wrapper 
├── gradle.properties   
├── gradlew 
├── gradlew.bat 
├── settings.gradle.kts 
├── subproject-one  
|   └── build.gradle.kts    
├── subproject-two  
|   └── build.gradle.kts    
└── ⋮

디렉토리 구조는 위 형태와 같다.

gradle에는 Gradle Wrapper와 관련된 설정파일들이 존재한다.
이는 빌드 스크립트를 실행시키는 gradlew와 관련된 설정을 의미한다.

.gradle에는 Gradle 버전에 따라 빌드에 필요한 캐시 정보가 저장된다.
예를들어, 의존성 정보나 Task 실행 기록 등이 캐시형태로 관리된다.

build는 실질적인 빌드 결과물이 저장되는 디렉토리다.
컴파일된 클래스파일과 JAR 파일, 테스트 결과 등이 저장된다.

Gradle Wrapper인 gradlewgraldew.bat은 Gradle을 설치하지 않고도 Gradle 프로젝트를 빌드할 수 있게 해준다.

또한, Wrapper 설정에 따른 일관적인 버전의 Gradle을 사용할 수 있게 해준다.

Spring 프로젝트 생성 시, gradle.properties는 자동으로 생성되지 않는다. 이는 프로젝트에 대한 Gradle 설정파일이므로 필요에 따라 직접 생성해줘야 한다.

빌드 라이프사이클

Gradle의 빌드는 각 Task간의 의존관계에 따라 순차적으로 실행된다.
빌드 스크립트를 작성함으로써 이러한 Task 간의 의존관계를 설정할 수 있다.

Gradle은 Task들을 실행하기 전에 위 이미지처럼 방향성을 지닌 비순환형태의 작업 그래프를 생성한다.


빌드과정은 크게 3가지의 단계로 구분된다.

1. Initialization 단계

  • settings.build 파일 식별
  • Settings 인스턴스를 생성하고, 빌드를 구성하는 프로젝트 결정
  • 모든 프로젝트에 대한 Project 인스턴스 생성

2. Configuration 단계

  • 빌드에 참여하는 모든 프로젝트의 빌드 스크립트(build.gradle) 확인
  • Task 그래프 생성

3. Execution 단계

  • 그래프에 따라 Task들의 실행 순서 결정
  • 병렬적으로 Task 실행

settings.gradle 작성

이 파일에는 빌드과정의 초기화 단계에서 생성되는 Settings 인스턴스에 대한 내용들이 작성된다.
주 목적은 빌드에 참여할 프로젝트 정보들을 관리하는 것이다.

작성 언어에 따라 settings.gradle(Groovy)settings.gradle.kts(Kotlin) 으로 구분된다.
이 파일에 의해 생성되는 Settings 인스턴스에 대한 문서는 이 곳(Groovy)이 곳(Kotlin)에서 확인할 수 있다.

표준 속성들만 살펴보자면, 주로 사용되는 속성 값들은 아래와 같다.

이름설명
buildCache빌드 성능 향상을 위한 빌드 캐시 설정이 작성된다
pluginssettings 에서 사용하는 플러그인들이 작성된다
rootDir빌드의 루트 디렉토리(= 루트 프로젝트의 디렉토리)가 작성된다
rootProject빌드의 루트 프로젝트가 작성된다
settings현재 settings 객체 자체를 의미한다

주로 사용되는 메서드들은 아래와 같다.

이름설명
include()괄호 안의 프로젝트를 빌드에 포함시킬 때 사용된다
includeBuild()복합 빌드에 다른 빌드를 포함시킬 때 사용된다

includeBuild()

독립적으로 빌드가 가능한 프로젝트 A, B가 있다고 가정할 때, A프로젝트가 B프로젝트를 의존하는 상황에서 A프로젝트의 빌드과정에 B프로젝트 빌드과정을 포함시키는 식으로 사용된다.


// 빌드에 대한 플러그인 버전과 저장소 관리
// 프로젝트에서 사용할 플러그인과 저장소에 대한 내용 작성
pluginManagement {  
    repositories {
        gradlePluginPortal()
    }
}

// Settings 객체에만 영향을 끼칠 플러그인 관리
plugins {   
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}

// 루트 프로젝트 이름
rootProject.name = 'simple-project'     

// 프로젝트 전반에 걸친 종속성 관리를 위한 저장소 설정
dependencyResolutionManagement {    
    repositories {
        mavenCentral()
    }
}

// 빌드에 포함될 프로젝트 목록 설정
include("sub-project-a")    
include("sub-project-b")
include("sub-project-c")

settings.gradle 파일의 작성 예시는 위 형태와 같다.

본질적으로 스크립트 항목들은 Gradle API의 설정 객체에서 메서드를 호출한다.

즉, include()는 사실 settings.include()형태로 호출된다.

build.gradle 작성

이 파일에는 빌드과정의 초기화 단계에서 생성되는 Project 인스턴스에 대한 내용들이 작성된다.

settings.gradle처럼 작성 언어에 따라 *.gradle(Groovy)*.gradle.kts(Kotlin) 으로 구분된다.
이 파일에 의해 생성되는 Project 인스턴스에 대한 문서는 이 곳(Groovy)이 곳(Kotlin)에서 확인할 수 있다.

표준 속성들만 살펴보자면, 주로 사용되는 속성 값들은 아래와 같다.

이름타입설명
nameString프로젝트 디렉토리의 명칭이 작성된다
pathString현재 프로젝트 경로가 작성된다
descriptionString현재 프로젝트에 대한 설명이 작성된다
dependenciesDependencyHandler현재 프로젝트의 종속성 핸들러를 반환한다
repositoriesRepositoryHandler현재 프로젝트의 저장소 핸들러를 반환한다
layoutProjectLayout프로젝트의 여러 중요위치에 대한 엑세스를 제공한다
groupObject현재 프로젝트의 그룹이 작성된다( ex: group = 'com.example'
versionObject현재 프로젝트의 버전이 작성된다( ex: `version = '0.0.1-SNAPSHOT')

주로 사용되는 메서드들은 아래와 같다.

이름설명
uri()현재 프로젝트 디렉토리 기준으로 URI 경로에 대한 상태경로를 지정한다
task()주어진 이름의 Task를 생성하고 프로젝트에 추가한다

// Gradle 확장, 또는 프로젝트 구성의 모듈화와 재사용을 위한 플러그인 설정
// 이 예시에서는 현재 프로젝트가 java 애플리케이션임을 의미
plugins {   
    id 'application'
}

// 종속성 다운로드를 위한 저장소 설정
// 이 예시에서는 Maven Central Repository 사용
repositories {  
    mavenCentral()
}

// 프로젝트에 사용될 종속성 목록 설정
// 앞선 repositories에 설정된 저장소에서 이미 컴파일된 클래스 라이브러리를 가져옴
dependencies {  
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    implementation 'com.google.guava:guava:32.1.1-jre'
}

// 앞선 plugins 를 통해 추가된 application 플러그인을 이용해 프로젝트 정보를 설정
application {   
    mainClass = 'com.example.Main'
}

// JUnit5를 이용해 테스트를 실행하도록 지정
tasks.named('test', Test) { 
    useJUnitPlatform()
}

// exclude를 통해 제외한 파일을 제외하도록 javadoc Task 수정
tasks.named('javadoc', Javadoc).configure {
    exclude 'app/Internal*.java'
    exclude 'app/internal/*'
}

// 신규 Task 등록
// from 경로의 모든 파일들을 Reports.zip 으로 압축하고, /dir 경로에 저장
// tasks.create<Zip>("zip-reports") { } 형식으로 작성할 수도 있지만 권장되지 않음
tasks.register('zip-reports', Zip) {
    from 'Reports/'
    include '*'
    archiveFileName = 'Reports.zip'
    destinationDirectory = file('/dir')
}

build.gradle 파일의 작성 예시는 위 형태와 같다. 좀 더 자세한 내용은 Docs 문서를 참고하자.

참고 및 이미지 출처

0개의 댓글