1.2Gradle
안드로이드 앱 개발의 빌드 자동화 도구, gradle
TL;DR
추억의 쪽지 시험
React Native 프로젝트에서 빼놓을 수 없는 도구는 Gradle이다. 빌드 환경 커스터마이징 및 안드로이드쪽에 네이티브 모듈을 연동해야하는 경우 Gradle을 보다 직접적으로 마주하게 될때가 오곤 한다.
Gradle이란?
Gradle is the open source build system of choice for Java, Android, and Kotlin developers. -공식 문서-
Gradle은 Android 앱 개발의 빌드 자동화 도구이다.

이전 포스팅인 CocoaPods에서도 알아보았지만, 리액트 네이티브 앱은 자바스크립트 코드 외에 각 OS에 필요한 네이티브 코드를 포함하고 있다. Android 쪽에선 Java/Kotlin 코드가 포함되는데, Gradle은 안드로이드 프로젝트에서
- 앱 빌드(컴파일, 패키징, 서명)
- 외부 라이브러리 추가(ex: Firebase, React Native 모듈)
- 빌드 환경 설정(Debug/Release 구분, SDK 버전 지정 등) 을 수행한다.
즉, CocoaPods가 iOS 네이티브 라이브러리의 의존성 관리(Pod 설치)를 담당한다면 Gradle은 Android의 빌드 전체를 담당하고 그 안에 의존성 관리(Maven 패키지의 Dependency)도 포함한다.
Gradle의 동작 원리
리액트 네이티브 프로젝트의 android 폴더 안에는 build.gradle
이 있는데, android 폴더 안의 app 폴더 아래에도 build.gradle
이 있다.
android 폴더에 있는 build.gradle
은 전체 프로젝트 공통 설정에 대한 부분으로, 루트 빌드 스크립트라고도 부른다. 예를 들어 전체 규칙/모든 모듈에서 쓸 저장소(repositories)/플러그인 등에 대한 설정이다.
android/app 폴더의 build.gradle
은 앱 모듈에 대한 구체적 설정으로, 앱 모듈 빌드 스크립트로도 부른다. 앱 모듈에 대한 설정이라는 말은, 실제 앱의 빌드 결과(디버그/릴리즈, APK/AAB 등)에 직접 영향을 주는 요소들에 대한 정보가 포함된다는 의미다. 앱의 applicationId, versionCode, 빌드 타입(debug, release 등), productFlavors, sdk 버전, keystore(서명) 설정, 앱 전용 의존성 등이 포함된다.
단, 과거에는 루트 build.gradle
에서 ext { ... }
블록으로 프로젝트 전역 상수를 선언하곤 했다. 즉, 루트에서 ext { minSdkVersion = 28 ...}
식으로 선언하면, app 모듈에선 android { minSdkVersion rootProject.ext.minSdkVersion}
등으로 가져다 썼다. 이 경우도 "공통 값은 루트에서, 실제 적용은 모듈에서"라는 책임 분리 원칙을 지킨 것으로 볼 수 있다.
./gradlew
버그가 나서 ./gradlew clean
이라는 명령어를 실행하래서 실행한 적이 아주 많다. gradlew
란 Gradle Wrapper의 줄임말로, 프로젝트 안에 포함된 gradlew
라는 스크립트를 실행시켜 해당 프로젝트에 맞는 Gradle 버전을 자동으로 다운로드하고 실행해준다.
clean
은 이전 빌드 산출물을 지우는 동작이다. 구체적으로는 build/
폴더를 삭제해 안에 있는 컴파일된 클래스, 리소스, 캐시 등을 지운다. Android를 빌드할 때 의존성이 충돌하거나 Gradle 캐시가 꼬이는 경우(코드를 수정했는데 이전 산출물이 반영되는 경우)가 잦기 때문에 ./gradlew clean
은 아주 많이 쓰는 명령어다. 물론 실행하려면 android
폴더에 있어야 한다.
clean
이외에도 빌드 시에도 gradlew
를 쓴다. ./gradlew assembleDebug
, ./gradlew bundleRelease
등의 명령어가 그 예다.
Gradle을 통한 빌드 과정
./gradlew assembleDebug
등의 명령어로 빌드를 지시하면 Gradle은 아래와 같이 동작한다.
- 초기화 단계:
settings.gradle
을 읽고 포함된 모듈(app, library등)을 인식한다. - 설정 단계: 각 모듈의
build.gradle
을 읽고 실행하며 태스크 그래프(Task Graph)를 구성한다. 즉,:app:assembleDebug
라는 태스크를 실행하기 위해 어떤 태스크들이 선행되어야 하는지 계산한다. 이 시점에서ext
값(SDK 버전 등)이 평가되고,android {...}
,dependencies {...}
같은 설정이 적용된다. - 실행 단계: 요청된 태스크와 그에 필요한 의존 태스크만 실행한다. 빌드 명령어의 경우 소스 코드 컴파일, 리소스 처리, APK/AAB 생성 등이다.