본문 바로가기
Kotlin/What's new

[Kotlin 번역] What's new in Kotlin 1.9.20

by 노력남자 2024. 11. 11.
반응형

Kotlin 1.9.20 릴리스가 공개되었습니다. 이제 K2 컴파일러가 모든 타겟에서 베타 단계에 있으며, Kotlin 멀티플랫폼이 안정적인 상태로 제공됩니다. 주요 업데이트는 다음과 같습니다:

 

멀티플랫폼 프로젝트를 설정하기 위한 새로운 기본 계층 템플릿 추가

Kotlin 멀티플랫폼의 Gradle 구성 캐시 완전 지원

Kotlin/Native에서 기본적으로 활성화된 사용자 정의 메모리 할당자

Kotlin/Native에서 가비지 컬렉터 성능 개선

Kotlin/Wasm의 새로운 타겟 및 타겟 이름 변경

Kotlin/Wasm의 표준 라이브러리에서 WASI API 지원

 

업데이트에 대한 간략한 개요는 이 비디오에서도 확인할 수 있습니다.

 

 

IDE 지원현황

 

Kotlin 1.9.20을 지원하는 Kotlin 플러그인은 다음의 IDE에서 사용할 수 있습니다:

 

IDE 지원 버전
IntelliJ IDEA  2023.1.x, 2023.2.x, 2023.x
Android Studio Hedgehog (2023.1.1), Iguana (2023.2.1)

 

IntelliJ IDEA 2023.3.x 및 Android Studio Iguana (2023.2.1) Canary 15부터는 Kotlin 플러그인이 자동으로 포함되고 업데이트됩니다. 이제 프로젝트 내에서 Kotlin 버전만 업데이트하면 됩니다.

 

새로운 Kotlin K2 컴파일러 업데이트

 

JetBrains의 Kotlin 팀은 새로운 K2 컴파일러의 안정화 작업을 계속하고 있습니다. K2 컴파일러는 주요 성능 향상, 새로운 언어 기능 개발 속도 향상, Kotlin이 지원하는 모든 플랫폼의 통합, 멀티플랫폼 프로젝트를 위한 더 나은 아키텍처를 제공합니다.

 

K2는 현재 모든 타겟에서 베타 상태입니다. 자세한 내용은 릴리스 블로그 게시물에서 확인하세요.

 

Kotlin/Wasm 지원

 

이번 릴리스부터 Kotlin/Wasm은 새로운 K2 컴파일러를 지원합니다. 프로젝트에서 활성화하는 방법을 확인하세요.

 

K2를 사용하는 kapt 컴파일러 플러그인 미리보기

 

kapt 컴파일러 플러그인에서 K2 지원은 실험적 기능입니다. 옵트인이 필요하며(자세한 내용은 아래 참조), 평가 목적으로만 사용해야 합니다.

 

버전 1.9.20에서 K2 컴파일러와 함께 kapt 컴파일러 플러그인을 사용해볼 수 있습니다. 프로젝트에서 K2 컴파일러를 사용하려면 gradle.properties 파일에 다음 옵션을 추가하세요:

 

kotlin.experimental.tryK2=true
kapt.use.k2=true

 

또는 다음 단계로 kapt에서 K2를 활성화할 수 있습니다:

 

build.gradle.kts 파일에서 언어 버전을 2.0으로 설정합니다.

gradle.properties 파일에 kapt.use.k2=true를 추가합니다.

 

K2 컴파일러와 함께 kapt 사용 중에 문제가 발생하면, 문제 추적기에 보고해 주세요.

 

Kotlin K2 컴파일러 활성화 방법

 

Gradle에서 K2 활성화

 

Kotlin K2 컴파일러를 활성화하고 테스트하려면 다음 컴파일러 옵션으로 새로운 언어 버전을 사용하세요:

 

-language-version 2.0

 

build.gradle.kts 파일에 다음과 같이 지정할 수 있습니다:

 

kotlin {
    sourceSets.all {
        languageSettings {
            languageVersion = "2.0"
        }
    }
}

 

Maven에서 K2 활성화

 

Kotlin K2 컴파일러를 활성화하고 테스트하려면 pom.xml 파일의 <project/> 섹션을 업데이트하세요:

 

<properties>
    <kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion>
</properties>

 

IntelliJ IDEA에서 K2 활성화

 

IntelliJ IDEA에서 Kotlin K2 컴파일러를 활성화하고 테스트하려면 Settings | Build, Execution, Deployment | Compiler | Kotlin Compiler로 이동하여 Language Version 필드를 2.0(실험적)으로 업데이트하세요.

 

새로운 K2 컴파일러에 대한 피드백 제공

 

피드백을 남겨주시면 감사하겠습니다!

 

Kotlin Slack의 #k2-early-adopters 채널에 가입하여 K2 개발자에게 직접 피드백을 제공하세요.

새로운 K2 컴파일러와 관련된 문제는 문제 추적기에 보고하세요.

Send usage statistics 옵션을 활성화하여 JetBrains가 K2 사용에 대한 익명 데이터를 수집할 수 있도록 허용하세요.

 

Kotlin/JVM

 

버전 1.9.20부터 컴파일러가 Java 21 바이트코드를 포함하는 클래스를 생성할 수 있습니다.

 

Kotlin/Native

 

Kotlin 1.9.20에는 새로운 메모리 할당기가 기본적으로 활성화된 안정적인 메모리 관리자가 포함되어 있으며, 가비지 수집기 성능 향상 및 기타 업데이트가 추가되었습니다:

 

기본적으로 활성화된 사용자 정의 메모리 할당기

가비지 수집기 성능 향상

klib 아티팩트의 점진적 컴파일

라이브러리 링크 문제 관리

클래스 생성자 호출 시 동반 객체 초기화

모든 cinterop 선언에 대한 옵트인 요구사항

링커 오류에 대한 사용자 정의 메시지

기존 메모리 관리자 제거

타겟 계층 정책 변경

 

기본적으로 활성화된 사용자 정의 메모리 할당기

 

