Gradle bağımlılık çözümü

Derleme dosyalarınız doğrudan bağımlılıkları belirtir ancak bu bağımlılıkların her biri başka bağımlılıklar gerektirebilir. Bu geçişli bağımlılıklar, genellikle çakışan versiyonlarıyla genel bağımlılık grafiğinizi hızla büyütür.

minor (yeni özellikler) veya patch (hata düzeltmeleri) parçaları değiştiğinde, kitaplık muhtemelen uyumlu olmaya devam eder ve uygulamanızı etkileme olasılığı daha düşüktür.

Örneğin, uygulamanızın A kitaplığına ve B kitaplığına bağlı olduğunu ve bunlar da C kitaplığının farklı sürümlerine bağlı olduğunu varsayalım.

Uygulamanız A ve B kitaplıklarına bağlıdır. Bu kitaplıklar da C kitaplığının farklı sürümlerine bağlıdır. Gradle, C kitaplığının en yeni sürümünü seçiyor.
Şekil 1. Geçişli sürüm çakışması. Gradle en yeni sürüme (varsayılan olarak) çözümlenir.

Bu durumda Gradle, varsayılan olarak C kitaplığının en yeni sürümünü seçer. Bu da derleme veya çalışma zamanı sorunlarına neden olabilir. Bu örnekte C kitaplığı 2.1.1 olarak çözümlenmiştir ancak A kitaplığının C 1.0.3 kitaplığını istediğini unutmayın. Sürüm numarasının büyük kısmı değişti. Bu, kaldırılan işlevler veya türler gibi uyumsuz değişiklikler olduğunu gösterir. Bu durum, A kitaplığından yapılan aramaların kilitlenmesine neden olabilir.

Uygulamanızın geçişli bağımlılıklar da olan doğrudan bağımlılıkları olabilir.

Uygulamanız A kitaplığına ve C kitaplığına bağlıdır. A Kitaplığı, C kitaplığının yeni sürümüne bağlıdır. Gradle, C kitaplığının en yeni sürümünü seçer.
Şekil 2. Başka bir geçişli sürüm çakışması. Burada Gradle geçişli sürüme döner ve uygulamanız bu yeni sürümü görür.

Böyle bir durumda, yeni geçişli bağımlılıklar uygulamanızda doğrudan talep ettiğiniz sürümü geçersiz kılabilir.

Gradle, her bağımlılığın en yeni sürümünü belirlemek için grafikteki tüm bağımlılıkların tüm aday sürümlerini inceler. Gradle'ın her bağımlılığın hangi sürümlerini çözdüğünü belirlemek için temel Gradle görevlerini ve daha gelişmiş araçları kullanabilirsiniz. Bu çözümdeki değişiklikleri karşılaştırmak, yükseltme işleminin risklerini anlayıp azaltma açısından son derece önemlidir.

Örneğin, uygulama modülünüz tarafından kullanılan tüm bağımlılıkların ağacını görüntülemek için ./gradlew app:dependencies komutunu çalıştırarak Gradle dependencies görevini kullanabilirsiniz. Bu işlemi, Şekil 2'de gösterildiği gibi kitaplıkları kullanan bir uygulamada çalıştırdığımızda,

1: releaseRuntimeClasspath - Runtime classpath of /release.
2: +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0
3: |    +--- ... (omitted for brevity) ...
4: +--- com.sample:library.a:1.2.3
5: |    +--- com.sample:library.c:2.1.1
6: |    |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
7: |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
8: +--- com.sample:library.c:1.4.1 -> 2.1.1 (*)

Raporun bu bölümünde, releaseRuntimeClasspath yapılandırması için çözülen bazı bağımlılıklar gösterilir.

Bağımlılıklar raporunuzda -> ifadesini gördüğünüzde, bir istekte bulunan (uygulamanız veya başka bir kitaplık) bu bağımlılığın beklemediği bir sürümünü kullanır. Çoğu kitaplık geriye dönük uyumluluk için yazıldığından bu, çoğu durumda herhangi bir soruna neden olmaz. Ancak bazı kitaplıklar uyumsuz değişiklikler yapabilir ve bu rapor, uygulamanızın davranışıyla ilgili yeni sorunların nereden kaynaklandığını belirlemenize yardımcı olabilir.

Gradle'ın bağımlılık raporlamasını kullanma hakkında daha fazla bilgiyi Bağımlılıkları Görüntüleme ve Hata Ayıklama başlıklı makalede bulabilirsiniz.

İstenen sürümleri doğrudan, sürüm kataloğunda veya Malzeme Listesi'nde (BOM) belirtebilirsiniz.

Doğrudan sürüm teknik özellikleri çözümlemesi

Belirttiğiniz bağımlılıkların sürümleri, sürüm çözümü için aday olur.

