티스토리 뷰

퍼옴: https://slipp.net/wiki/pages/viewpage.action?pageId=11632748

Gradle 설정 파일 및 기본 개념

Gradle 소개

  • Gradle은 지금까지 자바 진영에서 많이 사용해온 Ant 빌드 툴과 Maven 빌드 툴의 단점은 버리고, 장점을 취한 빌드 툴이다. 따라서 Ant와 Maven 빌드 툴의 기능을 모두 포함하고 있다.
  • Ant의 가장 큰 장점을 들자면 개발자가 자유롭게 빌드 단위(Ant에서는 target이라고 한다.)를 지정하고 빌드 단위 간의 의존 관계를 자유롭게 설정할 수 있다는 것이다. 하지만 자유도가 높다는 것은 잘 활용할 경우 좋은 도구가 될 수 있지만 그렇지 않을 경우 애물단지로 전락할 가능성이 있다는 것이다.
  • Maven의 가장 큰 장점은 Convention Over Configuration 전략에 따라 프로젝트 빌드 과정에 대한 많은 부분이 이미 관례로 정해져 있다는 것이다. 따라서 Maven 기반 프로젝트를 경험한 개발자는 Maven을 기반으로 하고 있는 새로운 프로젝트에서도 쉽게 적응할 수 있다는 것이다. 하지만 관례가 항상 좋은 것은 아니면, 특수한 상황이 발생하는 경우에는 맞지 않는 경우도 종종 발생한다. Maven의 관례에 거부감을 가지는 개발자도 있다.
  • Gradle은 Ant의 자유도와 Maven의 관례의 장점을 모두 흡수했다. 그리고 Ant와 Maven 빌드 툴 모두 가지고 있었던 가장 큰 단점이 XML에 대한 이슈도 Groovy라는 언어를 사용해 해결하고 있다. Ant의 자유도와 Maven의 관례를 어떻게 흡수하고 있는지 앞으로 살펴보도록 하겠다.

Gradle 설정 파일

  • Gradle 기본 설정 파일은 build.gradle이다. settings.gradle 파일이 존재할 경우 settings.gradle 파일까지 빌드에 포함해 실행한다. settings.gradle 파일은 여러 개의 모듈로 분리해 개발하는 경우 유용하게 사용할 수 있다.
  • Gradle에서 속성은 1. Gradle 설치 및 프로젝트 생성에서 확인할 수 있었듯이 gradle.properties 파일에서 관리할 수 있다.
  • build.gradle 이 아닌 다른 빌드 파일을 선택해 실행하는 경우 "gradle -b 설정파일"과 같이 실행한다. 이와 같이 실행할 경우 settings.gradle 은 무시된다.

Gradle Task = Ant의 자유도

gradle task

  • Gradle의 모든 빌드 단위는 task로 정의한다. task는 Ant의 target과 같은 개념이다.
  • Gradle에서는 개발자가 추가하고 싶은 빌드 단위가 있으면 새로운 task를 추가할 수 있다.
build.gradle
task hello {
    doLast {
        println 'Hello world!'
    }
}
  • 위와 같이 task를 추가하고 "gradle hello"를 실행할 수 있다.
  • 위 task는 다음과 같이 간소화해서 정의할 수도 있다.
task hello << {
    println 'Hello world!'
}
  • Gradle은 groovy 언어를 사용하고 있기 때문에 다음과 같이 빌드 스크립트에서 groovy 언어 문법을 직접 사용할 수 있다. groovy 언어 자체는 jvm 위에서 동작하기 때문에 자바 API를 그대로 사용할 수 있다.
task upper << {
    String someString = 'mY_nAmE'
    println "Original: " + someString
    println "Upper case: " + someString.toUpperCase()
}

task dependencies

  • Gradle은 Ant의 target이 서로 간에 의존관계를 가질 수 있었던 것처럼 task 간에 의존 관계를 가질 수 있다.

 

task hello << {
    println 'Hello world!'
}
task intro(dependsOn: hello) << {
    println "I'm Gradle"
}
  • 위 빌드 스크립트를 실행하면 다음과 같은 결과를 얻을 수 있다.
> gradle -q intro
Hello world!
I'm Gradle

이와 같이 Gradle은 프로젝트 요구사항에 따라 새로운 task를 추가할 수 있으며, 각 task간에 의존 관계를 설정함으로써 task의 우선순위를 결정할 수 있다. 이는 Ant 빌드 툴이 가지는 자유도를 모두 흡수할 수 있다는 것이다.

Gradle Task와 관련한 더 자세한 내용은 Chapter 6. Build Script Basics 문서를 참고하기 바란다.

Gradle Plugin = Maven의 관례

Gradle은 참 재밌게도 Ant의 자유도를 주면서도 Maven에서 제공하는 관례를 흡수하고 있다. Ant의 자유도가 좋기는 하지만 프로젝트를 시작할 때마다 매번 같은 task를 추가하고, task간의 의존관계를 설정해야 한다. 하지만 대부분의 프로젝트에서 발생하는 빌드 task와 의존관계는 비슷하다. 예를 들어 자바 프로젝트의 경우 production code compile과 test code compile은 항상 발생하며, test code compile은 production code compile에 의존관계가 생긴다.