Kotlin 1.9.20에는 새로운 메모리 할당기가 기본으로 활성화되어 있습니다. 이 할당기는 이전 기본 할당기인 mimaloc을 대체하여 가비지 수집을 더욱 효율적으로 만들고 Kotlin/Native 메모리 관리자의 런타임 성능을 향상시키기 위해 설계되었습니다.

 

새로운 사용자 정의 할당기는 시스템 메모리를 페이지로 나누어 순차적인 독립적 스위핑을 가능하게 합니다. 각 할당은 페이지 내의 메모리 블록이 되며, 페이지는 블록 크기를 추적합니다. 다양한 페이지 유형이 다양한 할당 크기에 최적화되어 있으며, 연속적인 메모리 블록 배열은 모든 할당된 블록을 효율적으로 반복하는 데 도움이 됩니다.

 

스레드가 메모리를 할당할 때 할당 크기에 따라 적절한 페이지를 찾습니다. 스레드는 서로 다른 크기 카테고리에 대해 여러 페이지 세트를 유지합니다. 일반적으로 현재 페이지는 해당 크기의 할당을 수용할 수 있으며, 그렇지 않으면 스레드는 공유 할당 공간에서 다른 페이지를 요청합니다. 이 페이지는 이미 존재하거나, 스위핑이 필요하거나, 새로 생성해야 할 수 있습니다.

 

새로운 할당기는 여러 독립적인 할당 공간을 동시에 허용하여, 다양한 페이지 레이아웃을 실험하여 성능을 더욱 향상시킬 수 있도록 Kotlin 팀에 유연성을 제공합니다.

 

사용자 정의 메모리 할당기 활성화 방법

 

Kotlin 1.9.20부터는 새로운 메모리 할당기가 기본값으로 설정되며 추가 설정이 필요하지 않습니다.

 

만약 높은 메모리 소비를 경험한다면, -Xallocator=mimalloc 또는 -Xallocator=std 옵션을 Gradle 빌드 스크립트에 추가하여 mimaloc 또는 시스템 할당기로 되돌릴 수 있습니다. 이러한 문제는 YouTrack에 보고하여 새로운 메모리 할당기의 개선에 도움이 되도록 해주세요.

 

할당기의 설계에 대한 기술적 세부 사항은 README에서 확인할 수 있습니다.

 

가비지 수집기 성능 향상

 

Kotlin 팀은 새로운 Kotlin/Native 메모리 관리자의 성능과 안정성을 계속해서 개선하고 있습니다. 이번 릴리스에는 가비지 수집기(GC)에 대한 몇 가지 중요한 변경 사항이 포함되어 있으며, Kotlin 1.9.20의 주요 사항은 다음과 같습니다:

 

GC 일시 정지 시간을 줄이기 위한 완전 병렬 마크

할당 성능을 개선하기 위한 대규모 메모리 청크 추적

 

GC 일시 정지 시간을 줄이기 위한 완전 병렬 마크

 

이전에는 기본 가비지 수집기가 부분적인 병렬 마크만 수행했습니다. 변이자(muter) 스레드가 일시 중지되면, GC는 스레드-로컬 변수와 호출 스택 같은 자체 루트에서 시작해 마크를 수행했습니다. 한편, 별도의 GC 스레드는 글로벌 루트와 네이티브 코드를 실행 중인 모든 변이자의 루트에서 마크 작업을 시작했습니다.

 

이 접근 방식은 글로벌 객체의 수가 적고, 변이자 스레드가 실행 가능한 상태에서 상당 시간을 보내는 경우에 효과적이었습니다. 그러나 이는 일반적인 iOS 애플리케이션에서는 그렇지 않습니다.

 

이제 GC는 일시 중지된 변이자, GC 스레드, 선택적 마커 스레드를 결합하여 마크 큐를 처리하는 완전 병렬 마크를 사용합니다. 기본적으로 마킹 프로세스는 다음에 의해 수행됩니다:

일시 중지된 변이자: 이제는 자신의 루트를 처리하고 비활성 상태로 있는 대신 전체 마킹 프로세스에 기여합니다.

GC 스레드: 최소한 하나의 스레드가 마킹을 수행하도록 보장합니다.

 

이 새로운 접근 방식으로 마킹 프로세스가 더 효율적으로 이루어져 GC의 일시 정지 시간이 줄어듭니다.

 

할당 성능 향상을 위한 대규모 메모리 청크 추적

 

이전에는 GC 스케줄러가 각 객체의 할당을 개별적으로 추적했습니다. 하지만 새로운 기본 사용자 정의 할당기나 mimalloc 메모리 할당기는 각 객체에 대해 개별 저장소를 할당하지 않고 여러 객체를 위한 큰 영역을 한 번에 할당합니다.

 

Kotlin 1.9.20에서는 GC가 개별 객체가 아닌 영역을 추적합니다. 이를 통해 작은 객체의 할당 속도가 빨라지고 할당마다 수행하는 작업 수가 줄어들어 가비지 수집기의 메모리 사용량을 최소화하는 데 도움이 됩니다.

 

klib 아티팩트의 증분 컴파일

 

이 기능은 실험적 기능입니다. 언제든 변경되거나 제거될 수 있으며, 사용하려면 옵트인이 필요합니다. 평가 목적으로만 사용하시기 바랍니다. YouTrack에서 피드백을 주시면 감사하겠습니다.

 

Kotlin 1.9.20은 Kotlin/Native의 컴파일 시간 최적화를 위해 klib 아티팩트의 부분적 증분 컴파일을 도입했습니다.

 

디버그 모드에서 Kotlin 소스 코드를 네이티브 바이너리로 컴파일할 때, 컴파일은 두 단계로 진행됩니다:

 

1. 소스 코드가 klib 아티팩트로 컴파일됩니다.

2. klib 아티팩트와 그 의존성이 바이너리로 컴파일됩니다.

 

두 번째 단계의 컴파일 시간을 최적화하기 위해 이미 의존성에 대한 컴파일러 캐시가 구현되었습니다. 이들은 한 번만 네이티브 코드로 컴파일되며, 이후에는 바이너리가 컴파일될 때마다 결과가 재사용됩니다. 그러나 프로젝트 소스에서 빌드된 klib 아티팩트는 매번 전체적으로 네이티브 코드로 재컴파일되었습니다.

 

