Gradle에 대해 알아보자

김용현·2024년 7월 30일

사이드 프로젝트

목록 보기
6/6

spring 프로젝트를 생성하면서, 필요한 라이브러리 등의 의존성 주입을 위해 종종 build.gradle 파일을 수정하곤 한다.

지금까지 단순히 구글에 돌아다니는 dependency...XXX와 같은 의존성 코드만 복붙했기에, 제대로 된 이해 없이 사용했던 것 같다. 이에 gradle에 대해 정리해보자!

Gradle이란?

gradle 이미지

gradle이란, 빌드 자동화 도구로 오픈소스 프로젝트이다. Groovy 언어 기반의 DSL 언어로 작성된다.

다양한 소프트웨어의 빌드와 컴파일, 테스트 및 패키징까지 개발자가 순수 개발에만 집중할 수 있도록 다양한 기능을 지원한다.

Gradle 동작 과정

Build Lifecycle

빌드 과정은 크게 세가지로 나뉘어진다.

  • 초기화
    빌드하고자 하는 프로젝트를 결정하고 settings.gradle 파일을 참조하여, 멀티 프로젝트인지 여부 파악 후 각각의 프로젝트 객체 생성

  • 구성
    빌드 대상이 되는 모든 프로젝트들의 build.gradle 파일 실행
    이를 통해 프로젝트 객체를 구성한다. (build.gradle 파일 자체가 프로젝트 객체라고 함, configured Task 수행)

  • 실행
    프로젝트 구성 도중 설정된 태스크 중 실행 대상 결정하여 수행

스프링 프로젝트를 생성하면 대략 다음과 같이 초기 프로젝트가 구성되는데, (Module 디렉토리 제외) 간단하게 어떤 파일들인지 알아보자.

  • .gradle
    gradle 버전 별 엔진 및 설정 파일

  • .idea 
    에디터 관련 파일들

  • gradle/wrapper
    사용자가 Gradle을 설치하지 않았어도 Gradle tasks를 실행할 수 있도록 도와준다. (프로젝트 생성자와 사용자가 동일한 버전의 Gradle 사용 가능)

  • gradle-wrapper.jar
    Wrapper 파일로 실행 스크립트가 동작하면 Wrapper에 맞는 환경을 로컬 캐시가 다운로드 받은 뒤 실제 명령에 해당하는 task 실행

  • gradle-wrapper.properties
    Gradle Wrapper 설정 파일

  • gradlew
    Unix용 실행 스크립트 -> 다양한 명령어 사용 시 해당 스크립트로 실행

  • gradlew.bat
    Windows용 실행 스크립트

  • build.gradle
    의존성이나 플러그인 설정 등 프로젝트 빌드에 대한 모든 기능 정의.

  • settings.gradle
    빌드할 프로젝트 정보 설정

파일 별 특징 출처

build.gradle에 대해 알아보자.

gradle 파일은 크게 두가지로 작성될 수 있는데,

  • groovy DSL 사용
  • kotlin DSL 사용

기존에는 groovy DSL을 사용했으나, 최근에는 kotlin DSL을 사용하는 것을 권장한다고 한다. (IDE와의 연결을 통한 코드 자동완성 등의 도움을 받을 수 있음, 실행 전 오류 확인 가능 등)

여기서는 kotlin DSL을 사용하여 gradle 파일들을 작성한다.

본론으로 돌아와서, build.gradle.kts 파일을 보자.

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
	id("org.springframework.boot") apply false
	id("io.spring.dependency-management") apply false
	kotlin("plugin.spring") apply false
	kotlin("jvm")
}

allprojects {
	repositories {
		mavenCentral()
	}

	tasks.withType<JavaCompile> {
		sourceCompatibility = "21"
		targetCompatibility = "21"
	}

	tasks.withType<KotlinCompile> {
		kotlinOptions {
			freeCompilerArgs = listOf("-Xjsr305=strict")
			jvmTarget = "21"
		}
	}

	tasks.withType<Test> {
		useJUnitPlatform()
	}
}

subprojects {
	group = "com.makeeverything"
	version = "0.0.1-SNAPSHOT"

	apply(plugin = "org.springframework.boot")
	apply(plugin = "org.jetbrains.kotlin.plugin.spring")
	apply(plugin = "io.spring.dependency-management")
	apply(plugin = "kotlin")
	apply(plugin = "kotlin-kapt")

	configurations {
		compileOnly {
			extendsFrom(configurations.annotationProcessor.get())
		}
	}

	java {
		toolchain {
			languageVersion = JavaLanguageVersion.of(21)
		}
	}

	dependencies {
		implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
		implementation("org.jetbrains.kotlin:kotlin-reflect")

		testImplementation("org.springframework.boot:spring-boot-starter-test")
		testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
		testRuntimeOnly("org.junit.platform:junit-platform-launcher")
	}
}

