개발 일지

Gradle 이란

북극곰은콜라 2023. 4. 18. 13:51
반응형


Gradle 이란

Groovy 기반의 빌드 툴

 


장점

  • 자유로운 빌드 설정
  • 동적인 빌드 설정 가능
  • 손쉬운 wrapper
  • 빠른 성능
  • (취향) 가독성

 


Build

Life Cycle

  1. 초기화 단계
    1. init.gradle, gradle.properties 환경설정파일을 read
    2. settings.gradle 파일에 포함된 하위 프로젝트(모듈) 설정
  2. 설정 단계
    1. 모든 빌드 스크립트를 평가 및 DAG Create
    2. 실행순서 결정
  3. 시행 단계
    1. 태스크를 차례로 실행

Task

빌드 단계

DAG

Directed Acyclic Graph로 빌드 순서등을 가진 것
예시) java plugin DAG

 


Repositories & dependencies

Repositories

필요할 때 가져와서 쓸 수 있는 라이브러리의 집합
로컬 캐시에 저장됨
기본 디렉터리는 .gradle
// 예시
mavenCentral(), jcenter(), mavenLocal()
maven {
    credentials {
        username 'username'
        password 'password'
    }
    url 'http://xxx.yyy.zzz/abc'
}
flatDir {
    dirs 'lib'
}

Dependencies

사용하는 라이브러리들 명시
라이브러리 그룹, 이름, 버전으로 찾아오며 의존성 설정 가능

문법

전체 문법
  [의존성] group: '[그룹]', name: '[이름]', version: '[버전]'

간이 문법
  [의존성] '[그룹]:[이름]:[버전]'

버전은 1.+ 이런 식으로도 가능 (비추)

라이브러리의 jar만 참조
  전체 : [의존성] group: '[그룹]', name: '[이름]', version: '[버전]' ext: 'jar'
  간이식 : [의존성] '[그룹]:[이름]:[버전]@jar'

전이적 의존성 중 특정 라이브러리 제외 (이미 다른 곳에서 참조하여 받거나 특정 경로로 지정되었을 때)
  compile xxxx:yyy:4.2 {    exclude group: 'aaa.bbb.ccc'      }

compile : 프로젝트 전체에서 사용가능
runtime : 런타임 시에만 사용
testCompile : src/test/java 소스 디렉터리에서만

컴파일 시에만
  compileOnly 'org.projectlombok:lombok'
로컬 파일 시스템 파일 참조
  compile files('libs/a.jar, 'libs/b.jar'')
  compile fileTree(dir: 'libs', includes: ['*.jar'])

전의적 의존성
명시적으로 의존성을 가진 라이브러리가 가진 의존성들 dependencies 문법에 transitive: false로 비활성화 가능 (모든 라이브러리를 다 가지고 있어야 한다....)

 


Gradle Wrapper

Gradle 실행 시 해당 환경에 Gradle 설치 없이 하기 위함
빌드 설계자의 버전에 맞게 빌드 가능

구성

gradle-wrapper.jar : 그레이들 래퍼 jar
gradle-wrapper.properties : 그레이들 래퍼 버전 및 실행환경
gradlew : Unix 계열에서 실행가능한 스크립트
gradlew.bat : 윈도우 계열에서 실행가능한 스크립트

gradle-wrapper.properties

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl : 래퍼의 다운로드 버전이 확인 가능
처음 실행 후 zipStoreBase 아래 zipStorePath 아래 저장되며 이후 캐시로 동작

실행

기본 : 명령창에서 ./gradlew(유닉스) 또는 gradlew.bat 실행(윈도우)
여러 타스크 실행 : ./gradlew clean init

 


Task 설명

// 빌드스크립트(build.gradle)에 외부 라이브러리가 필요할때 쓰는 메서드
// 항상 맨위
// 이 메서드로 추가시 현 스크립트에서 추가된 의존성, 저장소 및 메서드 사용가능
buildscript {
    repositories {
        mavenLocal()
    }
    dependencies {
    }
}
 
