Mobil geliştirmede Rust paylaşımlı çekirdek, iOS ve Android için aynı iş mantığını iki kez yazmak yerine tek bir Rust kütüphanesinde toplayıp her iki platforma da bağlama (binding) üretmek anlamına gelir. Bu yazıda UniFFI ile gerçek bir Rust modülünü Kotlin ve Swift tarafına nasıl taşıyacağını, cargo-ndk ve XCFramework'ün araç zincirindeki yerini, FFI sınırında hata yönetimini ve bu yaklaşımın ne zaman KMP veya native Swift/Kotlin'e göre mantıklı olmadığını adım adım göreceksin.
💡 Pro Tip: UniFFI'yi projenin en başından "tek kaynak, iki binding" olarak kur — sonradan eklemeye çalışmak, zaten yazılmış platform-özel arayüzleri geriye doğru UniFFI tiplerine uydurmak anlamına gelir ve bu genelde ilk kurulumdan daha maliyetlidir.
İçindekiler
- Neden Rust Çekirdek: Hangi Problemleri Çözer
- Araç Zinciri: cargo-ndk, XCFramework, UniFFI
- İlk Paylaşımlı Modül: Uçtan Uca Örnek
- FFI Sınırında Hata ve Bellek Yönetimi
- Derleme Süresi ve Binary Boyutu Gerçeği
- CI'da İki Platformu Birlikte Kurmak
- Ne Zaman Rust Yerine KMP veya Swift Seçilmeli
- SSS
- Rust ile iOS ve Android'de ortak kod nasıl paylaşılır?
- UniFFI nedir ve ne işe yarar?
- Rust mobil çekirdek üretimde mantıklı mı?
- cargo-ndk olmadan Android için Rust derlenebilir mi?
- UniFFI'de hata yönetimi nasıl çalışır?
- Güncelleme (Eylül 2026)
- Sonuç
- Kaynaklar
Neden Rust Çekirdek: Hangi Problemleri Çözer
İki platformda aynı iş kuralını (fiyatlandırma motoru, senkronizasyon algoritması, şifreleme katmanı gibi) ayrı ayrı Swift ve Kotlin'de yazdığında, iki farklı ekip iki farklı bug yüzeyiyle uğraşır. Rust çekirdek yaklaşımı bu mantığı tek bir yerde tutar ve her iki platforma da aynı davranışı garanti eder.
Android'in resmi geliştirici dokümantasyonu (AOSP), Rust'ı "bellek güvenliği garantileri sunan, C/C++ ile eşdeğer performansa sahip modern bir sistem programlama dili" olarak tanımlar. Aynı sayfa, Rust'ın "Fearless Concurrency" (korkusuz eşzamanlılık) sloganına da referans verir — güvenli eşzamanlı kod yazmayı kolaylaştıran derleyici garantileri sayesinde.
Bu iddiaların kaynağı somut: AOSP'nin resmi "Android Rust introduction" sayfası, Google'ın native OS bileşenlerinde Rust'ı nasıl konumlandırdığını anlatıyor ve platformun Rust'a güvenlik açısından bilinçli bir bahis oynadığını gösteriyor. Sayfa, Rust'ın Android'e girişini üç ayrı Google Security Blog yazısına ("Rust in the Android Platform", "Integrating Rust into the Android Open Source Project", "Rust/C++ interop in the Android Platform") bağlıyor; bu üçlü hâlâ platformun Rust yaklaşımının referans noktası.
Mobil tarafta bu genel platform desteği başlı başına "paylaşımlı çekirdek" değildir — asıl fayda, bu Rust kodunu her iki mobil platforma da tek kaynaktan dağıtabilmekten gelir. İşte tam burada UniFFI devreye giriyor.
- Ne değildir: Rust çekirdek, UI katmanını değiştirmez; SwiftUI/Jetpack Compose yerine geçmez.
- Ne içindir: Platformdan bağımsız iş mantığı, kriptografi, veri senkronizasyonu, parser/algoritma katmanları.
- Kime uygun değildir: Küçük ekip + tek platformda kalacak basit CRUD uygulaması — bu durumda Rust'ın öğrenme eğrisi maliyeti fayda sağlamaz (bu konuyu son bölümde detaylandırıyoruz).
Araç Zinciri: cargo-ndk, XCFramework, UniFFI
Paylaşımlı Rust çekirdeğini mobile taşıyan üç parça var: Rust kodunu derleyen araçlar, platform-özel paket formatları ve dil bağlamalarını üreten kod üretici.
Android tarafı — cargo-ndk: cargo-ndk, Rust kodunu Android NDK hedefleri için derlemeyi kolaylaştıran bir cargo eklentisidir; UniFFI'nin kendi README'sindeki "External resources" bölümü de ona atıf verir ("Cargo NDK Gradle Plugin allows you to build Rust code using cargo-ndk, which generally makes Android library builds less painful"). Önemli bir davranış değişikliği: v4.0.0 (30 Temmuz 2025) ile cargo-ndk çıktıyı varsayılan olarak strip etmiyor ve --no-strip seçeneği kaldırıldı; sembol temizliğini Cargo'nun [profile.release] strip = true ayarıyla sen yaparsın.
iOS tarafı — XCFramework: Apple'ın resmi yolu, farklı platform ve mimarilere ait ikili dosyaları (arm64 cihaz, arm64/x86_64 simülatör) tek bir pakette birleştirip Swift Package Manager veya doğrudan Xcode projesine dağıtmaktır. Bu paket formatının adı XCFramework'tür ve Apple'ın "Creating a multiplatform binary framework bundle" resmi rehberi bu süreci anlatır.
Bağlama üretici — UniFFI: Mozilla'nın geliştirdiği UniFFI, Rust kütüphanelerinden çoklu-dil (Kotlin, Swift, Python, Ruby) bağlaması üreten resmi araç setidir. UniFFI hâlâ 1.0 sürümüne ulaşmamış olsa da proje kendisini üretime hazır kabul ediyor — nitekim Firefox'un mobil ve masaüstü tarayıcılarında üretimde kullanılıyor: Rust'ta bir kez yazılan kod, otomatik üretilen bağlamalar sayesinde hem Kotlin hem Swift'ten çağrılabiliyor.
Katman | Araç | Görev | Platform |
|---|---|---|---|
Derleme (Android) | cargo-ndk | Rust → NDK hedefleri (.so) | Android |
Paketleme (iOS) | XCFramework | Çoklu mimari ikili birleştirme | iOS |
Bağlama üretimi | UniFFI | Rust → Kotlin/Swift kod üretimi | Her ikisi |
Arayüz tanımı | .udl dosyası veya proc-macro | Rust API yüzeyini tanımlama | Ortak |
UniFFI'nin arayüz tanımlama konusunda iki yolu var: klasik .udl dosyası (WebIDL tabanlı bir Interface Definition Language) veya doğrudan Rust kodunun içine yazılan proc-macro'lar (#[uniffi::export] gibi). Yeni projelerde proc-macro yaklaşımı, arayüz tanımını Rust kaynağıyla aynı yerde tuttuğu için daha az senkronizasyon hatası üretir.
Bu makalenin yazıldığı tarihte (Ekim 2025) UniFFI'nin güncel sürümü v0.30.0'dı — bir gün önce etiketlenmişti. Sürüm numarasını burada anmamızın nedeni sonraki bölümlerdeki komut örneklerinin bu sürüm ailesiyle uyumlu olması; kendi projende her zaman cargo add uniffi ile o anki güncel sürümü çekmelisin.
İlk Paylaşımlı Modül: Uçtan Uca Örnek
Basit bir hesaplama çekirdeği üzerinden ilerleyelim. Önce Rust tarafında kütüphaneyi kuruyoruz:
toml
1# Cargo.toml2[package]3name = "mathcore"4version = "0.1.0"5edition = "2021"6 7[lib]8crate-type = ["cdylib", "staticlib", "lib"]9 10[dependencies]11# "cli" feature'ı olmadan uniffi::uniffi_bindgen_main() derlenmez12uniffi = { version = "0.30.0", features = ["cli"] }13 14[build-dependencies]15uniffi = { version = "0.30.0", features = ["build"] }Arayüzü proc-macro ile tanımlıyoruz — .udl dosyasına gerek kalmadan Rust kodunun içinde:
rust
1// src/lib.rs2uniffi::setup_scaffolding!();3 4#[uniffi::export]5fn add(a: i32, b: i32) -> i32 {6 a + b7}8 9#[derive(uniffi::Record)]10pub struct CalcResult {11 pub value: i32,12 pub overflow: bool,13}Tek-crate senaryosunda uniffi-bindgen'i çalıştırılabilir bir binary olarak kurman gerekiyor. Cargo.toml'a bir [[bin]] girişi ekleyip uniffi::uniffi_bindgen_main() çağıran küçük bir main.rs yazman yeterli (çoklu-crate workspace'lerde bunun yerine ayrı bir uniffi-bindgen crate'i oluşturulur). Bindgen CLI'si uniffi crate'inin cli feature'ı arkasındadır: ya bağımlılığa features = ["cli"] eklersin ya da komutu --features=uniffi/cli ile çalıştırırsın (aşağıda ikisi de var):
rust
1// src/bin/uniffi-bindgen.rs2fn main() {3 uniffi::uniffi_bindgen_main()4}Swift başlık/modulemap üretimi için aynı yöntemle ikinci bir binary kuruyoruz:
rust
1// src/bin/uniffi-bindgen-swift.rs2fn main() {3 uniffi::uniffi_bindgen_swift()4}UniFFI'nin kütüphane-modu (generate --library) yaklaşımı, derlenmiş cdylib/.so dosyasından doğrudan binding üretmene izin verir — bu, ayrı bir .udl dosyası belirtmekten daha kullanışlıdır çünkü arayüz zaten proc-macro ile Rust kodunun içinde tanımlı. Akış şöyle işler:
bash
1# 1) Rust kütüphanesini derle2cargo build --release3 4# 2) Kotlin bağlamalarını kütüphane-modundan üret5cargo run --features=uniffi/cli --bin uniffi-bindgen generate \6 --library target/release/libmathcore.so \7 --language kotlin \8 --out-dir out/kotlin9 10# 3) Android hedefleri için cargo-ndk ile çapraz derle11cargo ndk -t arm64-v8a -t armeabi-v7a -t x86_64 \12 -o app/src/main/jniLibs build --releaseKotlin tarafında üretilen kod, CalcResult veri sınıfını ve add() fonksiyonunu doğrudan Kotlin tipleriyle sunar — JNI köprüsünü elle yazmana gerek kalmaz:
kotlin
1// Android — üretilen binding kullanımı2import uniffi.mathcore.add3import uniffi.mathcore.CalcResult4 5val sonuc: Int = add(3, 4)iOS tarafında aynı adım Swift bağlamaları üretir, ardından ürettiğin statik kütüphaneler ile başlık/modulemap dosyaları Apple'ın XCFramework aracıyla tek pakette birleştirilir:
bash
1# iOS hedeflerini kur ve çapraz derle2rustup target add aarch64-apple-ios aarch64-apple-ios-sim3cargo build --release --target aarch64-apple-ios && cargo build --release --target aarch64-apple-ios-sim4 5# Swift kaynağı + başlık + XCFramework uyumlu modulemap'i tek çağrıda üret6cargo run --features=uniffi/cli --bin uniffi-bindgen-swift -- \7 target/release/libmathcore.a out/swift \8 --swift-sources --headers --modulemap --xcframework9 10# iOS + simülatör mimarilerini XCFramework'te birleştir11xcodebuild -create-xcframework \12 -library target/aarch64-apple-ios/release/libmathcore.a \13 -headers out/swift \14 -library target/aarch64-apple-ios-sim/release/libmathcore.a \15 -headers out/swift \16 -output MathCore.xcframeworkswift
1// iOS — üretilen binding kullanımı2// Üretilen out/swift/*.swift hedefine eklenir; XCFramework C katmanını taşır.3let sonuc: Int32 = add(a: 3, b: 4)Dikkat edeceğin nokta: Rust tarafındaki tip isimleri (i32, CalcResult) her iki platformda da otomatik olarak dile uygun karşılıklarına (Int/Int32, veri sınıfı/struct) çevrilir — bunu elle senkronize etmen gerekmez, UniFFI'nin asıl kazandırdığı zaman burada.
FFI Sınırında Hata ve Bellek Yönetimi
Rust ile Kotlin/Swift arasındaki sınır (FFI — foreign function interface), iki farklı bellek modelinin buluştuğu yerdir: Rust'ın sahiplik (ownership) sistemi ile Kotlin/Swift'in çöp toplayıcı/ARC tabanlı modelleri. UniFFI bu sınırı senin için soyutlar, ama nasıl çalıştığını bilmek hata ayıklarken kritik.
Hata yönetimi tarafında UniFFI, Rust'ın Result<T, E> tipini foreign dillerin kendi hata mekanizmalarına eşler: Kotlin'de bir Exception alt sınıfına, Swift'te bir Error uyumlu enum'a. Yani Rust tarafında Err(...) döndüren bir fonksiyon, Kotlin tarafında try/catch ile, Swift tarafında do/catch ile yakalanabilir hale gelir — bunu elle köprülemene gerek kalmaz.
rust
1#[derive(uniffi::Error, Debug)]2pub enum MathError {3 Overflow,4 DivisionByZero,5}6 7#[uniffi::export]8fn safe_divide(a: i32, b: i32) -> Result<i32, MathError> {9 if b == 0 {10 return Err(MathError::DivisionByZero);11 }12 a.checked_div(b).ok_or(MathError::Overflow)13}Bellek yönetimi tarafında ise ayrımı doğru kurman gerekiyor: Record ve Enum'lar sınırdan değer olarak (kopyalanarak) geçer — yukarıdaki CalcResult gibi; yalnız Interface/Object tipleri Arc<> arkasında referansla taşınır. Resmi dokümanın ifadesiyle: "Interfaces are passed by reference so can not have data items - unlike a Record or Enum, which are passed by value so only have data fields and no methods." Swift tarafında ARC bu referansı kendisi bırakır, ama Kotlin'de her Object örneğini açıkça destroy() etmen (ya da .use { } bloğu kullanman) gerekir — record alanlarında duran Object'ler için de geçerlidir. Büyük veri (ör. görsel byte dizileri) her sınır geçişinde kopyalanacağı için, yoğun veri akışlarında bu kopyalama maliyetini hesaba katmalısın. Bu makalenin yazıldığı sürüm ailesinde (v0.30.0) sıfır-kopya (zero-copy) byte buffer desteği yoktu; bu konudaki güncel durumu makalenin sonundaki "Güncelleme" bölümünde bulabilirsin.
Derleme Süresi ve Binary Boyutu Gerçeği
Binary boyutu ve derleme süresi projeden projeye değişir — kod boyutu, bağımlılık sayısı ve hedef mimari sayısı birlikte belirler. Kontrol edebileceğin dört değişken var:
- cargo-ndk artık varsayılan olarak strip etmez: v4.0.0 (30 Temmuz 2025) kırıcı değişikliğiyle araç çıktıyı varsayılan olarak strip etmeyi bıraktı ve
--no-stripseçeneği kaldırıldı; temizliğiCargo.toml'da[profile.release] strip = trueile sen açmalısın. - LTO (Link-Time Optimization) açık bir seçenektir:
Cargo.toml'da[profile.release] lto = trueile derleyiciye çapraz-crate optimizasyon yaptırabilirsin; bu genelde binary'yi küçültür ama derleme süresini uzatır. opt-level = "z": Boyutu hız yerine öncelikli optimize eden standart bir Rust derleyici bayrağıdır; performans-kritik olmayan modüllerde tercih edilebilir.- Mimari sayısı doğrudan çarpandır:
arm64-v8a+armeabi-v7a+x86_64gibi üç Android ABI'si için ayrı ayrı derleme yapman, toplam APK/AAB boyutuna üç kat katkı sağlar — Play Store'un App Bundle mekanizması bu maliyeti dağıtımda azaltır ama derleme tarafında hâlâ üç ayrı derleme gerekir.
Kısacası: "Rust binary'si küçüktür/büyüktür" gibi genel bir iddiada bulunmak yerine, bu dört kontrol noktasını kendi projende ölçmen gereken değişkenler olarak gör.
CI'da İki Platformu Birlikte Kurmak
Paylaşımlı çekirdeğin en pratik faydası, tek bir CI pipeline'ında hem Android hem iOS hedeflerini aynı Rust kaynağından derleyebilmen. cargo-ndk çapraz-platform CI senaryolarını hedefleyen bir araç olarak tasarlandı — Windows dahil farklı işletim sistemlerinde çalışabilir, bu da geliştirici makinesi Linux/macOS/Windows fark etmeksizin Android hedeflerini derleyebilmen anlamına gelir.
Tipik bir CI akışı şöyle sıralanır:
- Rust toolchain kurulumu —
rustup target addile Android (aarch64-linux-android,armv7-linux-androideabi) ve iOS (aarch64-apple-ios,aarch64-apple-ios-sim) hedeflerini ekle. - cargo-ndk kurulumu — yalnız Android job'unda gerekir; iOS job'u macOS runner'ında doğrudan
cargo build --target aarch64-apple-iosile çalışabilir. - Bağlama üretimi — her iki job da aynı
uniffi-bindgenkomutunu, farklı--languagebayrağıyla çalıştırır. - Paketleme — Android job'u
.sodosyalarınıjniLibs'e kopyalar, iOS job'uxcodebuild -create-xcframeworkile paketler. - Yayınlama — her iki çıktı da kendi platform paket yöneticisine (Maven local/Android Archive, Swift Package) gönderilir.
Pratikte tuzak, iOS ve Android job'larının Rust kaynak kodunu aynı commit'ten derlediğinden emin olmak — iki platformun binding'lerinin farklı Rust sürümlerinden üretilmesi, ince davranış farkları (özellikle hata mesajı formatlaması) yaratabilir.
Ne Zaman Rust Yerine KMP veya Swift Seçilmeli
Rust paylaşımlı çekirdek her senaryoya uymaz. UniFFI'nin kendi proje sahipleri bile aracın "üretime hazır ama 1.0'dan uzak, dahili çalışmaları hâlâ süren" bir araç olduğunu açıkça belirtiyor — bu, API kırılma riskini üstlenmeyi göze alman gerektiği anlamına gelir.
Alternatiflerle kıyaslandığında karar noktaları şöyle özetlenebilir:
Kriter | Rust + UniFFI | Kotlin Multiplatform (KMP) | Ayrı native (Swift+Kotlin) |
|---|---|---|---|
Ekip yetkinliği | Rust bilgisi gerekir | Kotlin bilgisi yeterli | Her platform kendi dilinde |
Kod paylaşımı | Tam (çekirdek mantık) | Tam (çekirdek mantık) | Yok |
Ekosistem olgunluğu | 1.0 öncesi, API kırılabilir | JetBrains resmi desteği | En olgun, platform-native |
Tipik kullanım alanı | Kripto/parser/algoritma çekirdeği | İş mantığı + kısmi UI paylaşımı | Küçük/orta ölçekli tek-özellik uygulamalar |
UniFFI'nin kendi ekosisteminde Kotlin Multiplatform'a bir köprü de var: üçüncü taraf "Gobley" projesi, UniFFI çıktısını doğrudan KMP hedeflerine (JVM + Native) bağlıyor. Bunu "Rust ile KMP birbirini dışlar" değil, "ihtiyaca göre birlikte de kullanılabilir" şeklinde okumalısın.
Rust çekirdeği şu durumlarda mantıklı:
- Kriptografi/güvenlik katmanı — tek yerde denetlenen, iki platforma da aynı davranışı garanti eden kod.
- Karmaşık senkronizasyon/parser algoritmaları — platformdan bağımsız, yoğun test edilen iş mantığı.
- Zaten Rust ekibin varsa — masaüstü/backend tarafında Rust kullanan bir ekip, mobil çekirdeği aynı dile taşıyarak bilgi tekrarını önler.
Rust çekirdeği şu durumlarda mantıklı DEĞİL:
- Küçük ekip, tek platform öncelikli MVP — UniFFI'nin araç zinciri kurulum maliyeti (cargo-ndk, XCFramework, CI eşleştirmesi) kısa vadede kaybettirir.
- UI-ağırlıklı özellikler — Rust çekirdek UI katmanını kapsamaz, bu senaryoda KMP'nin
compose-multiplatformgibi UI-paylaşım seçenekleri daha uygun olabilir. - Ekipte Rust deneyimi hiç yoksa ve zaman baskısı varsa — öğrenme eğrisi + FFI hata ayıklama karmaşıklığı, teslim tarihini riske atar.
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
Okuyucu Ödülü
Bu makaleyi bitirdiğinde kendi Rust paylaşımlı çekirdek modülünü sıfırdan kurmuş olacaksın. Aşağıdaki checklist, anlattığımız adımları eksiksiz uyguladığını doğrulaman için; her maddeyi sırayla işaretle.
SSS
Rust ile iOS ve Android'de ortak kod nasıl paylaşılır?
Rust tarafında platformdan bağımsız iş mantığını tek bir kütüphane olarak yazarsın, sonra UniFFI ile bu kütüphaneden Kotlin ve Swift bağlamaları üretirsin. Android tarafında cargo-ndk ile .so dosyaları derlenip jniLibs klasörüne, iOS tarafında ise statik kütüphaneler XCFramework'e paketlenip Xcode projesine eklenir. Uygulama kodun (SwiftUI/Compose) bu üretilen bağlamaları normal bir yerel kütüphaneymiş gibi çağırır.
UniFFI nedir ve ne işe yarar?
UniFFI, Mozilla'nın geliştirdiği ve Rust kütüphanelerinden Kotlin, Swift, Python, Ruby gibi dillere otomatik bağlama üreten bir araç setidir. Arayüzü ya .udl dosyasıyla ya da doğrudan Rust kodu içindeki proc-macro'larla tanımlarsın; UniFFI geri kalan JNI/C-ABI köprü kodunu senin için üretir. Firefox'un mobil ve masaüstü tarayıcıları bu aracı üretimde kullanıyor.
Rust mobil çekirdek üretimde mantıklı mı?
Kriptografi, senkronizasyon algoritması veya parser gibi platformdan bağımsız, yoğun test edilen iş mantığı için evet — tek kaynaktan iki platforma aynı davranışı garanti eder. Ama UniFFI henüz 1.0 sürümüne ulaşmadı ve proje sahipleri bunu açıkça "dahili çalışmaları süren" bir araç olarak tanımlıyor; küçük ekipli, UI-ağırlıklı veya zaman baskılı MVP projelerinde araç zinciri kurulum maliyeti faydayı aşabilir.
cargo-ndk olmadan Android için Rust derlenebilir mi?
Evet, cargo build --target aarch64-linux-android gibi komutlarla doğrudan da derleyebilirsin, ama NDK toolchain yollarını, linker ayarlarını ve çoklu-mimari çıktısını elle yönetmen gerekir. cargo-ndk bu adımları tek komuta indirger — bu yüzden çoğu proje elle derlemek yerine bu eklentiyi tercih eder. Sembol temizliğini ise v4.0.0'dan beri araç kendiliğinden yapmaz; [profile.release] strip = true ayarını sen açarsın.
UniFFI'de hata yönetimi nasıl çalışır?
Rust tarafında #[derive(uniffi::Error)] ile işaretlenmiş bir enum, Kotlin tarafında bir Exception alt sınıfına, Swift tarafında Error uyumlu bir tipe otomatik eşlenir. Fonksiyonun dönüş tipi Result<T, E> olduğunda, foreign taraf bunu kendi doğal hata yakalama mekanizmasıyla (try/catch, do/catch) işler; FFI sınırında elle hata kodu çevirmene gerek kalmaz.
Güncelleme (Eylül 2026)
Bu makalenin gövdesi Ekim 2025'teki UniFFI v0.30.0 sürümüne göre yazıldı. Aradan geçen bir yılda UniFFI ekosisteminde asıl hareket şu sürüm zincirinde yaşandı: v0.32.0 (Haziran 2026), v0.32.1 (8 Eylül 2026) ve v0.32.2 (23 Eylül 2026 — bu makalenin yazıldığı tarihten bir gün önce). Projenin kendi CHANGELOG'una göre öne çıkan değişiklikler:
- v0.32.0 kırıcı değişiklikler: Kotlin ve Python'da async primary constructor varsa bağlama üretimi artık hata veriyor — önceden bu diller ctor'u atlıyor ya da hep hata fırlatan bir ctor üretiyordu (Swift etkilenmiyor);
--configbayrağı global konfigürasyon formatına geçti;[ByRef] bytestipi Rust tarafında doğrudan&[u8]'e, Kotlin tarafında doğrudanByteBuffer'a eşleniyor. - v0.32.1: Kotlin
aarch64hedefinde bir checksum doğrulama hatası düzeltildi. - Ana dalda (henüz sürümlenmemiş) bekleyen özellikler: senkron export edilen fonksiyonların foreign tarafın sahip olduğu byte buffer'ı kopyasız (zero-copy) ödünç alıp yerinde yazabilmesini sağlayan bir değişiklik ve deneysel bir JNI-tabanlı Kotlin bağlama üretici (
uniffi-bindgen-kotlin-jni) geliştiriliyor.
Eğer yeni bir proje kuruyorsan, bu makaledeki komutları doğrudan v0.30.0 yerine güncel sürümle (cargo add uniffi) çalıştır ve [ByRef] bytes kullanan kodun varsa v0.32.0'daki tip değişikliğini gözden geçir. cargo-ndk ve AOSP'nin resmi Rust dokümantasyonu tarafında bu pencerede (Ekim 2025–Eylül 2026) yeni bir gelişme yok — her ikisi de makalenin yazıldığı tarihteki halleriyle güncelliğini koruyor.
Sonuç
Rust paylaşımlı çekirdek, iki platformda aynı iş mantığını iki kez yazmanın maliyetini ortadan kaldıran ama bedava olmayan bir yaklaşım: UniFFI, cargo-ndk ve XCFramework üçlüsü seni JNI/C-ABI köprü kodu yazmaktan kurtarıyor, karşılığında Rust öğrenme eğrisi ve FFI hata ayıklama disiplini istiyor. Kriptografi, senkronizasyon veya parser gibi platformdan bağımsız kritik iş mantığın varsa bu takas genelde kendini ödüyor; küçük ekip ve UI-ağırlıklı işlerde ise native yaklaşım veya KMP daha az sürtünmeli kalıyor.
Konuyu derinleştirmek istersen ilgili yazılarımıza bakabilirsin:
- Mobil mikroservis mimarisi — paylaşımlı çekirdek yaklaşımının backend/servis tarafındaki karşılığı.
- iOS offline-first mimari — senkronizasyon katmanını Rust çekirdeğe taşımanın gerekçelerinden biri.
- Flutter iOS platform kanalları — FFI sınırında dil-köprüsü kurmanın Flutter'daki eşdeğeri.
- React Native vs Flutter karşılaştırması — çapraz-platform kod paylaşımı seçeneklerini genişçe değerlendirir.
- iOS CI/CD pipeline kurulumu — bu makaledeki cargo-ndk/XCFramework adımlarını gerçek bir CI job'una bağlamak için.
Kaynaklar
- AOSP — Android Rust introduction — Rust'ın Android platformundaki resmi konumunu, bellek güvenliği ve "Fearless Concurrency" gerekçesini anlatan birincil AOSP dokümantasyonu.
- mozilla/uniffi-rs — GitHub deposu — UniFFI'nin resmi kaynak kodu, README'sinde Firefox üretim kullanımı ve 1.0-öncesi durum notu yer alıyor.
- UniFFI Kullanıcı Kılavuzu (latest) — proc-macro ve
.udlarayüz tanımlama yöntemlerini karşılaştıran resmi manual. - UniFFI — Foreign Language Bindings (Tutorial) —
uniffi-bindgenkurulumu vegenerate --librarykomutunun kaynağı. - bbqsrc/cargo-ndk — GitHub deposu — Android NDK için Rust derleme eklentisinin resmi deposu.
- cargo-ndk — CHANGELOG — v4.0.0 (30 Temmuz 2025) kırıcı değişikliği: "No longer strips build output by default, and
--no-stripoption is removed". - Apple Developer — Creating a multiplatform binary framework bundle — XCFramework paketleme sürecinin resmi Apple rehberi.
- UniFFI v0.30.0 sürüm notları — bu makalenin yazıldığı tarihte (Ekim 2025) güncel olan sürümün etiketlendiği kayıt.