현재 사이드 프로젝트의 build.gradle.kts이다.

앞서 build.gradle 파일 자체가 프로젝트 객체라고 했다. 이러한 프로젝트 객체는 수많은 메소드와 프로퍼티를 갖고 있다.

이러한 프로퍼티 값을 정하고, 메소드를 실행하여 프로젝트의 설정을 하는 것인데, 대표적으로 많이 쓰는 것은 plugin, repositories, dependencies, application 등이 있다.

프로퍼티 값은 {} 중괄호 안에 들어가는 값이 프로퍼티로 들어간다. 따라서 위 이미지를 보면 dependiencies {...} 와 같이 되어 있는데,
이는 실제로 dependiencies({...}) 와 같으며 함수의 인자로 넘어간다고 생각하면 된다. (이처럼 중괄호 안의 값들을 groovy에서는 클로저(closure))라고 한다.

참고❗️
build.gradle.kts 파일에서 주로 설정하는 것은 기존에 프로젝트 객체가 갖고 있는 프로퍼티 값들이다.
커스텀 프로퍼티를 정의하기 위해서는 다음과 같이 하면 된다.

// 커스텀 프로퍼티 정의 방법
project.ext.[커스텀 프로퍼티명] = []
project.[커스텀 변수명] // 프로퍼티 접근 방법

지금까지의 이해를 바탕으로 build.gradle.kts 파일에 정의된 내용들 중 대표적인 것들을 살펴보면

plugins

plugins {
	id("org.springframework.boot") apply false
	id("io.spring.dependency-management") apply false
	kotlin("plugin.spring") apply false
	kotlin("jvm")
}

plugin이란 특정 작업을 하기 위해 Task를 모아둔 것을 말한다.
이러한 plugin들은 Google이나 JetBrains 등의 기업에서 사전에 정의해둔 것들을 가져다가 쓰면 된다.

현재 프로젝트에서는 다음과 같이 4개의 plugin을 갖고 있지만, apply false 설정을 통해 적용하지는 않고 있는 것도 보인다.

allProjects

allprojects {
	repositories {
		mavenCentral()
	}

	tasks.withType<JavaCompile> {
		sourceCompatibility = "21"
		targetCompatibility = "21"
	}

	tasks.withType<KotlinCompile> {
		kotlinOptions {
			freeCompilerArgs = listOf("-Xjsr305=strict")
			jvmTarget = "21"
		}
	}

	tasks.withType<Test> {
		useJUnitPlatform()
	}
}

해당 메소드는 프로젝트 수준의 build.gradle.kts와 하위 모듈들의 build.gradle.kts의 정보를 설정한다.

repositories

repositories {
		mavenCentral()
	}

프로젝트에서 사용하는 라이브러리들이 저장된 저장소 위치를 결정하는 함수이다. 대표적으로 mavenCentral(), google(), jcenter() 등이 있다.

subProjects

subprojects {
	group = "com.makeeverything"
	version = "0.0.1-SNAPSHOT"

	apply(plugin = "org.springframework.boot")
	apply(plugin = "org.jetbrains.kotlin.plugin.spring")
	apply(plugin = "io.spring.dependency-management")
	apply(plugin = "kotlin")
	apply(plugin = "kotlin-kapt")

	configurations {
		compileOnly {
			extendsFrom(configurations.annotationProcessor.get())
		}
	}

	java {
		toolchain {
			languageVersion = JavaLanguageVersion.of(21)
		}
	}

	dependencies {
		implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
		implementation("org.jetbrains.kotlin:kotlin-reflect")

		testImplementation("org.springframework.boot:spring-boot-starter-test")
		testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
		testRuntimeOnly("org.junit.platform:junit-platform-launcher")
	}
}

allProjects와 다르게 subProjects는 프로젝트 수준의 루트 모듈 외에 하위 모듈들의 build.gradle.kts 파일을 제어한다.

해당 프로젝트에서는 테스트 코드 관련 라이브러리와 스프링 관련 플러그인들을 정의하였다.

dependencies

dependencies {
		implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
		implementation("org.jetbrains.kotlin:kotlin-reflect")

		testImplementation("org.springframework.boot:spring-boot-starter-test")
		testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
		testRuntimeOnly("org.junit.platform:junit-platform-launcher")
	}

외부 라이브러리 의존성을 명시하는 곳이다. 모듈 별로 필요한 라이브러리 의존성을 주입받아 사용할 수 있다.

profile
평생 여행 다니는게 꿈 💭 👊 😁 🏋️‍♀️ 🦦 🔥

0개의 댓글