새로운 증분 컴파일을 통해 프로젝트 모듈 변경이 소스 코드의 klib 아티팩트 부분 재컴파일만 유발할 경우 klib의 일부만 바이너리로 다시 컴파일됩니다.

 

증분 컴파일을 활성화하려면 다음 옵션을 gradle.properties 파일에 추가하세요:

 

kotlin.incremental.native=true

 

문제가 발생하면 YouTrack에 보고해 주시기 바랍니다.

 

라이브러리 링크 문제 관리

 

이번 릴리스에서는 Kotlin/Native 컴파일러가 Kotlin 라이브러리의 링크 문제를 처리하는 방식이 개선되었습니다. 오류 메시지에는 해시 대신 서명 이름을 사용하여 보다 읽기 쉬운 선언이 포함되어, 문제를 더 쉽게 찾아 수정할 수 있습니다. 예를 들면 다음과 같습니다:

 

No function found for symbol 'org.samples/MyClass.removedFunction|removedFunction(kotlin.Int;kotlin.String){}[0]'

 

Kotlin/Native 컴파일러는 타사 Kotlin 라이브러리 간의 링크 문제를 감지하고 런타임 시 오류를 보고합니다. 한 타사 Kotlin 라이브러리의 작성자가 다른 타사 Kotlin 라이브러리가 사용하는 실험적 API에 비호환성 변경을 가할 경우 이러한 문제가 발생할 수 있습니다.

 

Kotlin 1.9.20부터 컴파일러는 기본적으로 조용한 모드에서 링크 문제를 감지합니다. 프로젝트에서 이 설정을 조정할 수 있습니다.

 

컴파일 로그에 이러한 문제를 기록하려면 -Xpartial-linkage-loglevel=WARNING 컴파일러 옵션으로 경고를 활성화하십시오.

보고된 경고의 심각도를 컴파일 오류로 높이려면 -Xpartial-linkage-loglevel=ERROR를 사용하십시오. 이 경우 컴파일이 실패하고 모든 오류가 컴파일 로그에 기록됩니다. 링크 문제를 더 면밀히 검사할 때 이 옵션을 사용하십시오.

 

kotlin {
    macosX64("native") {
        binaries.executable()

        compilations.configureEach {
            compilerOptions.configure {
                // 링크 문제를 경고로 보고:
                freeCompilerArgs.add("-Xpartial-linkage-loglevel=WARNING")

                // 링크 경고를 오류로 올림:
                freeCompilerArgs.add("-Xpartial-linkage-loglevel=ERROR")
            }
        }
    }
}

 

이 기능과 관련하여 예기치 않은 문제가 발생하면 -Xpartial-linkage=disable 컴파일러 옵션으로 옵트 아웃할 수 있습니다. 이런 경우에는 문제 추적기에 보고해 주세요.

 

클래스 생성자 호출 시 Companion 객체 초기화

 

Kotlin 1.9.20부터 Kotlin/Native 백엔드는 클래스 생성자에서 companion 객체의 정적 초기화를 호출합니다.

 

class Greeting {
    companion object {
        init {
            print("Hello, Kotlin!")
        }
    }
}

fun main() {
    val start = Greeting() // "Hello, Kotlin!" 출력
}

 

이제 자바의 static initializer와 일치하는 방식으로, 대응하는 클래스가 로드될 때 companion 객체가 초기화됩니다. 이 기능의 구현이 플랫폼 간 일관성을 가지게 되어, Kotlin Multiplatform 프로젝트에서 코드 공유가 더 쉬워졌습니다.

 

모든 cinterop 선언에 대한 옵트인 요구 사항

 

Kotlin 1.9.20부터 libcurl이나 libxml과 같은 C 및 Objective-C 라이브러리에서 cinterop 도구가 생성한 모든 Kotlin 선언에 @ExperimentalForeignApi가 표시됩니다. 옵트인 주석이 없으면 코드가 컴파일되지 않습니다.

 

이 요구 사항은 C 및 Objective-C 라이브러리 가져오기 기능의 실험적 상태를 반영합니다. 프로젝트의 특정 영역에 제한하여 사용하기를 권장합니다. 향후 가져오기 기능이 안정화될 때 마이그레이션이 더 쉬워집니다.

 

Kotlin/Native에 기본적으로 제공되는 네이티브 플랫폼 라이브러리(예: Foundation, UIKit 및 POSIX)에서는 일부 API에 대해서만 @ExperimentalForeignApi가 필요하며, 이러한 경우 경고와 함께 옵트인이 필요함을 알려줍니다.

 

링크 오류에 대한 사용자 정의 메시지

 

라이브러리 작성자는 이제 사용자 정의 메시지를 통해 링크 오류 해결을 돕는 메시지를 제공할 수 있습니다.

 

Kotlin 라이브러리가 CocoaPods 통합과 같이 C 또는 Objective-C 라이브러리에 의존하는 경우, 사용자 시스템에 이러한 종속 라이브러리가 로컬에 있어야 하며 프로젝트 빌드 스크립트에서 명시적으로 구성되어야 합니다. 그렇지 않으면 “Framework not found”와 같은 혼란스러운 메시지가 표시될 수 있습니다.

 

이제 컴파일 실패 메시지에 특정 지침이나 링크를 제공할 수 있습니다. cinterop에 -Xuser-setup-hint 컴파일러 옵션을 전달하거나 .def 파일에 userSetupHint=message 속성을 추가하세요.

 

레거시 메모리 관리자 제거

 

새 메모리 관리자는 Kotlin 1.6.20에서 도입되었고 1.7.20에서 기본값이 되었습니다. 이후 추가 업데이트와 성능 개선을 거쳐 Stable이 되었습니다.

 

레거시 메모리 관리자를 제거할 시점이 되었습니다. 여전히 사용하는 경우, gradle.properties 파일에서 kotlin.native.binary.memoryModel=strict 옵션을 제거하고 마이그레이션 가이드를 따라 필요한 변경 사항을 적용하세요.

 

타겟 등급 정책 변경

 

