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, genel bağımlılık grafiğinizi hızla büyütür ve genellikle çakışan sürümler içerir.

minor (yeni özellikler) veya patch (hata düzeltmeleri) bölümleri değiştiğinde kitaplığın uyumlu olma olasılığı yüksektir ve uygulamanızı etkileme olasılığı düşüktür.

Örneğin, uygulamanızın A ve B kitaplıklarına bağlı olduğunu ve bu kitaplıkların 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çer.
Şekil 1. Geçişli sürüm çakışması. Gradle, varsayılan olarak en yeni sürüme çözüm bulur.

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ında sorunlara neden olabilir. Bu örnekte C kitaplığı 2.1.1 olarak çözüldü ancak A kitaplığının C kitaplığının 1.0.3 sürümü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 daha yeni bir 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 çözüm bulur ve uygulamanız bu yeni sürümü görür.

Bu gibi durumlarda, daha yeni aktarıcı bağımlılıklar uygulamanızda doğrudan istediğ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 üçüncü taraf eklentilerini kullanabilirsiniz. Bu çözümdeki değişiklikleri karşılaştırmak, yükseltme işleminin risklerini anlamak ve azaltmak için önemlidir.

Örneğin, uygulama modülünüzün kullandığı tüm bağımlılıkların ağacını görüntülemek için ./gradlew app:dependencies çalıştırarak Gradle dependencies görevini kullanabilirsiniz. Bu aracı, kitaplıkları 2. resimde gösterildiği gibi kullanan bir uygulamaya uyguladığımızda aşağıdakileri görürüz:

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 -> gördüğünüzde, bir istekleyici (uygulamanız veya başka bir kitaplık) söz konusu bağımlılık için beklemediği bir sürümü kullanıyor demektir. Çoğu kitaplık geriye dönük uyumluluk için yazıldığı için bu durum çoğu durumda soruna yol açmaz. Ancak bazı kitaplıklar uyumlu olmayan değişiklikler yapabilir. 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 bir sürüm kataloğunda veya bir Malzeme Listesi'nde (BOM) belirtebilirsiniz.

Doğrudan sürüm spesifikasyonu çözünürlüğü

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 uygulamanızda androidx.compose.ui:ui kitaplığının 1.7.3 sürümünü bağımlı olarak istemek için:

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

1.7.3 sürümü, aday sürüm olur. 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ünürlüğü

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ümü için adaylara eklenir. Sürüm kataloğunda kullanılmayan değişkenler yoksayılır.

Örneğin, androidx.compose.ui:ui dosyasının 1.7.3 sürümünü gradle/libs.versions.toml dosyanızda 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 etmek için libs.androidx.compose.ui adlı bir değişken tanımlar. Bir bağımlılığı belirtmek için bu değişkeni kullanmadığınız sürece bu sürüm aday olarak değerlendirilmez.

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

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

Gradle, doğrudan bir spesifikasyon için yaptığı şekilde çözümler.

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

BOM'da görünen tüm kitaplıkların sürümleri, sürüm çözümü için aday olur. Kitaplıkların yalnızca doğrudan veya dolaylı olarak belirtildiği durumlarda 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 için sürüm belirtmeniz gerekmez. İstenen sürüm, BOM'den alınır.

BOM ve kitaplıklar için değişken oluşturmak üzere bir sürüm kataloğu da kullanabileceğinizi 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ığı hiçbir yerde kullanılmaz.

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, B kitaplığını doğrudan bağımlılık olarak belirtmemiş olsanız bile BOM'da 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.