Örneğin, app/build.gradle.kts öğenizde bağımlılık olarak androidx.compose.ui:ui kitaplığının 1.7.3 sürümünü istemek için:

dependencies {
    implementation("androidx.compose.ui:ui:1.7.3")
}

1.7.3 sürümü aday sürüm haline gelir. Gradle, 1.7.3 ve geçişli bağımlılıklar tarafından istenen aynı kitaplığın diğer sürümleri arasında en yeni sürümü çözer.

Sürüm kataloğu çözümlemesi

Sürüm katalogları, uygulamanız genelinde kullanılan bağımlılıkların sürümünü izlemek için değişkenler tanımlar. Sürüm kataloğundan bir değişken kullanırsanız bu değişkenin belirtilen bağımlılıkları sürüm çözümleme adaylarına eklenir. Sürüm kataloğunda kullanılmayan değişkenler yoksayılır.

Örneğin, gradle/libs.versions.toml dosyanızda androidx.compose.ui:ui'nin 1.7.3 sürümünü bağımlılık olarak belirtmek için:

[versions]
ui = "1.7.3"

[libraries]
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "ui" }

Bu, kitaplığı temsil edecek libs.androidx.compose.ui adlı bir değişkeni tanımlar. Bağımlılığı belirtmek için ilgili değişkeni kullanmadığınız sürece bu sürüm aday olarak kabul edilmez.

app/build.gradle.kts üzerinden kitaplığı ve sürümünü istemek için:

dependencies {
    implementation(libs.androidx.compose.ui)
}

Gradle, doğrudan spesifikasyonda olduğu gibi çözüm bulur.

Birim malzeme listesi (BOM) çözünürlüğü

BOM'de görünen tüm kitaplıkların sürümleri, sürüm çözümü için aday haline gelir. Kitaplıkların yalnızca doğrudan veya dolaylı olarak belirtildiğinde bağımlılık olarak kullanıldığını unutmayın. BOM'daki diğer kitaplıklar yoksayılır.

BOM sürümleri, doğrudan bağımlılıklarınızın yanı sıra BOM'da görünen tüm geçişli bağımlılıklarınızı etkiler.

Örneğin, app/build.gradle.kts dosyanızda platform bağımlılık olarak bir BOM belirtin:

dependencies {
    implementation(platform("androidx.compose:compose-bom:2024.10.00"))
    implementation("androidx.compose.ui:ui")
}

Bağımlılık olarak kullanmak istediğiniz kitaplıklar sürüm spesifikasyonu gerektirmez. İstenen sürüm BOM'den gelir.

BOM ve kitaplıklar için değişkenler oluşturmak üzere bir sürüm kataloğu kullanabileceğinizi de unutmayın. BOM bağımlılığında görünen kitaplıklar için sürüm kataloğundaki sürüm numaralarını çıkarın.

Örneğin, sürüm kataloğunuz BOM'u ve BOM'un sürüm numarasını içerir ancak BOM'dan referans verdiğiniz kitaplıklar için bir sürüm belirtmez:

[versions]
composeBom = "2024.10.00"

[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }

app/build.gradle.kts, sürüm kataloğunda tanımlanan değişkenleri kullanarak BOM'a ve kitaplıklara referans verir:

dependencies {
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.compose.ui)
}

BOM'da belirtilen kitaplığın sürümü, Gradle'ın çözümü için aday olur. Ayrıca, doğrudan bağımlılık olarak kullanıp kullanmadığınıza bakılmaksızın, BOM'da belirtilen diğer tüm kitaplık sürümleri de aday sürüm olur.

Örneğin, bir BOM'da A, B ve C kitaplıklarının sürümleri belirtildiğini varsayalım. Uygulamanız, D kitaplığının yanı sıra A kitaplığını da doğrudan bağımlı olarak kullanmak istiyor. D kitaplığı, B kitaplığını bağımlı olarak kullanır. C kitaplığını hiçbir şey kullanmaz.

Bir BOM, A, B ve C kitaplıklarının sürümlerini içerir. Uygulamanız, A ve D kitaplıklarını bağımlılık olarak kullanıyor. D kitaplığı, B kitaplığını bağımlı olarak kullanır. C Kitaplığı bu uygulamada doğrudan veya dolaylı olarak kullanılmaz.
Şekil 3. BOM senaryosu.

A, B ve D kitaplıkları uygulamadaki bağımlılar, C kitaplığı ise yoksayılır. Gradle, bağımlılık olarak doğrudan B kitaplığını belirtmeseniz bile BOM'de belirtilen A ve B sürümlerini aday olarak kullanır.

D kitaplığı, B kitaplığının 2.0.1'den eski bir sürümünü istediyse Gradle 2.0.1'i çözer. D kitaplığı, B kitaplığının daha yüksek bir sürümünü istediyse Gradle bu sürüme çözüm bulur.