초보자를 위한 Gradle 안내서 2편: Gradle 아키텍쳐

커리큘럼

  1. Build툴?, Gradle은 무엇인가?
  2. Gradle 아키텍쳐
  3. Task
  4. 각자의 프로젝트로

이어서..

전편에서는 Build라는게 무엇을 뜻하고 Gradle 설치랑 Gradle wrapper, Gradle의 파일들의 의미에 대해서 봤었다.
(까먹었다면 돌아가세욧!)
이번에는 Gradle의 철학과 아키텍쳐에 대한 내용이다. 겁먹지마요 어렵지 않아요…

Groovy..

앞으로 내용 중간중간에 스크립트가 나올 것인데 Groovy 문법에 모르신다면 여기를 눌러서 문법을 한번 읽어보시는 것을 추천드리고 싶다.

Gradle 아키텍쳐 구조

gradle-architecture
Gradle은 core(본체)와 Plugin으로 나눠져 있다.
갑자기 Plugin? 이라고 생각이 들 수 있지만 사실 Gradle은 빌드툴임에도 빌드 기능은 Core가 아닌 Plugin으로 구현되어 있다
java project의 build.gradle 파일을 열어봤으면 아래와 같이 java를 plugin으로 받는게 보일 것이다.

apply plugin: 'java'

java 역시 Build 기능은 plugin으로 되어있다는 걸 볼 수 있다.

그럼 왜? 이런 구조를 가졌을까?
그건 Gradle이란? 에서 소개했던 Gradle의 철학 때문이다.
거의 모든 유형의 소프트웨어를 빌드 할 수있을 정도로 유연하게 설계된 오픈 소스 빌드 자동화 도구라고 Gradle을 소개했었는데

모든 유형의 소프트웨어 유연하게 빌드하기 위해서는 직접적인 빌드에 관한 것을 코어 빼고 필요한 기능을 Plugin으로 쉽게 가지다 쓰거나 만들 수도 구성을 하였다.
그렇게 함으로써 각각 언어에 맞는 방식의 Build를 지원할 수 있는 것이다.

당연 Plugin통해 규칙과 계층 구조(디렉토리 구조라던지..)를 정의해줌으로 여러 프로젝트를 획일화된 구조도 지원한다.
(이런 생각은 어떻게 하는거지…)

추가로 Plugin을 보다 공유할 수 있도록 Hub도 존재한다.
가서 구경하고 싶다면 여기있다.

Gradle Core

Gradle Core를 본체라고 이야기 했는데 Gradle의 파일 구조에서도 철학을 확인할 수 있다. ~\gradle-6.4.1\lib 폴더를 보면 jar파일들이 있는데 볼 수 있다.

~\gradle-6.4.1\lib\
    plugins\
        Plugin에 관한 Jar 파일
    gradle core에 관한 Jar 파일

걱정안하셔도 됩니다… 버진 6.4.1 기준으로 Core만 91개의 jar파일이 있는데 모두 볼 생각도 여력도 없다.ㅠ
temp forder

Core는 빌드를 하는데 있어서 Lifecycle과 제공되는 API을 몇개 살펴볼 것이다.

빌드 단계(Lifecycle)

project폴더에 gradle init을 했다는 가정으로 다음과 같이 파일들이 구성된다.
(플로그인에 따라 뭔가 더 있을 수는 있다)

project/
    gradlew
    gradlew.bat
    gradle/wrapper/
        gradle-wrapper.jar
        gradle-wrapper.properties
    build.gradle
    settings.gradle

Gradle은 3단계의 빌드 스크립트를 실행한다.

  1. 초기화
  2. 구성
  3. 실행

Project폴더에 단일 프로젝트를 기준으로 설명할 것이다

1. 초기화 (설정 로드)

