Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Varsayılan Cargo Özellik Çözücüsü

Özet

  • Cargo.toml içindeki edition = "2021" ayarı, resolver = "2" anlamına gelir.

Ayrıntılar

Rust 1.51.0’dan beri Cargo, Cargo.toml içinde resolver = "2" ile etkinleştirilen yeni bir özellik çözücüsünü isteğe bağlı olarak destekliyor.

Rust 2021 ile birlikte bu varsayılan hale geldi. Yani Cargo.toml dosyasına edition = "2021" yazmak, resolver = "2" demek olur.

Çözücü, bir çalışma alanı için geçerli olan genel bir ayardır ve bağımlılıkların içinde yazıldığında dikkate alınmaz. Bu ayar yalnızca çalışma alanının en üst düzey paketinde geçerlidir. Eğer bir sanal çalışma alanı kullanıyorsanız, yeni çözücüyü etkinleştirmek için [workspace] tanımında [resolver alanını] ayrıca açıkça ayarlamanız gerekir.

Yeni özellik çözücüsü, birden fazla yolla bağımlı olunan crate’ler için istenen tüm özellikleri artık tek bir yerde birleştirmez. Ayrıntılar için Rust 1.51 duyurusuna bakabilirsiniz.

Taşıma

Yeni çözücüye geçiş için otomatik bir taşıma aracı yoktur. Çoğu projede bu güncellemenin etkisi ya çok az olur ya da hiç olmaz.

cargo fix --edition ile güncelleme yaparken, yeni çözücü bağımlılıkları farklı özelliklerle derleyecekse Cargo bir rapor gösterir. Bu rapor şu şekilde görünebilir:

not: Edition 2021’e geçmek, Cargo içinde 2. sürüm özellik çözücüsünün kullanımını etkinleştirir. Bu durum, bazı bağımlılıkların eskisine göre daha az özellikle derlenmesine yol açabilir. Çözücü değişiklikleri hakkında daha fazla bilgi için: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/default-cargo-resolver.html
Aşağıdaki bağımlılıklar derlenirken, belirtilen özellikler artık kullanılmayacaktır:

  bstr v0.2.16: default, lazy_static, regex-automata, unicode
  libz-sys v1.1.3 (as host dependency): libc

Bu rapor, bazı bağımlılıkların artık belirtilen özelliklerle derlenmeyeceğini bildirir.

Derleme hataları

Bazı durumlarda bu değişiklikten sonra projeniz doğru şekilde derlenmeyebilir. Bir paketteki bağımlılık bildirimi, başka bir yerde bazı özelliklerin etkin olduğunu varsayıyorsa ve bu özellikler artık kapalıysa, derleme başarısız olabilir.

Örneğin şöyle bir bağımlılığımız olduğunu düşünelim:

# Cargo.toml

[dependencies]
bstr = { version = "0.2.16", default-features = false }
# ...

Bağımlılık ağacımızın başka bir yerinde de başka bir paket şuna sahip olsun:

# Another package's Cargo.toml

[build-dependencies]
bstr = "0.2.16"

Biz de paketimizde bstr içindeki words_with_breaks metodunu kullanıyor olalım. Bu metodun çalışması için bstr crate’inin unicode özelliğinin etkin olması gerekir. Tarihsel olarak bu çalışıyordu; çünkü Cargo iki paket arasında bstr özelliklerini birleştiriyordu. Ancak Rust 2021’e geçtikten sonra yeni çözücü bstryi iki kez derler: biri varsayılan özelliklerle build-dependency olarak, diğeri ise normal bağımlılığımız olarak özelliksiz biçimde. Böylece bstr, unicode özelliği olmadan derlenmiş olur ve words_with_breaks metodu ortada olmadığı için derleme eksik metod hatasıyla başarısız olur.

Buradaki çözüm, bağımlılığı gerçekten kullandığınız özelliklerle birlikte bildirdiğinizden emin olmaktır. Örneğin:

[dependencies]
bstr = { version = "0.2.16", default-features = false, features = ["unicode"] }

Bazı durumlarda sorun, doğrudan kontrolünüzün olmadığı bir üçüncü taraf bağımlılıktan kaynaklanabilir. Böyle bir durumda, sorunlu bağımlılık için doğru özellik kümesini bildirmesi amacıyla ilgili projeye bir yama göndermeyi düşünebilirsiniz. Alternatif olarak, kendi Cargo.toml dosyanızdan da herhangi bir bağımlılığa özellik ekleyebilirsiniz. Örneğin yukarıdaki bstr bildirimi üçüncü taraf bir bağımlılıkta yer alıyorsa, doğru bağımlılık bildirimini kendi projenize kopyalamanız yeterlidir. Özellikler, yeni çözücünün birleştirme kurallarıyla uyumlu oldukları sürece birleştirilir. Bu kurallar şunlardır:

  • O anda derlenmeyen hedefler için platforma özgü bağımlılıklarda etkin olan özellikler yok sayılır.
  • Build-dependencies ve proc-macro’lar, normal bağımlılıklarla özellik paylaşmaz.
  • Dev-dependencies, onlara ihtiyaç duyan bir hedef derlenmedikçe özellik etkinleştirmez; örneğin testler ya da örnekler gibi.