1단계 지원 요건이 상향 조정되었습니다. Kotlin 팀은 1단계 지원이 가능한 타겟에 대해 컴파일러 릴리스 간의 소스 및 바이너리 호환성을 제공하는 데 전념하고 있으며, CI 도구로 정기적으로 테스트되어 컴파일 및 실행이 가능해야 합니다. 현재 1단계에는 macOS 호스트용 다음 타겟이 포함됩니다:

 

macosX64

macosArm64

iosSimulatorArm64

iosX64

 

Kotlin 1.9.20에서는 다음과 같은 이전에 사용되지 않던 타겟을 제거했습니다:

 

iosArm32

watchosX86

wasm32

mingwX86

linuxMips32

linuxMipsel32

 

현재 지원되는 타겟 목록을 참조하세요.

 

Kotlin Multiplatform

 

Kotlin 1.9.20은 Kotlin Multiplatform의 안정화에 집중하며, 새로운 프로젝트 마법사 및 기타 주요 기능을 통해 개발자 경험을 개선하는 새로운 단계를 진행했습니다:

 

Kotlin Multiplatform이 안정화됨

멀티플랫폼 프로젝트 구성을 위한 템플릿

새로운 프로젝트 마법사

Gradle 구성 캐시에 대한 완전 지원

Gradle에서 새로운 표준 라이브러리 버전 설정이 더 쉬워짐

타사 cinterop 라이브러리에 대한 기본 지원

Compose Multiplatform 프로젝트에서 Kotlin/Native 컴파일 캐시 지원

호환성 가이드라인

 

Kotlin Multiplatform은 안정화됨

 

Kotlin 1.9.20 릴리스는 Kotlin의 진화에서 중요한 이정표를 의미합니다: Kotlin Multiplatform은 드디어 안정화되었습니다. 이는 이 기술이 프로젝트에서 안전하게 사용할 수 있으며 100% 생산에 적합하다는 의미입니다. 또한, Kotlin Multiplatform의 향후 개발은 엄격한 하위 호환성 규칙에 따라 계속될 것입니다.

 

일부 고급 기능은 여전히 개발 중이며, 이를 사용할 때는 해당 기능의 현재 안정성 상태를 설명하는 경고를 받게 됩니다. IntelliJ IDEA에서 실험적 기능을 사용하려면 Settings | Advanced Settings | Kotlin | Experimental Multiplatform에서 명시적으로 활성화해야 합니다.

 

Kotlin 블로그를 방문하여 Kotlin Multiplatform 안정화 및 향후 계획에 대해 더 알아보세요.

 

멀티플랫폼 호환성 가이드를 확인하여 안정화를 위한 중요한 변경 사항을 살펴보세요.

 

멀티플랫폼 프로젝트 구성을 위한 템플릿

 

Kotlin 1.9.20부터 Kotlin Gradle 플러그인은 인기 있는 멀티플랫폼 시나리오에 대한 공유 소스 세트를 자동으로 생성합니다. 프로젝트 설정이 이러한 시나리오 중 하나라면, 소스 세트 계층을 수동으로 구성할 필요가 없습니다. 필요한 대로 명시적으로 타겟을 지정하기만 하면 됩니다.

 

이제 기본 계층 템플릿 덕분에 설정이 훨씬 쉬워졌습니다. 이 템플릿은 Kotlin Gradle 플러그인에 내장된 소스 세트 계층의 미리 정의된 템플릿으로, 선언된 타겟에 대해 Kotlin이 자동으로 생성하는 중간 소스 세트를 포함합니다.

 

프로젝트 설정을 더 쉽게 만들기

 

다음은 Android와 iPhone 기기를 타겟으로 하고 Apple Silicon MacBook에서 개발되는 멀티플랫폼 프로젝트의 설정을 Kotlin의 다양한 버전에서 비교한 예입니다:

 

Kotlin 1.9.0 및 이전 버전 (표준 설정)

 

kotlin {
    androidTarget()
    iosArm64()
    iosSimulatorArm64()

    sourceSets {
        val commonMain by getting

        val iosMain by creating {
            dependsOn(commonMain)
        }

        val iosArm64Main by getting {
            dependsOn(iosMain)
        }

        val iosSimulatorArm64Main by getting {
            dependsOn(iosMain)
        }
    }
}

 

Kotlin 1.9.20

 

kotlin {
    androidTarget()
    iosArm64()
    iosSimulatorArm64()

    // iosMain 소스 세트는 자동으로 생성됨
}

 

위의 예시에서 보듯이 기본 계층 템플릿을 사용하면 프로젝트 설정 시 필요한 보일러플레이트 코드가 상당히 줄어듭니다.

 

androidTarget, iosArm64, iosSimulatorArm64 타겟을 선언하면 Kotlin Gradle 플러그인이 적절한 공유 소스 세트를 템플릿에서 찾아 자동으로 생성합니다. 결과적으로 다음과 같은 계층 구조가 생성됩니다:

 

 

초록색 소스 세트는 실제로 생성되어 프로젝트에 포함됩니다.

회색 소스 세트는 템플릿에서 제공되지만, 사용되지 않아서 무시됩니다.

 

소스 세트 완성 기능 사용

 

IntelliJ IDEA는 이제 기본 계층 템플릿으로 생성된 소스 세트에 대한 자동 완성 기능을 제공합니다. 이를 통해 생성된 프로젝트 구조를 더 쉽게 작업할 수 있습니다.

 

 

Kotlin은 또한 선언된 타겟이 없어서 소스 세트를 찾을 수 없는 경우 경고를 표시합니다. 예를 들어, 아래와 같이 JVM 타겟을 선언하지 않은 경우 jvmMain 소스 세트를 사용하려고 하면 경고 메시지가 나타납니다:

 

kotlin {
    androidTarget()
    iosArm64()
    iosSimulatorArm64()

    sourceSets {
        jvmMain {
        }
    }
}

 

이 경우 빌드 로그에서 다음과 같은 경고 메시지가 출력됩니다:

 

w: Accessed 'source set jvmMain' without registering the jvm target:
  kotlin {
      jvm() /* <- 'jvm' 타겟을 등록하세요 */

      sourceSets.jvmMain.dependencies {
      }
  }

 

타겟 계층 설정

 

Kotlin 1.9.20부터 기본 계층 템플릿이 자동으로 활성화됩니다. 대부분의 경우 추가 설정이 필요하지 않습니다.

 

하지만 1.9.20 이전에 프로젝트를 생성했다면, 이전에 dependsOn() 호출로 중간 소스 세트를 수동으로 추가했을 경우 경고 메시지가 나타날 수 있습니다. 이 문제를 해결하려면 다음과 같이 진행합니다:

현재 기본 계층 템플릿에 의해 커버되는 중간 소스 세트가 있다면, 수동으로 추가한 dependsOn() 호출과 by creating으로 생성된 소스 세트를 제거하세요.

기본 소스 세트 목록을 확인하려면 전체 계층 템플릿을 참고하세요.

 

기본 템플릿이 제공하지 않는 추가 소스 세트가 필요하다면, 예를 들어 macOS와 JVM 타겟 간에 코드를 공유하는 소스 세트를 만들려면, applyDefaultHierarchyTemplate()를 명시적으로 다시 적용하여 계층을 조정하고 나머지 소스 세트는 수동으로 설정할 수 있습니다:

 

kotlin {
    jvm()
    macosArm64()
    iosArm64()
    iosSimulatorArm64()

    // 기본 계층 템플릿 명시적 적용
    applyDefaultHierarchyTemplate()

    sourceSets {
        // 추가적인 jvmAndMacos 소스 세트 생성
        val jvmAndMacos by creating {
            dependsOn(commonMain.get())
        }

        macosArm64Main.get().dependsOn(jvmAndMacos)
        jvmMain.get().dependsOn(jvmAndMacos)
    }
}

 

기존에 동일한 이름의 소스 세트를 이미 프로젝트에서 사용하고 있는데, 이 소스 세트가 기본 템플릿에서 생성된 것과 다르게 다른 타겟 집합 간에 공유되는 경우, 현재로서는 기본 템플릿의 dependsOn 관계를 수정하는 방법이 없습니다.

 

이 경우 사용할 수 있는 방법은 다른 목적에 맞는 소스 세트를 기본 템플릿이나 수동으로 생성된 것들에서 찾는 것입니다. 또는 템플릿을 완전히 무시하고 설정을 수동으로 진행할 수도 있습니다.

 

템플릿을 완전히 무시하려면 gradle.properties 파일에 kotlin.mpp.applyDefaultHierarchyTemplate=false를 추가하고, 모든 다른 소스 세트를 수동으로 구성하세요.

 

현재로서는 이러한 경우의 설정을 단순화할 수 있는 사용자 정의 계층 템플릿을 만들 수 있는 API 작업이 진행 중입니다.

 

타겟을 선언할 때, 플러그인은 템플릿에 맞게 공유 소스 세트를 선택하고 프로젝트에 생성합니다.

 

기본 계층 템플릿

 

 

이 예시는 프로젝트의 프로덕션 부분만 보여주며, Main 접미사(예: commonMain 대신 common)를 생략한 것입니다. 그러나 *Test 소스에 대해서도 동일한 방식이 적용됩니다.

 

새로운 프로젝트 마법사

 

JetBrains 팀은 새로운 방식으로 크로스 플랫폼 프로젝트를 생성하는 방법을 도입하고 있습니다. 바로 Kotlin Multiplatform 웹 마법사입니다.

 

이 새로운 Kotlin Multiplatform 마법사의 첫 번째 구현은 가장 인기 있는 Kotlin Multiplatform 사용 사례를 다루고 있으며, 이전 프로젝트 템플릿에 대한 피드백을 모두 반영하고 아키텍처를 가능한 한 견고하고 신뢰할 수 있도록 만들었습니다.

 

새로운 마법사는 분산 아키텍처를 채택하여, 통합된 백엔드와 다양한 프론트엔드를 제공합니다. 웹 버전이 첫 번째 단계이며, 향후 IDE 버전과 커맨드라인 도구의 구현도 고려하고 있습니다. 웹에서는 항상 최신 버전의 마법사를 제공하지만, IDE에서는 다음 릴리스를 기다려야 합니다.

 

새로운 마법사 덕분에 프로젝트 설정이 그 어느 때보다 쉬워졌습니다. 모바일, 서버 및 데스크탑 개발을 위한 타겟 플랫폼을 선택하여 프로젝트를 자신의 필요에 맞게 조정할 수 있습니다. 또한 향후 릴리스에서 웹 개발도 추가할 계획입니다.

 

 

새로운 프로젝트 마법사는 이제 Kotlin을 사용한 크로스 플랫폼 프로젝트를 생성하는 권장 방법입니다. 1.9.20부터 Kotlin 플러그인은 더 이상 IntelliJ IDEA에서 Kotlin Multiplatform 프로젝트 마법사를 제공하지 않습니다.

 

새로운 마법사는 초기 설정을 통해 프로젝트 설정을 쉽게 시작할 수 있도록 돕습니다. 만약 문제가 발생하면, YouTrack에 보고하여 마법사 경험을 개선할 수 있도록 도와주세요.

 

Kotlin Multiplatform에서 Gradle 구성 캐시의 전체 지원

 

이전에는 Kotlin multiplatform 라이브러리에 대해 Gradle 구성 캐시의 미리보기를 도입했습니다. 1.9.20부터 Kotlin Multiplatform 플러그인은 한 걸음 더 나아갔습니다.

 

이제 Kotlin CocoaPods Gradle 플러그인과 Xcode 빌드에 필요한 통합 작업들(예: embedAndSignAppleFrameworkForXcode)에서도 Gradle 구성 캐시를 지원합니다.

 

이로 인해 모든 multiplatform 프로젝트는 개선된 빌드 시간을 활용할 수 있습니다. Gradle 구성 캐시는 후속 빌드를 위해 구성 단계의 결과를 재사용하여 빌드 프로세스를 가속화합니다. 자세한 내용과 설정 방법은 Gradle 문서를 참조하십시오.

 

Gradle에서 새로운 표준 라이브러리 버전 구성의 용이성

 

멀티플랫폼 프로젝트를 생성할 때, 표준 라이브러리(stdlib)에 대한 종속성이 각 소스 세트에 자동으로 추가됩니다. 이는 멀티플랫폼 프로젝트를 시작하는 가장 쉬운 방법입니다.

 

이전에는 표준 라이브러리에 대한 종속성을 수동으로 구성하려면 각 소스 세트에 대해 개별적으로 구성해야 했습니다. 하지만 1.9.20부터는 commonMain 루트 소스 세트에서 한 번만 종속성을 구성하면 됩니다.

 

표준 라이브러리 버전 1.9.10 이전

 

kotlin {
    sourceSets {
        // common 소스 세트
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10")
            }
        }

        // JVM 소스 세트
        val jvmMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.10")
            }
        }

        // JS 소스 세트
        val jsMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib-js:1.9.10")
            }
        }
    }
}

 

표준 라이브러리 버전 1.9.20

 

kotlin {
    sourceSets {
        commonMain {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
            }
        }
    }
}

 

이 변경은 표준 라이브러리의 Gradle 메타데이터에 새로운 정보를 포함시킴으로써 가능해졌습니다. 이를 통해 Gradle은 다른 소스 세트를 위한 올바른 표준 라이브러리 아티팩트를 자동으로 해결할 수 있습니다.

 

타사 cinterop 라이브러리에 대한 기본 지원

 

Kotlin 1.9.20에서는 Kotlin CocoaPods Gradle 플러그인이 적용된 프로젝트에서 모든 cinterop 종속성에 대해 기본 지원을 추가했습니다(옵트인 방식이 아님).

 

이제 플랫폼별 종속성에 제한되지 않고 더 많은 네이티브 코드를 공유할 수 있습니다. 예를 들어, iosMain 공유 소스 세트에 Pod 라이브러리에 대한 종속성을 추가할 수 있습니다.

 

이전에는 Kotlin/Native 배포판에 포함된 플랫폼별 라이브러리(예: Foundation, UIKit, POSIX)에서만 이 기능이 작동했습니다. 이제 모든 타사 Pod 라이브러리가 기본적으로 공유 소스 세트에서 사용 가능하며, 이를 지원하기 위한 별도의 Gradle 속성을 지정할 필요가 없습니다.

 

Compose Multiplatform 프로젝트에서 Kotlin/Native 컴파일 캐시 지원

 

이번 릴리스에서는 Compose Multiplatform 컴파일러 플러그인과의 호환성 문제가 해결되었습니다. 이 문제는 주로 iOS용 Compose Multiplatform 프로젝트에 영향을 미쳤습니다.

 

이 문제를 우회하기 위해서는 kotlin.native.cacheKind=none Gradle 속성을 사용하여 캐싱을 비활성화해야 했습니다. 그러나 이 방법은 캐싱이 작동하지 않으므로 컴파일 시간이 느려지는 성능 저하를 초래했습니다.

 

이제 해당 문제가 해결되었으므로, gradle.properties 파일에서 kotlin.native.cacheKind=none을 제거하고 Compose Multiplatform 프로젝트에서 개선된 컴파일 시간을 누릴 수 있습니다.

 

컴파일 시간 개선에 대한 추가 팁은 Kotlin/Native 문서를 참조하세요.

 

호환성 가이드라인

 

프로젝트를 구성할 때는 Kotlin Multiplatform Gradle 플러그인과 사용 중인 Gradle, Xcode, Android Gradle Plugin(AGP) 버전의 호환성을 확인해야 합니다:

 

Kotlin Multiplatform Gradle 플러그인 Gradle Android Gradle 플러그인 Xcode
1.9.20 7.5 이상  7.4.2–8.2 15.0

 

이 릴리스에서는 Xcode의 권장 버전이 15.0입니다. Xcode 15.0에 포함된 라이브러리는 완벽하게 지원되며, Kotlin 코드에서 이를 어디서든 접근할 수 있습니다.

 

하지만 Xcode 14.3도 대부분의 경우에서 잘 작동하며, 로컬 머신에서 14.3 버전을 사용하면 Xcode 15로 제공된 라이브러리는 보이지만 접근할 수 없다는 점을 유의하세요.

 

Kotlin/Wasm

 

Kotlin 1.9.20에서 Kotlin Wasm은 Alpha 안정성 수준에 도달했습니다.

 

Wasm GC 4단계 및 최종 opcodes와의 호환성

 

Wasm GC가 최종 단계로 이동하면서, 이진 표현에서 사용되는 상수 숫자인 opcodes가 업데이트되었습니다. Kotlin 1.9.20은 최신 opcodes를 지원하므로, 최신 버전의 Kotlin으로 Wasm 프로젝트를 업데이트할 것을 강력히 권장합니다. 또한 최신 버전의 Wasm 환경을 지원하는 브라우저를 사용하는 것도 권장됩니다:

Chrome 및 Chromium 기반 브라우저는 버전 119 이상

Firefox는 버전 119 이상, 단 Firefox 119에서는 Wasm GC를 수동으로 활성화해야 합니다.

 

새로운 wasm-wasi 타겟과 wasm 타겟의 wasm-js로의 이름 변경

 

이번 릴리스에서는 Kotlin/Wasm에 새로운 타겟인 wasm-wasi가 추가되었습니다. 기존의 wasm 타겟은 wasm-js로 이름이 변경되었습니다. Gradle DSL에서는 각각 wasmWasi {}wasmJs {}로 사용할 수 있습니다.

 

이 타겟을 프로젝트에서 사용하려면, build.gradle.kts 파일을 다음과 같이 업데이트해야 합니다:

 

kotlin {
    wasmWasi {
        // ...
    }
    wasmJs {
        // ...
    }
}

 

이전에 사용되었던 wasm {} 블록은 더 이상 사용되지 않으며, wasmJs {}로 대체되었습니다.

 

기존의 Kotlin/Wasm 프로젝트를 마이그레이션하려면 다음 단계를 따르세요:

 

1. build.gradle.kts 파일에서 wasm {} 블록의 이름을 wasmJs {}로 변경합니다.