이와 같이 프로젝트를 빌드할 때 공통적으로 발생하는 task와 의존관계를 관례로 만들어 제공할 수 있다. Gradle은 이 관례들을 플러그인이라는 개념으로 제공하고 있다. 1. Gradle 설치 및 프로젝트 생성 문서에서 웹 애플리케이션 프로젝트를 생성했을 때 apply plugin: 'jetty'가 자동으로 추가되었다. 이 빌드 스크립트의 의미는 현재 프로젝트에서 jetty 플러그인을 사용하겠다는 의미이다. 즉, jetty 플러그인에서 제공하는 task와 task간의 의존관계를 현재 프로젝트에 포함 시킨다는 내용이다.

1. Gradle 설치 및 프로젝트 생성에서 생성한 프로젝트에서 jetty 플러그인 설정 부분을 주석처리하고 "gradle tasks"를 실행하면 다음과 같은 결과를 얻을 수 있다. 주석은 자바의 주석과 동일하다.

build.gradle
// apply plugin: 'jetty'
 
group = 'net.slipp'
D:\gradle-workspace\slipp>gradle tasks
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Help tasks
----------
dependencies - Displays all dependencies declared in root project 'slipp'.
dependencyInsight - Displays the insight into a specific dependency in root project 'slipp'.
help - Displays a help message
projects - Displays the sub-projects of root project 'slipp'.
properties - Displays the properties of root project 'slipp'.
tasks - Displays the tasks runnable from root project 'slipp' (some of the displayed tasks may belong to subprojects).
 
 
To see all tasks and more detail, run with --all.
 
 
BUILD SUCCESSFUL
 
 
Total time: 2.013 secs
D:\gradle-workspace\slipp>

gradle에서 기본으로 제공하는 tasks는 위와 같이 Help를 지원하는 6개의 task 밖에 없다. 그렇다면 앞에서 주석처리한 apply plugin: 'jetty'에 대한 주석을 제거하고 gradle tasks를 실행해 보면 다음과 같은 결과를 얻을 수 있다.

D:\gradle-workspace\slipp>gradle tasks
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
war - Generates a war archive with all the compiled classes, the web-app content and the libraries.
 
Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.
 
Help tasks
----------
dependencies - Displays all dependencies declared in root project 'slipp'.
dependencyInsight - Displays the insight into a specific dependency in root project 'slipp'.
help - Displays a help message
projects - Displays the sub-projects of root project 'slipp'.
properties - Displays the properties of root project 'slipp'.
tasks - Displays the tasks runnable from root project 'slipp' (some of the displayed tasks may belong to subprojects).
 
Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.
 
Web application tasks
---------------------
jettyRun - Uses your files as and where they are and deploys them to Jetty.
jettyRunWar - Assembles the webapp into a war and deploys it to Jetty.
jettyStop - Stops Jetty.
 
Rules
-----
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
Pattern: clean<TaskName>: Cleans the output files of a task.
 
 
To see all tasks and more detail, run with --all.
 
 
BUILD SUCCESSFUL
 
 
Total time: 2.715 secs
D:\gradle-workspace\slipp>

jetty 플러그인 하나를 추가했지만 위에서 보는 것과 같이 많은 task가 추가된 것을 확인할 수 있다. 그렇다면 이 모든 task가 jetty 플러그인이 포함하는 task인가? 그렇지 않다. Jetty Plugin 문서를 보면 jettyRun, jettyRunWar, jettyStop 3개의 task만 가지고 있는 것을 확인할 수 있다. 그렇다면 나머지 task는 어디에서 온 것인가? 다른 task는 task간의 의존관계에 의해 추가된 task이다. jetty plugin의 task간  의존관계는 다음과 같다.

 


war와 classes task에 대한 의존관계가 있기 때문에 jetty plugin은 war task를 포함하고 있는 War Plugin과 의존관계를 맺고 있다. jetty plugin 소스에서 war plugin과 의존관계를 맺는 부분도 빌드 스크립트에서 apply plugin: 'war'와 같은 방식으로 동작하고 있다. 따라서 war plugin의 모든 task와 의존관계가 jetty plugin으로 전달되는 구조이다. classes task는 Java Plugin에 포함되어 있는 task이기 때문에 java plugin과도 의존관계를 맺어야 한다.

이와 같이 jetty plugin만 적용하더라도 war plugin과 java plugin과의 의존관계도 발생하기 때문에 위 결과와 같이 상당히 많은 task가 추가된다는 것을 알 수 있다.

이와 같이 plugin이 추가되면 task만 추가되는 것이 아니라 task간의 의존관계도 같이 추가된다. 예를 들어 위 task 중에 build task를 실행하면 다음과 같은 결과를 확인할 수 있다.

D:\gradle-workspace\slipp>gradle build
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:war UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build UP-TO-DATE
 
BUILD SUCCESSFUL
 
Total time: 2.193 secs
D:\gradle-workspace\slipp>

위와 같이 빌드를 위해 필요한 모든 부분이 관례를 통해 가능한 상태가 된다. 이는 빌드 스크립트를 만들 때 반복 작업을 줄이고 best practice를 적용하기 위한 좋은 방법이다.


'CI > Maven|Gradle' 카테고리의 다른 글

[퍼옴] Graddle Wrapper 기본 및 사용법  (0) 2017.09.25
[퍼옴] maven 빌드를 gradle 빌드로 변경하기  (0) 2017.07.31
[퍼옴] Gradle 빌드 라이프사이클  (0) 2017.07.31
Maven Scope  (0) 2017.04.05
댓글
공지사항
최근에 올라온 글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함