Gerçek dünyadan bir örnek olarak diesel ile diesel_migrations kullanımını düşünebiliriz. Bu paketler veritabanı desteği sağlar ve hangi veritabanının kullanılacağı bir özellik ile seçilir:

[dependencies]
diesel = { version = "1.4.7", features = ["postgres"] }
diesel_migrations = "1.4.0"

Sorun şu ki diesel_migrations içinde, kendisi de diesele bağlı olan bir iç proc-macro bulunur. Bu proc-macro, kendi diesel kopyasında bağımlılık ağacının geri kalanıyla aynı özelliklerin etkin olduğunu varsayar. Yeni çözücüye geçtikten sonra bu varsayım bozulur; çünkü artık iki ayrı diesel kopyası vardır ve proc-macro için derlenen kopyada postgres özelliği eksiktir.

Buradaki çözüm, dieseli gerekli özelliklerle bir build-dependency olarak eklemektir. Örneğin:

[build-dependencies]
diesel = { version = "1.4.7", features = ["postgres"] }

Bu sayede Cargo, host bağımlılıkları için postgres özelliğini de ekler; yani proc-macro’lar ve build-dependencies tarafında da bu özellik etkin olur. Böylece diesel_migrations proc-macro’su postgres özelliğini alır ve doğru şekilde derlenir.

dieselin 2.0 sürümünde, bu bağımlılık gereksinimi ortadan kaldırılacak şekilde yeniden yapılandırma yapıldığı için bu sorun bulunmaz.

Özellikleri incelemek

cargo tree komutu, yeni çözücüye geçişi kolaylaştırmak için önemli ölçüde iyileştirildi. cargo tree, bağımlılık ağacını incelemek ve hangi özelliklerin etkin olduğunu, daha da önemlisi neden etkin olduğunu görmek için kullanılabilir.

Bunun bir yolu --duplicates bayrağını kullanmaktır; kısa hali -ddir. Bu bayrak size bir paketin birden fazla kez derlendiğini gösterir. Az önceki bstr örneğinde şöyle bir çıktı görebiliriz:

> cargo tree -d
bstr v0.2.16
└── foo v0.1.0 (/MyProjects/foo)

bstr v0.2.16
[build-dependencies]
└── bar v0.1.0
    └── foo v0.1.0 (/MyProjects/foo)

Bu çıktı, bstrnin iki kez derlendiğini ve her iki durumda da bu bağımlılığın hangi zincir üzerinden geldiğini gösterir.

Her paketin hangi özellikleri kullandığını -f bayrağıyla da yazdırabilirsiniz:

cargo tree -f '{p} {f}'

Bu, Cargo’ya çıktının “biçimini” değiştirmesini söyler; böylece hem paketi hem de etkin özellikleri yazdırır.

Hangi “kenarların” gösterileceğini belirtmek için -e bayrağını da kullanabilirsiniz. Örneğin cargo tree -e features, her bağımlılığın araya hangi özellikleri eklediğini gösterir. Bu seçenek, ağacı “ters çevirmek” için kullanılan -i bayrağıyla birlikte daha da yararlı hale gelir. Böylece özelliklerin belirli bir bağımlılığa nasıl aktığını görebilirsiniz. Örneğin bağımlılık ağacı büyükse ve bstrye tam olarak kimin bağımlı olduğunu bilmiyorsanız, aşağıdaki komut bunu gösterir:

> cargo tree -e features -i bstr
bstr v0.2.16
├── bstr feature "default"
│   [build-dependencies]
│   └── bar v0.1.0
│       └── bar feature "default"
│           └── foo v0.1.0 (/MyProjects/foo)
├── bstr feature "lazy_static"
│   └── bstr feature "unicode"
│       └── bstr feature "default" (*)
├── bstr feature "regex-automata"
│   └── bstr feature "unicode" (*)
├── bstr feature "std"
│   └── bstr feature "default" (*)
└── bstr feature "unicode" (*)

Bu çıktı parçası, foo projesinin bara default özelliğiyle bağımlı olduğunu gösterir. Ardından bar, bstrye build-dependency olarak yine default özelliğiyle bağımlıdır. Buradan ayrıca bstrnin default özelliğinin, başka özelliklerin yanında unicode özelliğini de etkinleştirdiğini görebiliriz.