2. 프로젝트 구조에서 wasmMain 디렉터리의 이름을 wasmJsMain으로 변경합니다.

 

WASI API 지원 (표준 라이브러리)

 

이번 릴리스에서는 WASI (WebAssembly System Interface) 지원이 추가되었습니다. WASI는 Wasm 플랫폼을 위한 시스템 인터페이스로, Kotlin/Wasm을 브라우저 외의 환경에서도 사용할 수 있게 해줍니다. 예를 들어, 서버 사이드 애플리케이션에서 시스템 리소스에 접근할 수 있는 표준화된 API 집합을 제공하여, Kotlin/Wasm의 사용을 더욱 쉽게 만듭니다. 또한, WASI는 외부 리소스에 접근할 때 보안 계층을 추가하는 기능도 제공합니다.

 

Kotlin/Wasm 애플리케이션을 실행하려면 Wasm Garbage Collection (GC)을 지원하는 VM이 필요합니다. 예를 들어, Node.js 또는 Deno가 해당됩니다. Wasmtime, WasmEdge 등은 아직 Wasm GC 완전 지원을 위해 작업 중입니다.

 

WASI 함수를 가져오기 위해서는 @WasmImport 애노테이션을 사용합니다:

 

import kotlin.wasm.WasmImport

@WasmImport("wasi_snapshot_preview1", "clock_time_get")
private external fun wasiRawClockTimeGet(clockId: Int, precision: Long, resultPtr: Int): Int

 

전체 예제는 GitHub 저장소에서 확인할 수 있습니다.

 

주의: wasmWasi 타겟을 사용할 때는 JavaScript와의 상호 운용성을 사용할 수 없습니다.

 

Kotlin/Wasm API 개선 사항

 

이번 릴리스에서는 Kotlin/Wasm API에 여러 가지 품질 향상 개선이 포함되었습니다. 예를 들어, DOM 이벤트 리스너에서 값을 반환할 필요가 없어졌습니다:

 

1.9.20 이전:

 

fun main() {
    window.onload = {
        document.body?.sayHello()
        null
    }
}

 

1.9.20 이후:

 

fun main() {
    window.onload = { document.body?.sayHello() }
}

 

이와 같은 개선으로 코드가 간결하고 명확해졌습니다.

 

Gradle 지원

 

Kotlin 1.9.20은 Gradle 6.8.3부터 8.1까지 완전히 호환됩니다. 최신 Gradle 릴리스를 사용해도 되지만, 이 경우 새로운 Gradle 기능이 제대로 작동하지 않거나, 일부 기능에서 사용 중단 경고가 발생할 수 있습니다.

 

이번 릴리스는 다음과 같은 변경 사항을 포함합니다:

 

테스트 픽스처에서 내부 선언 접근 지원

 

Kotlin 1.9.20에서는 Gradle의 java-test-fixtures 플러그인을 사용하는 경우, 테스트 픽스처가 이제 메인 소스 세트 클래스 내의 내부 선언에 접근할 수 있습니다. 또한, 테스트 소스는 테스트 픽스처 클래스 내의 내부 선언도 볼 수 있습니다.

 

Konan 디렉토리 경로를 구성할 새로운 속성

 

Kotlin 1.9.20에서는 kotlin.data.dir Gradle 속성을 통해 ~/.konan 디렉토리 경로를 사용자 지정할 수 있습니다. 이제 환경 변수 KONAN_DATA_DIR을 통해 경로를 설정할 필요가 없습니다. 또한, -Xkonan-data-dir 컴파일러 옵션을 사용하여 cinterop 및 konanc 도구를 통해 사용자 지정 경로를 설정할 수도 있습니다.

 

Kotlin/Native 작업에 대한 새로운 빌드 보고서 메트릭

 

Kotlin 1.9.20에서는 Gradle 빌드 보고서에 Kotlin/Native 작업에 대한 메트릭이 포함됩니다. 예를 들어, 다음과 같은 빌드 보고서에서 메트릭을 확인할 수 있습니다:

 

전체 Kotlin 작업 시간: 20.81초 (전체 작업 시간의 93.1%)

 

시간 Kotlin 시간 비율 작업
15.24초 3.2% :compileCommonMainKotlinMetadata
5.57초 26.8% :compileNativeMainKotlinMetadata

 

각 작업에 대해 다음과 같은 상세 정보도 제공됩니다:

 

Kotlin 언어 버전

작업 시간 및 메트릭

작업 실행 시간, 크기 메트릭

 

kotlin.experimental.tryK2 빌드 보고서는 이제 Kotlin/Native 작업이 컴파일된 경우 이를 포함하고, 사용된 Kotlin 언어 버전을 나열합니다:

 

‘kotlin.experimental.tryK2’ 결과:

 

:lib:compileCommonMainKotlinMetadata: 2.0 언어 버전
:lib:compileKotlinJvm: 2.0 언어 버전
:lib:compileKotlinIosArm64: 2.0 언어 버전
...

 

Gradle 8.0을 사용할 경우, Gradle 구성 캐시가 활성화된 상태에서 빌드 보고서에서 문제가 발생할 수 있습니다. 이는 Gradle 8.1 이상에서 해결된 알려진 문제입니다.

 

표준 라이브러리

 

Kotlin 1.9.20에서 Kotlin/Native 표준 라이브러리가 안정화되었으며, 몇 가지 새로운 기능이 추가되었습니다:

 

Enum 클래스의 values 함수 교체

 

이 기능은 실험적입니다. 언제든지 변경되거나 삭제될 수 있으므로 평가 목적에만 사용해야 합니다. 이에 대한 피드백은 YouTrack에서 제출해주시면 감사하겠습니다.

 

Kotlin 1.9.0에서는 enum classentries 속성이 안정화되었습니다. entries 속성은 values() 함수의 대체 기능으로, 더 현대적이고 성능이 향상된 방법입니다. Kotlin 1.9.20에서는 enumValues<T>() 함수의 대체 기능인 enumEntries<T>()가 추가되었습니다.

 

