Skip to content

Instantly share code, notes, and snippets.

@dalinaum
Last active June 1, 2021 13:02
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dalinaum/b1b14a8b8bfe3422f79f529e13c91ac7 to your computer and use it in GitHub Desktop.
Save dalinaum/b1b14a8b8bfe3422f79f529e13c91ac7 to your computer and use it in GitHub Desktop.
안드로이드 빌드 시스템

안드로이드 빌드 시스템

자바 세계의 빌드 시스템은 시기에 맞추어 다른 도구가 주목을 받았습니다. 처음에는 확장성이 강력한 아파치 앤트, Apache Ant가 주목을 받았습니다. 설정이 편하고 중앙 저장소를 가진 아파치 메이븐, Apache Maven이 다음 타자였습니다. 사람들은 강력하지만 설정하기 어려운 앤트와 편리하지만 커스터마이징하기 어려운 메이븐 사이에서 아쉬움을 느꼈고 절충된 해법을 찾기를 원했습니다. 아파치는 2004년 대안으로 아파치 아이비, Apache Ivy를 선보였으나 시장의 반응은 좋지 않았습니다. 그 후로 3년 뒤 우리는 그래들, Gradle을 만나게 됩니다. 그래들은 그루비 언어를 기반으로 쉽게 설정할 수 있으며 다양한 기능을 추가할 수 있었고 자바 세상의 주류로 편입하게 됩니다.

안드로이드가 처음 등장했을 때 안드로이드의 주요 빌드 시스템은 아파치 앤트였습니다. 이 당시에는 IDE 환경도 안드로이드 스튜디오를 쓰는 지금과는 달리 이클립스 기반의 안드로이드 개발 툴, Android Development Tool을 사용했습니다. 이후 자바 세계의 변화에 맞추어서 안드로이드 빌드에서 메이븐을 여러 안드로이드 커뮤니티에서 실험하기 시작했고 나중에 구글이 공식 빌드 시스템을 그래들 기반으로 변경하였습니다.

기본 빌드 시스템의 파일 구성

일반적인 안드로이드 빌드 구성

<그림 1> 일반적인 안드로이드 빌드 구성

처음으로 주목할 부분은 build.gradle 파일이 두 곳에 있다는 점입니다. 먼저 루트에 build.gradle에 있는데 app 디렉토리에도 build.gradle 파일이 있습니다.

  1. 프로젝트 빌드 설정 파일 - build.gradle
  2. 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.+등으로 +를 사용하여 지정할 수 있습니다. + 부터는 가장 높은 숫자로 지정됩니다.

repositoriesclasspath를 불러올 저장소를 지정합니다. jcenter()는 jcenter 저장소를 사용하겠다는 의미입니다. 예전에는 메이븐의 저장소를 쓰기 위해 mavenCentral()를 사용하였지만 캐쉬나 여러 정책에서 뛰어난 jcenter로 옮겨가는 추세입니다.

allprojects {
    repositories {
        jcenter()
    }
}

allprojects는 현재 프로젝트와 서브 프로젝트에서도 이 설정을 모두 사용하겠다는 의미입니다. 모듈 app에서도 jcenter 저장소를 사용하기 위해 allprojects 설정을 하였습니다.

app 모듈 빌드 스크립트

이제 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이 세가지 위치합니다.

  1. compile - 일반 앱 빌드를 위한 라이브러리 지정.
  2. androidTestCompile - 안드로이드 빌드(에스프레소)등을 사용한 테스트에 사용하는 라이브러리.
  3. 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'
        }
    }
}
  1. compileSdkVersion - 빌드에 사용할 SDK 버전입니다. 현재 안드로이드 7.1 버전이 25로 지정되어 있습니다.
  2. buildToolsVersion - 안드로이드 앱 빌드에 사용할 빌드 툴의 버전입니다. 계속 업데이트됩니다.
  3. applicationId - 애플리케이션의 아이디로 대개 패키지 이름과 동일하게 사용합니다.
  4. minSdkVersion - 이 앱이 사용될 최소 SDK 버전입니다.
  5. targetSdkVersion - 목표 SDK 버전으로 이 앱에서 사용할 클래스 등이 결정됩니다. 앱은 단말기의 SDK 버전이 minSdkVersion 보다 높으면 수행할 수 있습니다. 앱에서는 targetSdkVersion 이하의 기능들을 사용하게 됩니다. 단말의 SDK 버전에 따라 targetSdkVersion의 기능을 이용할 수 없기 때문에 실행 시간에 단말의 버전을 확인하여 기능의 사용여부를 결정하여야 합니다.
  6. versionCode - 앱의 버전입니다. 1부터 시작해서 차례대로 증가하여 사용합니다. 이 숫자는 줄어들 수 없습니다.
  7. versionName - 사용자에게 보기 좋게 표현되는 버전입니다.

buildTypes 내에는 releasedebug등의 블록이 위치할 수 있습니다. 이는 어떻게 빌드하느냐 따라 다른 블록이 호출되게 됩니다.

  1. minifyEnabled - 이 옵션이 활성화되면 프로가드가 호출이 되어 앱을 난독화하고 코드의 양을 줄이게 됩니다.
  2. proguardFiles - 프로가드 과정에 사용할 설정들이 위치한 곳입니다.

참고

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment