본문 바로가기
Android/Compose 숨참고 Deep dive

Compose 컴파일러 Part 1 : A Kotlin compiler plugin

by DONXUX 2023. 3. 21.

Compose 컴파일러는 Kotlin 컴파일러 플러그인입니다.

Compose Architecture

Compose를 사용해보신 분이라면 Kotlin 함수에 @Composable 어노테이션을 붙인 함수는 Composable 함수로 변환되는 것은 알고 계실겁니다.

보통, 코틀린에서 어노테이션 처리는 kapt이나 ksp 의해 이루어집니다. 하지만 Compose는 일반적인 어노테이션 프로세서로 처리하지 않습니다. Compose 컴파일러는 코틀린 컴파일러의 플러그인입니다. 자바로 Compose를 사용할 수 없는 이유이기도 합니다.

안드로이드 공식문서의 설명

우선 kapt 작동 방식을 생각해봅시다. 코틀린에는 자체적으로 어노테이션 프로세싱을 지원하지 않기 때문에, 자바의 어노테이션 프로세서를 이용해야하고, 그걸 이루는 것이 kapt이죠. 덕분에 자바 Stub이 생성되고, 절차가 늘어나기 때문에 컴파일 시간이 길어지게됩니다.

 

반면, Compose 컴파일러가 코틀린 컴파일러의 플러그인이어서 얻을 수 있는 이점은 다음과 같습니다.

  • Compose 컴파일 과정이 코틀린 컴파일 과정에 임베드되어 내부적인 정보까지 깊게 액세스 할 수 있으며, 이는 전체 프로세스 속도를 높일 수 있습니다.
  • Compose 컴파일러의 프론트엔드 단계에서 경고 및 오류를 보고가 가능합니다. 즉, 정적 분석을 수행하여 개발자는 실제로 빌드하지 않고도 코딩하는 동안 실시간으로 피드백 받을 수 있습니다.
  • IR(Intermediate Representation)을 조정함으로써 (새 코드를 추가하는 것뿐만 아니라) 소스 코드를 자유롭게 조작할 수 있습니다(코틀린은 멀티플랫폼을 지원합니다). 이는 Compose 컴파일러가 Composable 함수를 런타임에서 지원할 수 있도록 변환하는 능력을 제공합니다.
IR(Intermediate Representation)?
코틀린 컴파일러는 크게 프론트엔드 컴파일러와 백엔드 컴파일러 두개로 나뉩니다. 프론트엔드에서는 코드 분석을 수행하고 백엔드에서는 실행 파일을 생성합니다. 프론트엔드에서 코드 분석 후 출력하는 산출물이 IR입니다. VM의 바이트코드와 유사한 기능을 한다고 생각하면됩니다. 이러한 IR을 각 대상 플랫폼에 맞게 컴파일을 해야하는데, 이러한 역할을 해주는 것이 백엔드 컴파일러입니다. 각 플랫폼(JS, JVM, Native)의 백엔드 컴파일러 존재합니다. 그래서 멀티플랫폼 컴파일러 확장을 더욱 쉽게 구현할 수 있다는 장점이 있습니다.
코틀린 컴파일 과정

References

  1. Jorge Castillo, Andrei Shikov. 『Jetpack Compose internals』, 2021
  2. https://blog.jetbrains.com/kotlin/2021/02/the-jvm-backend-is-in-beta-let-s-make-it-stable-together/
  3. https://stackoverflow.com/questions/68045875/for-what-purpose-is-useir-used
  4. https://sungbin.land/a-fully-diving-into-jetpack-compose-compiler-4f0fd7bead0c