enumValues<T>() 함수는 여전히 지원되지만, 성능 저하가 적은 enumEntries<T>() 함수의 사용을 권장합니다. enumValues<T>()를 호출할 때마다 새로운 배열이 생성되는 반면, enumEntries<T>()는 매번 동일한 목록을 반환하므로 훨씬 효율적입니다.

 

예시:

 

enum class RGB { RED, GREEN, BLUE }

@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T : Enum<T>> printAllValues() {
    print(enumEntries<T>().joinToString { it.name })
}

printAllValues<RGB>()
// RED, GREEN, BLUE

 

enumEntries 함수 사용 방법

 

이 기능을 사용하려면 @OptIn(ExperimentalStdlibApi)를 추가하고, 언어 버전 1.9 이상을 사용해야 합니다. 최신 Kotlin Gradle 플러그인 버전을 사용하는 경우 언어 버전을 따로 지정하지 않고도 기능을 시험할 수 있습니다.

 

Kotlin/Native 표준 라이브러리 안정화

 

Kotlin 1.9.0에서는 Kotlin/Native 표준 라이브러리를 안정화하기 위한 작업을 시작했다고 설명했습니다. Kotlin 1.9.20에서는 이 작업을 마무리하고 Kotlin/Native 표준 라이브러리를 안정화했습니다. 이번 릴리스의 주요 내용은 다음과 같습니다:

 

Vector128 클래스가 kotlin.native 패키지에서 kotlinx.cinterop 패키지로 이동했습니다.

ExperimentalNativeApiNativeRuntimeApi 어노테이션의 옵트인 요구 수준이 경고에서 오류로 변경되었습니다.

Kotlin/Native 컬렉션은 이제 동시 수정(concurrent modification)을 감지할 수 있습니다. 예를 들어, ArrayListHashMap에서 동시 수정이 발생하면 이를 감지합니다.

Throwable 클래스의 printStackTrace() 함수가 이제 STDOUT 대신 STDERR에 출력됩니다.

printStackTrace()의 출력 형식은 안정적이지 않으며 변경될 수 있습니다.

 

Atomics API 개선

 

Kotlin 1.9.0에서는 Atomics API가 Kotlin/Native 표준 라이브러리가 안정화되면 준비가 완료된다고 했으며, Kotlin 1.9.20에서는 다음과 같은 변경 사항이 포함되었습니다:

 

실험적AtomicIntArray, AtomicLongArray, AtomicArray<T> 클래스가 도입되었습니다. 이 클래스들은 Java의 원자적 배열(atomic arrays)과 일관성을 맞추기 위해 설계되었으며, 향후 공통 표준 라이브러리에 포함될 수 있습니다.

AtomicIntArray, AtomicLongArray, AtomicArray<T> 클래스는 실험적입니다. 언제든지 변경되거나 삭제될 수 있으므로, @OptIn(ExperimentalStdlibApi)를 사용하여 시험할 수 있습니다. 평가 목적에만 사용해야 합니다.

kotlin.native.concurrent 패키지 내에서 1.9.0에서 경고 수준으로 deprecated된 Atomics API의 deprecation 수준이 오류로 변경되었습니다.

kotlin.concurrent 패키지에서 AtomicIntAtomicLong 클래스의 멤버 함수들 중 오류 수준으로 deprecated된 함수들이 제거되었습니다.

AtomicReference 클래스의 모든 멤버 함수가 이제 원자적 내장 함수(atomic intrinsic functions)를 사용합니다.

 

Kotlin/JS에서 HashMap 연산 성능 향상

 

Kotlin 1.9.20에서는 Kotlin/JS에서 HashMap 연산 성능을 개선하고 메모리 사용을 줄였습니다. 내부적으로 Kotlin/JS는 **열린 주소법(open addressing)**을 사용하여 HashMap을 구현하였으며, 이로 인해 다음과 같은 작업에서 성능이 향상되었습니다:

 

새로운 요소를 HashMap에 삽입할 때

기존 요소를 HashMap에서 검색할 때

HashMap의 키나 값을 반복(iterate)할 때

 

문서 업데이트

 

Kotlin 문서에 몇 가지 중요한 변경 사항이 포함되었습니다:

 

JVM 메타데이터 API 참조: Kotlin/JVM에서 메타데이터를 파싱하는 방법을 살펴보세요.

시간 측정 가이드: Kotlin에서 시간을 계산하고 측정하는 방법을 배워보세요.

Kotlin 투어의 개선된 컬렉션 장: Kotlin 프로그래밍 언어의 기초를 이론과 실습을 통해 배울 수 있는 장입니다.

확정적으로 널이 아닌 타입: 확정적으로 널이 아닌 제네릭 타입에 대해 배워보세요.

개선된 배열 페이지: 배열에 대해 배우고 언제 사용하는 것이 좋은지에 대해 알아보세요.

Kotlin Multiplatform에서 예상 및 실제 선언: Kotlin Multiplatform에서 예상 및 실제 선언 메커니즘에 대해 배워보세요.

 

Kotlin 1.9.20 설치

 

IDE 버전 확인

 

IntelliJ IDEA 2023.1.x2023.2.x는 Kotlin 플러그인 버전 1.9.20로의 업데이트를 자동으로 제안합니다.

IntelliJ IDEA 2023.3은 Kotlin 1.9.20 플러그인을 포함할 예정입니다.

Android Studio Hedgehog (231) 및 **Iguana (232)**는 Kotlin 1.9.20을 향후 릴리스에서 지원할 예정입니다.

새로운 명령줄 컴파일러는 GitHub 릴리스 페이지에서 다운로드할 수 있습니다.

 

Gradle 설정 구성

 

Kotlin 아티팩트와 의존성을 다운로드하려면, settings.gradle(.kts) 파일을 업데이트하여 Maven Central 저장소를 사용하도록 설정하세요:

 

pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
}

 

저장소가 지정되지 않으면, Gradle은 구식 JCenter 저장소를 사용하게 되어 Kotlin 아티팩트와 관련된 문제가 발생할 수 있습니다.

 

원문

 

https://kotlinlang.org/docs/whatsnew1920.html#full-support-for-the-gradle-configuration-cache-in-kotlin-multiplatform

반응형

댓글