둘을 조사 하기 전에 gradle은 들어보고 어느 정도 사용 해 본 경험이 있다. 바로 안드로이드 스튜디오에서!
모바일 프로그래밍을 배우는 수업 시간에 gradle 파일에 라이브러리를 추가하기도 하고 binding(ui의 동작을 가져오는 함수)을 키거나 끄기도 하는 등 해당 액티비티의 설정? 같은 것을 만졌던 기억이 난다.
일단 설명 하기 전에 먼저 말하자면 둘 다 빌드 관리 도구에 속한다.
이번 글에서는 빌드 관리 도구란 무엇인지, maven과 gradle 전에는 무엇이 있었는지, 두 도구의 개념과 차이는 무엇인지 설명하고자 한다.
빌드 관리 도구는 빌드를 통한 어플래케이션 생성을 자동화 하기 위한 도구이다.
즉, 소프트웨어 개발에 있어 소스코드를 실행 가능한 애플리케이션으로 만들어주는 도구이며 이런 빌드 과정을 자동화, 간편화하여 관리하기 때문에 빌드 관리 도구 또는 빌드 자동화 도구라고 불린다.
즉 빌드 관리 도구는 빌드를 더욱 쉽게 하기 위해 만들어진 것이다.
maven과 gradle은 아래에서 설명할 것이므로 간략히 적는다.
Target(대상), Dpendency(의존성), Recipe(명령어)로 구성되어있다.
예시.
$(TARGET) : $(OBJS)
$(CC) -o $(TARGET) $(OBJS)
크로스 플랫폼에 대응해 범용성을 높였다.
Make를 java에 적용할 때 생긴 문제를 보완하기 위해 탄생했다.
Java + XML을 도입했다.
예시.
<project name="프로젝트이름" default="기본타겟이름" basedir="." > <!--빌드파일의 루트태그.-->
<target name="타겟이름"> <!--실제 프로젝트가 수행할 작업(Task지정) -->
<property name="프로퍼티이름1" value="프로퍼티값1"/>
<property name="프로퍼티이름2" value="프로퍼티값2"/>
</target>
<target name="타겟이름1">
<태스크명/>
<태스크명1 dir="${build}"/>
<property name="프로퍼티이름3" value="프로퍼티값3"/>
</target>
<target name="타겟이름2" depends="타겟이름1">
<태스크명2 속성1="값1" 속성2="값2"/> <!--타겟 내에서 실제로 수행할 작업 -->
</target>
</project>
출처: https://cheershennah.tistory.com/192 [Today I Learned. @cheers_hena 치얼스헤나:티스토리]
위의 역사를 보면 알 수 있듯 Maven은 Ant 빌드도구를 개선하기 위해 나온 것이다. 이를 유념하고 조사를 시작해본다.
복제, 배포, 수정의 권한 허용 | 가능 |
---|---|
배포시 라이선스 사본 첨부 | 가능 |
저작권 고지사항 또는 Attribution 고지사항 유지 | 가능 |
배포시 소스코드 제공의무(Reciprocity)와 범위 | 명시되어있지않음 |
조합저작물(Lager Work) 작성 및 타 라이선스 배포 허용 | 가능 |
수정 시 수정내용 고지 | 명시되어있지않음 |
명시적 특허 라이선스의 허용 | 가능 |
라이선시가 특허소송 제기 시 라이선스 종료 | 명시되어있지않음 |
이름, 상표, 상호에 대한 사용제한 | 가능 |
보증의 부인 | 가능 |
책임의 제한 | 가능 |
개념에서 알 수 있듯 Java의 Lifecycle 관리 도구이며 정해진 Lifecycle이 존재하고 이에 의해 작업을 수행하며 전반적인 프로젝트를 관리한다.
라이프사이클
clean - validate - compile - test - package - verify - install - site - deploy 순서의 사이클을 가진다. 이때 각 단계를 Phase(페이즈)라고 한다.
위의 사이클 외에도 다양한 사이클이 있으며 크게 Clean, Build, Site로 나눈다. 각 단계를 모두 수행하는 것이 아니라 원하는 부분까지만 할 수도 있다. 특히 test 단계는 프로젝트 규모에 따라 오랜 시간이 걸릴 수 있으니 스킵이 가능하도록 되어있다.
Maven은 필요한 라이브러리를 pom.xml 파일에 저장한다.
역사의 순서에서 알 수 있듯 gradle은 maven의 강점을 계승하면서 단점을 보완하려는 시도로 만들어졌다. 따라서 gradle은 유연성과 성능 향상을 목표로 개발 되었다.
Gradel의 구조는 위의 사진과 같다.
build.gradle은 파일 자체가 Project Object이다. 이는 프로젝트 단위에서 필요한 작업을 수행하기 위해 모든 메서드와 속성을 모아둔 객체이다.
이때 대표적인 것엔 plugins, repogitories, dependencies, application 등이 있다.
// 프로젝트에서 사용하는 Gradle 플러그인 설정
plugins {
id 'java'
..
}
// 프로젝트 생성 시 GroupId, Application 버전, Java 버전
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
// 필요한 라이브러리를 다운로드할 저장소 설정
// 공개 저장소(jcenter)와 Apache Maven 중앙 저장소(mavenCentral) 이용
repositories {
mavenCentral()
}
// 의존 라이브러리 설정
dependencies {
// compile, api: 의존 라이브러리 수정시 본 모듈을 의존하는 모듈들도 모두 재빌드 (api로 사용을 권장)
// A(api) <- B <- C 로 의존하는 구조라면, A 수정 시 B,C 모두 빌드
// implementation: 의존 라이브러리 수정시, 해당 모듈을 직접 의존하는 모듈만 빌드 (비교적 빠름)
// A(implementation) <- B <- C 로 의존하는 구조라면, A 수정 시 B 만 빌드
// compileOnly: 컴파일시에만 의존하고, 빌드 결과물에는 포함하지 않음 (runtime시 필요없는 라이브러리)
// runtimeOnly: runtime 시에만 필요한 라이브러리
// testCompile: test에서만 적용되는 compile 속성
// testImplementation: test에서만 적용되는 implementation 속성
// testCompileOnly: test에서만 적용되는 compileOnly 속성
// testRuntimeOnly: test에서만 적용되는 runtimeOnly 속성
// annotationProcessor: 어노테이션 기반 라이브러리를 컴파일러가 인식하도록 함 (lombok, queryDSL 등)
..
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Maven | Gradle | |
---|---|---|
1. 빌드 스크립트 언어 | XML | Groovy/Kotlin DSL |
2. 확장성 | 준수 | 더 좋음 |
3. 성능 | 느림 | 빠름 |
4. 컨벤션 오버 구성 | 강조, 사전 정의 | 더 유연, 자유롭게 정의 |
5. 학습 곡선 | 초기 설정 간단, 낮음 | 초기 설정 및 고급 기능 사용에 있어 높음 |
xml 보다 groovy가 더 유연하고 가독성이 좋다.
gradle의 특징에서 봤듯 10배 이상의 성능 차이가 있다. 이는 gradle의 캐싱, 병렬처리 등에 요인이 있다.
Maven은 이미 있는 플러그인들로 확장이 가능. gradle은 사용자 정의 플러그인 작성이 더욱 쉬워 플러그인 생태계가 더 풍부하다.
표와 같이 차이가 있고 각 장단점이 있지만 유연한 것이 실제 적용하기에 더 수월한 면이 있다.
이러한 점들을 고려해 Maven와 gradle을 선택 가능하다. 하지만 결국 나는 이제 개발자를 준비하는 과정 중이고 gradle은 가장 최신에 나온 tool이므로 어떤 것을 공부해야 하는가를 물어본다면 gradle이라고 할 수 있을 듯 하다.