자바 세계의 빌드 시스템은 시기에 맞추어 다른 도구가 주목을 받았습니다. 처음에는 확장성이 강력한 아파치 앤트, Apache Ant가 주목을 받았습니다. 설정이 편하고 중앙 저장소를 가진 아파치 메이븐, Apache Maven이 다음 타자였습니다. 사람들은 강력하지만 설정하기 어려운 앤트와 편리하지만 커스터마이징하기 어려운 메이븐 사이에서 아쉬움을 느꼈고 절충된 해법을 찾기를 원했습니다. 아파치는 2004년 대안으로 아파치 아이비, Apache Ivy를 선보였으나 시장의 반응은 좋지 않았습니다. 그 후로 3년 뒤 우리는 그래들, Gradle을 만나게 됩니다. 그래들은 그루비 언어를 기반으로 쉽게 설정할 수 있으며 다양한 기능을 추가할 수 있었고 자바 세상의 주류로 편입하게 됩니다.
안드로이드가 처음 등장했을 때 안드로이드의 주요 빌드 시스템은 아파치 앤트였습니다. 이 당시에는 IDE 환경도 안드로이드 스튜디오를 쓰는 지금과는 달리 이클립스 기반의 안드로이드 개발 툴, Android Development Tool을 사용했습니다. 이후 자바 세계의 변화에 맞추어서 안드로이드 빌드에서 메이븐을 여러 안드로이드 커뮤니티에서 실험하기 시작했고 나중에 구글이 공식 빌드 시스템을 그래들 기반으로 변경하였습니다.
<그림 1> 일반적인 안드로이드 빌드 구성
처음으로 주목할 부분은 build.gradle
파일이 두 곳에 있다는 점입니다. 먼저 루트에 build.gradle
에 있는데 app
디렉토리에도 build.gradle
파일이 있습니다.
- 프로젝트 빌드 설정 파일 -
build.gradle
app
모듈용 빌드 설정 파일 -app/build.gradle
프로젝트 내에는 하나 이상의 모듈이 포함되게 되고 모듈 마다 별도의 빌드 설정 파일이 존재합니다. 여기에서는 app
모듈만 존재하기 때문에 app/build.gradle
파일이 존재합니다. 만약 모듈이 여럿이라면 빌드 설정 파일도 추가로 해당 디렉토리에 위치합니다.
어떤 모듈이 있는지는 settings.gradle
파일에 정의합니다. 해당 파일의 내용을 살펴봅시다.
include ':app'
이 설정은 app
모듈이 포함시킵니다. 포함할 모듈명 앞에는 세미콜론(:
)이 들어갑니다.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
buildscript()는 외부 라이브러리를 포함할 때 사용합니다.
dependencies()
의 classpath
에서 우리가 사용할 라이브러리를 지정합니다.
classpath 'com.android.tools.build:gradle:2.2.3'
사용할 라이브러리는 com.android.tools.build:gradle
이고 버전은 2.2.3
입니다. 버전명이 분명하지 않다면 2.+
등으로 +
를 사용하여 지정할 수 있습니다. +
부터는 가장 높은 숫자로 지정됩니다.
repositories
는 classpath
를 불러올 저장소를 지정합니다. jcenter()
는 jcenter 저장소를 사용하겠다는 의미입니다. 예전에는 메이븐의 저장소를 쓰기 위해 mavenCentral()
를 사용하였지만 캐쉬나 여러 정책에서 뛰어난 jcenter로 옮겨가는 추세입니다.
allprojects {
repositories {
jcenter()
}
}
allprojects
는 현재 프로젝트와 서브 프로젝트에서도 이 설정을 모두 사용하겠다는 의미입니다. 모듈 app
에서도 jcenter 저장소를 사용하기 위해 allprojects
설정을 하였습니다.
이제 app/build.gradle
을 살펴봅시다.
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "example.io.realm.testapplication"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
testCompile 'junit:junit:4.12'
}
먼저 최상위의 apply plugin: 'com.android.application'
가 있습니다. 이는 com.android.application
플러그인을 사용하겠다는 의미입니다. 이는 루트 빌드 스크립트에서 classpath
로 지정한 com.android.tools.build:gradle:2.2.3
에 존재하는 플러그인입니다. 이 플러그인으로 인해서 실제 안드로이드 빌드 과정을 그래들이 이해하고 우리의 프로젝트를 빌드하는 것입니다.
다음으로 참고할 것은 dependencies
블록입니다.
여기에는 compile
, androidTestCompile
, testCompile
이 세가지 위치합니다.
compile
- 일반 앱 빌드를 위한 라이브러리 지정.androidTestCompile
- 안드로이드 빌드(에스프레소)등을 사용한 테스트에 사용하는 라이브러리.testCompile
- 유닛 테스트에 사용할 라이브러리.
compile
에서는 jcenter에 있는 라이브러리를 com.android.support:appcompat-v7:25.1.0
를 통해 지정하였지만 fileTree
를 통해 로컬 파일을 빌드 과정에 포함시킬 수 있습니다.
마지막으로 가장 중요한 android
블록을 살펴봅시다. 여기에서는 몇가지 내용만 살펴보겠습니다.
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "example.io.realm.testapplication"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
`versionName` "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
compileSdkVersion
- 빌드에 사용할 SDK 버전입니다. 현재 안드로이드 7.1 버전이 25로 지정되어 있습니다.buildToolsVersion
- 안드로이드 앱 빌드에 사용할 빌드 툴의 버전입니다. 계속 업데이트됩니다.applicationId
- 애플리케이션의 아이디로 대개 패키지 이름과 동일하게 사용합니다.minSdkVersion
- 이 앱이 사용될 최소 SDK 버전입니다.targetSdkVersion
- 목표 SDK 버전으로 이 앱에서 사용할 클래스 등이 결정됩니다. 앱은 단말기의 SDK 버전이minSdkVersion
보다 높으면 수행할 수 있습니다. 앱에서는targetSdkVersion
이하의 기능들을 사용하게 됩니다. 단말의 SDK 버전에 따라targetSdkVersion
의 기능을 이용할 수 없기 때문에 실행 시간에 단말의 버전을 확인하여 기능의 사용여부를 결정하여야 합니다.versionCode
- 앱의 버전입니다. 1부터 시작해서 차례대로 증가하여 사용합니다. 이 숫자는 줄어들 수 없습니다.versionName
- 사용자에게 보기 좋게 표현되는 버전입니다.
buildTypes
내에는 release
와 debug
등의 블록이 위치할 수 있습니다. 이는 어떻게 빌드하느냐 따라 다른 블록이 호출되게 됩니다.
minifyEnabled
- 이 옵션이 활성화되면 프로가드가 호출이 되어 앱을 난독화하고 코드의 양을 줄이게 됩니다.proguardFiles
- 프로가드 과정에 사용할 설정들이 위치한 곳입니다.
- 빌드 구성 - 조금 더 자세한 빌드 구성에 대해 확인하세요.
- Android Plugin DSL Reference - 구체적인 설정을 확인하세요.