....
 
 
// ""은 변수 치환 사용, ''은 사용안함
 
task customTaskA {
    // 다른 task를 참조 (import)
    dependsOn 'customTaskB'
    // 전역변수 export
    ext.customValue = 'CUSTOM VALUE FROM TASK_A'
}
 
task customTaskB {
}
// task에서 실행될 일 추가
customTaskB.doLast {
    println 'add doLast to customTaskB'
}
 
// export된 변수 사용
task customTaskC {
    doLast {
        println customTaskA.customValue
    }
}
 
 
// 기본 타스크 지정
defaultTasks 'clean', 'devBuild'
 
 
// 변수 선언
def buildType = 'normal'
 
task buildProject {
    doLast {
        println '---build project start---'
        println "build type=${buildType}"
        println '---build project end---'
    }
}
 
task devBuild {
    dependsOn 'buildProject'
}
 
task releaseBuild {
    dependsOn 'buildProject'
}
 
// gradle 2단계(설정단계) 진행중 실행되는 메서드
// 등록된 타스크에 따라서 변수에 값 할당
gradle.taskGraph.whenReady {
    taskGrapth ->
        if (taskGrapth.hasTask(":releaseBuild")) {
            buildType = 'release'
            println 'release'
        } else if (taskGrapth.hasTask(":devBuild")) {
            buildType = 'dev'
            println 'dev'
        } else {
            buildType = 'normal'
            println 'normal'
        }
}

 


동작 원리

groovy와 코틀린으로 작성되어 있다.
org.gradle.api의 Project라는 인터페이스를 사용하는 형식

gradle 소스 분석 (v6.7)

Project (Interface)

  • 개요
    • main API이며 build file을 분석할 때 사용된다
    • 해당 인터페이스는 각 프로젝트의 build.gradle와 1:1 관계를 가진다
    • Task Object의 집합으로 구성되어 있다
  • life Cycle
    • Settings 인스턴스를 생성한다 (Settings 인터페이스는 gradle.setting 파일과 1:1 관계, gradle.setting파일로 생성된다고 봐도 무방하다)
    • Settings를 이용해서 프로젝트의 계층구조를 형성한다.
      • 해당 계층구조로 인해서 project가 순차적으로 생성된다.
    • build.gradle 파일을 이용해서 Project 인스턴스를 생성

Task (Interface)

  • 개요
    • 어떠한 작업들을 가진 인터페이스 (ex: 컴파일 클래스, 유닛테스트 실행, WAR로 export 등등)
    • gradle에서 실행가능 작업의 최소단위
    • Action들로 이루어져 있다
    • 기본적으로 TaskContainer에 의해서 생성 관리 된다.
  • build.gradle 파일에서의 Task
    • Dynamic Properties
      • setProperty(String, Object) 메서드를 이용하여 세팅
      • 파일 내에서 해당 프로퍼티의 key 또는 property(String)으로 get 해서 사용
    • Dependency
      • 다른 타스크들과의 의존성 및 순서를 세팅

// 예시 : buildscript 메서드 흐름

buildscript {
    repositories {
        mavenLocal()
    }
    dependencies {
    }
}


/*
Project 인터페이스의 buildscript(Closure configureClosure) 메서드를 실행
Closure 는 groovy의 Closure이다
	property, method등을 세팅 할 수 있으며, 정의된 메서드를 invoke 시킬 수 있는 기능을 가진 추상클래스
Closure가 repositories와 dependencies 메서드를 invoke 시킨다 (ScriptHandler)
ScriptHandler 인터페이스
	repositories(Closure configureClosure)
    	저장소를 설정한다
		사용가능 메서드 : https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/dsl/RepositoryHandler.html
	dependencies(Closure configureClosure)
    	의존성을 설정한다
		dependencies 사용가능 옵션 : https://developer.android.com/studio/build/dependencies?hl=ko
*/

 


REFERENCE

  • gradle 레시피 책
반응형