설정파일은 초기화 단계에서 읽히게 된다. Gradle의 기본 설정파일은 settings.gradle로 루트 프로젝트 위치에 파일이 있어야 한다.
설정 파일은 다중 프로젝트 빌드에 프로젝트 구조를 정의함으로 단일 프로젝트에서 설정 파일은 선택 사항이다.

settings.gradle을 열어보면 다음과 같이 구성되어있다.

rootProject.name = 'project'

단일 프로젝트에서는 rootProject naem만 설정이 된것을 알 수 있다.

이제 settings.gradle 읽고 Settings객체를 만든다
그후 Settings객체를 이용하여 각 프로젝트의 Project인스턴스를 만든다.
SettingsProject를 인스턴스화시키는 것은 알겠는데 project가 뭐지라고 생각되셨다면 정상이다.
(그렇구나 하고 넘어가지 마세요ㅠ)

project interface

공식문서에서는 다음과 같이 정의 되어 있다. 이 인터페이스는 빌드 파일에서 Gradle과 상호 작용하는 데 사용하는 기본 API, Project모든 Gradle 기능에 프로그래밍 방식으로 액세스 할 수 있습니다

공식문서를 가서 다 읽으면 좋지만 귀찮음으로 중요한 내용만 정리하면

  • build.gradle파일과 1:1 관계이다.
  • settings.gradle스크립트가 존재하는 경우

설정파일을 찾는 순서

Gradle은 다음과 같은 순서로 설정 파일을 찾습니다.

  1. master현재 디렉토리와 동일한 중첩 레벨을 가진 디렉토리를 찾기
  2. 아직 찾지 못한 경우 상위 디렉토리를 검색
  3. 그래도 아직 찾지 못하면 빌드는 단일 프로젝트 빌드로 실행 (이레서 단일 프로젝트는 선택사항이라고 했다)

간단하게 멀티 프로젝트를 구성 알아보기

멀티 프로젝트 관한 자세한 내용은 아래 참고에 남겨두었고 멀티 프로젝트는 Gradle에 익숙해지고 나서 고민하여도 괜찮다.

멀티 프로젝트를 구성하고 싶으면 project폴더 안에 module-a, module-b 폴더를 만들고 그 안에 프로젝트를 구성하고 settings.gradleinclude 키워드를 사용해서 추가하면 된다.

rootProject.name = 'project'
include 'module-a', 'module-b'

Gradle은 setting.gradle파일을 보고 다중 프로젝트 계층을 정의 되었으면 다중 프로젝트로 안되어 있으면 단일 프로젝트로 판단하고 빌드한다.

2. 구성

구성단계는 단순하다, 초기화단계에서 생성된 Project객체 그에 연결된 build.gradle가 실행된다. build.gradle에 있는 task를 읽어다가 TaskContainer를 이용해 task의 빈을 생성한 후 Task 그래프를 구성한다.

build.gradle을 다음과 같이 작성하고

// build.gradle file
print "Hello\n"

task testTask {
    print "testTask running\n"

    doLast {
        print "Task do Last\n"
    }
    
    doFirst {
        print "Task do First\n"
    }
}

print "finish Configure\n"

console창에 gradle testTask 명령을 실행하면

// 결과
..\project> .\gradlew testTask

> Configure project :
Hello
testTask running
finish Configure

> Task :testTask
Task do First
Task do Last

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

Task라는 것이 새롭게 등장했는데 Task는 내용이 방대함으로 다음 글에서 자세하게 설명하겠다. 여기서는 그냥 Gradle의 실행단위라고 외워두고 넘어가자

3. 실행

구성에 있는 예제 실행까지 보여줬는데 gradle [task] 명령을 내렸을 때 TaskContainer에서 [task]으로 입력한 테스크랑 같은 이름을 찾아서 실행시켜준다.

정리

초기화는 setting.gradle을 읽어서 Project인스턴스를 생성하고 구성은 build.gradle을 읽어서 Project을 실행하고 실행은 Consolec 명령으로 들어온 task를 찾아서 실행해준다.

참고

comments powered by Disqus