Kotlin과 Android Gradle Plugin의 불협화음
가장 대표적인 원인은 Kotlin과 Android Gradle Plugin(AGP)의 버전 불일치다. 안드로이드 생태계에서는 AGP와 Kotlin이 거의 동반 진화한다. AGP가 새로 나오면 대체로 더 높은 버전의 Kotlin이 요구되는데, 프로젝트에서 특정 버전을 강제로 고정하면 라이브러리에서 요구하는 버전과 충돌을 일으킨다. 이번 사례처럼 DataBinding 라이브러리가 Kotlin 2.2 기반으로 빌드되었는데 프로젝트는 Kotlin 1.9를 쓰고 있었다면, 결국 빌드 오류가 발생한다.
이 문제의 본질은 라이브러리 메타데이터와 프로젝트의 Kotlin 컴파일러가 서로 호환되지 않는 데 있다. 빌드 시스템은 이를 엄격하게 검사하기 때문에, 하위 호환성을 기대하는 건 위험하다. 따라서 항상 AGP 릴리스 노트와 Kotlin 호환성을 확인하며 업그레이드를 진행해야 한다.
리소스 파이프라인의 민감함
안드로이드 빌드에서 또 다른 흔한 걸림돌은 리소스 처리다. AAPT2(Resource Compiler)는 리소스 파일의 형식과 규칙을 매우 엄격하게 검증한다. 예를 들어 PNG 확장자를 가진 이미지가 실제로는 JPEG라면, 빌드는 실패한다. 표면적으로는 단순한 파일 확장자 문제지만, 실제로는 안드로이드의 리소스 빌드가 “확정적이고 재현 가능한 변환”을 요구하기 때문에 형식 불일치가 허용되지 않는 것이다.
이처럼 리소스 빌드 오류는 개발자의 실수라기보다 툴체인 설계상의 특징이라고 보는 편이 더 정확하다. 결국 개발자는 리소스 관리에서조차도 철저한 규칙 준수를 강제받는다.
실행 환경과 IDE의 변덕
빌드가 성공했더라도 안드로이드 스튜디오에서 실행 버튼이 회색으로 비활성화되는 경우도 흔하다. 이는 프로젝트가 Application 모듈로 인식되지 않거나, 런처 액티비티가 설정되지 않았을 때 발생한다. IDE 캐시가 꼬였을 때도 비슷한 증상이 나타난다. 결국 안드로이드 개발에서는 IDE 자체가 또 다른 변수가 된다.
“재현 가능한 빌드”의 필요성
이러한 문제들이 시사하는 바는 명확하다. 안드로이드 빌드는 단순히 소스 코드를 컴파일하는 과정이 아니라,
- Gradle, AGP, Kotlin 버전의 조율
- 외부 라이브러리 의존성 관리
- 리소스 형식 검증
- IDE와의 연계
이 모든 요소가 맞아떨어져야만 성공할 수 있다. 따라서 기업 프로젝트에서는 dependency-locking이나 버전 카탈로그(libs.versions.toml) 를 통해 빌드 환경을 고정하는 것이 필수적이다. 이는 “어제 빌드되던 것이 오늘 빌드되지 않는” 상황을 막는 가장 효과적인 방법이다.
결론
안드로이드 빌드 파이프라인은 거대하고 복잡하며, 사소한 차이에도 쉽게 깨진다. 그러나 이는 단점만은 아니다. 오히려 이러한 엄격함 덕분에 플랫폼 전반에서 일관된 결과물이 보장된다. 결국 개발자의 역할은 빠르게 변하는 생태계와 빌드 도구의 특성을 이해하고, 프로젝트 환경을 안정적으로 관리하는 전략을 세우는 것이다.
안드로이드 빌드가 어렵다고 느껴지는 것은 자연스럽다. 이는 개인의 실력이 부족해서가 아니라, 시스템이 본질적으로 복잡하기 때문이다. 따라서 가장 현명한 태도는 “모든 변수를 통제 가능한 상태로 두는 것”이다. 이것이야말로 불필요한 삽질을 줄이고, 안정적인 개발 환경을 유지하는 유일한 길이다.
답글 남기기