증분 빌드(Incremental build)는 이미 수행되어 I/O 변경이 없는 Task를 건너뛰는 최적화 기능입니다. 하나의 파일만 수정하고 있다면 다른 모든 파일을 다시 빌드할 필요는 없습니다.
하지만 새로운 브랜치로 전환하거나 개발 환경에 변화가 발생했을 때 이미 빌드한 모든 파일을 처음부터 다시 빌드해야 할 수는 있습니다.
이때 필요한 것이 빌드 캐시(Build cache)입니다.
이 문서에서는 빌드 최적화를 위해 로컬 빌드 캐시(Local build cache)와 원격 빌드 캐시(Remote build cache)를 소개합니다.
이 문서의 시작에 앞서 이 블로그의 문서: 빌드 최적화를 위한 증분 빌드(Incremental build)를 선행해야 합니다.
로컬 빌드 캐시(Local build cache)
이전에 빌드 결과를 로컬에 저장하여 재사용하려면 로컬 빌드 캐싱을 사용합니다.
로컬 빌드 캐시는 default로 off 상태이며 다음과 같이 활성화합니다.
우선 ./gradlew :app:clean :app:build를 실행하여 clean과 build Task를 수행합니다.
$ ./gradlew :app:clean :app:build
> Task :app:clean
> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses
> Task :app:test
> Task :app:check
> Task :app:build
BUILD SUCCESSFUL in 1s
8 actionable tasks: 8 executed
gradle.properties 파일에서 org.gradle.caching=true 프로퍼티를 추가합니다.
org.gradle.console=verbose
org.gradle.caching=true
테스트를 위해서 build Task를 수행하여 로컬 빌드 캐시가 생성되도록 합니다.
$ ./gradlew :app:build
> Task :app:compileJava UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar UP-TO-DATE
> Task :app:startScripts UP-TO-DATE
> Task :app:distTar UP-TO-DATE
> Task :app:distZip UP-TO-DATE
> Task :app:assemble UP-TO-DATE
> Task :app:compileTestJava UP-TO-DATE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test UP-TO-DATE
> Task :app:check UP-TO-DATE
> Task :app:build UP-TO-DATE
BUILD SUCCESSFUL in 409ms
7 actionable tasks: 7 up-to-date
Incremental build 덕분에 Task 실행이 최적화된 것을 알 수 있습니다.
빌드는 최적화되었으나 백그라운드에서는 로컬 빌드 캐시가 생성됩니다.
다시 한 번 clean과 build Task를 수행합니다.
./gradlew :app:clean :app:build
> Task :app:clean
> Task :app:compileJava FROM-CACHE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava FROM-CACHE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test FROM-CACHE
> Task :app:check UP-TO-DATE
> Task :app:build
BUILD SUCCESSFUL in 525ms
8 actionable tasks: 5 executed, 3 from cache
코드 | 비고 | |
build Task를 수행하여 Task의 I/O를 로컬 빌드 캐시로 생성하였습니다. 그리고 clean Task를 수행하여 브랜치가 스위칭되는 것을 모킹합니다.
다시 build Task를 수행하여 로컬 빌드 캐시가 활용되는 것을 확인하였습니다.
브랜치가 스위칭 되었을 때 Incremental build와 달리 로컬 빌드 캐시가 빌드를 최적화하고 있습니다.
Gradle은 이미 존재할 수 있는 Task의 출력(Output) 파일을 확인하기 위해서 시스템이 위치한 캐시 디렉토리를 찾습니다.
로컬에서 캐싱되면 Gradle은 Task의 출력 파일을 빌드 디렉토리로 복사합니다.
따라서 레이블 FROM-CACHE는 Gradle이 Task의 출력 파일을 복사하여 처리하였음을 의미합니다.
Gradle의 로컬 빌드 캐시 디렉토리는 다음 경로에 위치합니다.
macOS 또는 Linux 환경에서 | Windows 환경에서 | |
~/.gradle/caches | %USERPROFILE%\.gradle\caches |
Gradle은 디스크 공간을 절약하기 위해서 로컬 빌드 캐시 디렉토리에서 최근 사용되지 않은 항목을 주기적으로 삭제합니다.
원격 빌드 캐시(Remote build cache)
Gradle은 빌드 최적화 과정에서 여러 개발자가 함께 공유하는 원격 빌드 캐시에서 캐싱 할 수 있습니다.
만약 로컬 빌드 캐시와 원격 빌드 캐시가 모두 활성화되어 있다면 Gradle은 로컬에서 먼저 캐싱합니다.
로컬에서 캐싱하지 못한 경우에는 원격에서 캐싱합니다. 원격 캐싱이 히트한 경우 로컬에도 출력 파일을 저장해 다음번에는 로컬에서 캐싱됩니다.
원격 빌드 캐시를 사용하여 팀 단위의 업무에서 빌드 시간을 단축하고 통일성을 갖을 수 있습니다.
Gradle은 단일로 구성된 원격 빌드 캐시 노드를 Docker 이미지로 무료 제공합니다.
Production 환경에서 원격 빌드 캐시를 사용하려면 Gradle Enterprise를 사용을 권장합니다.
정리 및 복습
- Gradle이 제공하는 빌드 최적화로
로컬 빌드 캐시(Local build cache)와원격 빌드 캐시(Remote build cache)가 있습니다. - 업무 브랜치가 스위칭되거나 환경에 변화가 생기면
Incremental build만으로는 빌드 최적화가 어려울 수 있습니다. - 로컬 빌드 캐시는 시스템의 캐시 디렉토리에
출력(Output) 파일을 저장하고 빌드에서 재활용합니다. - 캐시 디렉토리 경로는 OS 환경마다 차이가 있습니다.
macOS 또는 Linux 환경에서 | Windows 환경에서 |
~/.gradle/caches | %USERPROFILE%\.gradle\caches |
- 로컬 빌드 캐시를 활성화 하려면
gradle.properties파일에서org.gradle.caching=true프로퍼티를 추가합니다. - 로컬 빌드 캐시와 원격 빌드 캐시가 모두 활성화되어 있는 경우
로컬에서 먼저 탐색합니다. 원격에서 탐색된 경우 로컬에도 출력 파일을 저장하여 다음번에는 로컬에서 탐색 될 수 있도록 합니다.
'Build > Gradle' 카테고리의 다른 글
Gradle 도큐먼트: 시스템 프로퍼티(System properties)를 사용한 빌드 환경 구성 (0) | 2023.11.17 |
---|---|
"Cannot add task 'wrapper' as a task with that name already exists" 오류 (0) | 2023.11.17 |
Gradle 도큐먼트: 빌드 최적화를 위한 증분 빌드(Incremental build) (0) | 2023.11.16 |
Gradle 도큐먼트: Gradle 플러그인(Plugins) 적용하기 (0) | 2023.11.15 |
Gradle 도큐먼트: 의존성(Dependencies) 관리 (0) | 2023.11.15 |