00 make/cmake dağınıklığından entegre araca
C/C++ projesinde build sistemi, paket yöneticisi, formatter ve linter dört ayrı araçtır ve hiçbiri standart değildir. Rust'ta bunların hepsi tek bir tutarlı zincirde toplanır.
Tipik bir C++ projesinde şu yığını kurarsınız: derleme için make veya cmake, bağımlılık çözümü için Conan/vcpkg/sistem pkg-config'i, kütüphane sürümlerini tutmak için yine başka bir mekanizma, biçimlendirme için clang-format, statik analiz için clang-tidy veya cppcheck. Her biri ayrı yapılandırma dosyası, ayrı sürüm uyumu, ayrı CI adımı ister. Hangi kombinasyonun kullanıldığı projeden projeye değişir; yeni bir repoya girdiğinizde önce build sistemini çözmeniz gerekir.
Rust'ta bu yığının tamamı cargo komutunun arkasında durur. Toolchain'i rustup yönetir, geri kalan her şey cargo <altkomut> ile gelir.
| İhtiyaç | C/C++ dünyası | Rust karşılığı |
|---|---|---|
| Build sistemi | make, cmake, ninja, autotools | cargo build |
| Paket / bağımlılık | Conan, vcpkg, pkg-config, apt | cargo add + crates.io |
| Sürüm kilitleme | (çoğunlukla yok) | Cargo.lock |
| Toolchain kurulumu | gcc/clang + dağıtım paketleri | rustup |
| Formatter | clang-format | cargo fmt |
| Linter | clang-tidy, cppcheck | cargo clippy |
| Test koşucu | CTest, GoogleTest + CMake | cargo test (yerleşik) |
| Dokümantasyon | Doxygen | cargo doc |
| IDE / LSP | clangd | rust-analyzer |
rustup (toolchain) → cargo new → cargo build → cargo test → cargo run → cargo publish
Cargo opinionated bir araçtır: dizin düzeni (src/, tests/, benches/), test bulma kuralı ve sürüm sözleşmesi konvansiyondur, yapılandırma değildir. cmake'te her projenin kendine özgü dizin mantığını çözmeye harcadığınız zaman burada yoktur.
Bu rehberin geri kalanı zinciri parça parça açar: önce rustup ile toolchain, sonra cargo ile günlük döngü, ardından kalite araçları (clippy, rustfmt) ve IDE entegrasyonu.
Bu bölümde
- C/C++'ta build/paket/format/lint dört ayrı araçken Rust'ta tek zincir olduğunu gördük
- Her C/C++ aracının Cargo karşılığını tabloladık
- Cargo'nun konvansiyon-üstü-yapılandırma yaklaşımını tanıdık
- Toolchain'i rustup, geri kalanı cargo'nun yönettiğini netleştirdik
01 rustup — toolchain yönetimi
rustup, Rust'ın derleyici sürümlerini, bileşenlerini ve cross-compile hedeflerini yöneten resmi toolchain yöneticisidir — dağıtım paketleriyle multilib/cross uğraşının yerini alır.
C/C++'ta belirli bir gcc sürümünü veya bir ARM cross-toolchain'i kurmak genellikle dağıtım paketleri, update-alternatives ve elle indirilen tarball'larla yürür. rustup bu işi tek bir araçta toplar: kanal seçimi, bileşen ekleme ve hedef ekleme hepsi aynı arayüzdedir.
Kanallar: stable, beta, nightly
Üç yayın kanalı vardır. stable altı haftada bir çıkar, üretim için varsayılandır. beta bir sonraki stable'ın aday sürümüdür. nightly her gece üretilir ve deneysel (unstable) özellikleri açar — bazı crate'ler ve araçlar (örn. cargo expand) nightly ister.
# rustup kurulumu (Unix)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Kanal kur ve varsayılan yap
rustup toolchain install stable
rustup toolchain install nightly
rustup default stable
# Kurulu toolchain'leri ve aktif olanı listele
rustup toolchain list
rustup show
Bileşenler (component)
Her toolchain'e ekstra araçlar bileşen olarak eklenir. clippy ve rustfmt stable'da varsayılan gelir; rust-src (no_std/embedded ve rust-analyzer için kaynak) ile rust-analyzer elle eklenebilir.
# Mevcut/kurulu bileşenleri gör
rustup component list --installed
# Bileşen ekle
rustup component add clippy rustfmt
rustup component add rust-src # std kaynağı (cross/embedded)
rustup component add rust-analyzer
Hedef ekleme (cross-compile)
Cross-compile için gcc dünyasında ayrı bir toolchain kurar, sysroot ayarlardınız. rustup'ta hedef üçlüsünü (target triple) eklersiniz; std önceden derlenmiş gelir.
# Hedefleri listele / ekle
rustup target list
rustup target add aarch64-unknown-linux-gnu
rustup target add thumbv7em-none-eabihf # Cortex-M4F, no_std
# Hedefe derle (linker yine de gereklidir)
cargo build --release --target aarch64-unknown-linux-gnu
rustup target add yalnızca Rust std'sini hedef için kurar. Linker ve C runtime'ı yine sağlamanız gerekir — örneğin aarch64-linux-gnu-gcc linker'ını ve uygun .cargo/config.toml içindeki [target.aarch64-unknown-linux-gnu] linker ayarını. Bu nokta cmake toolchain dosyasındaki CMAKE_C_COMPILER ayarına benzer.
update ve override
rustup update tüm kanalları günceller. Bir projeye özel toolchain sabitlemek için ya dizine rustup override koyarsınız ya da repoya rust-toolchain.toml eklersiniz — ikincisi tercih edilir, çünkü CI ve ekip arkadaşlarınızda da geçerli olur.
[toolchain]
channel = "1.86.0" # sabit sürüm: reproducible
components = ["clippy", "rustfmt", "rust-src"]
targets = ["thumbv7em-none-eabihf"]
Bu bölümde
- stable/beta/nightly kanallarını ve ne zaman hangisinin gerektiğini öğrendik
- clippy, rustfmt, rust-src bileşenlerini component ile ekledik
- Cross-compile için target ekledik ama linker'ın hâlâ gerektiğini gördük
- rust-toolchain.toml ile sürümü repoya sabitleyerek reproducible toolchain kurduk
02 cargo new / build / run
cargo new bir proje iskeleti üretir; build/run/check günlük geliştirme döngüsünü oluşturur. cmake'in configure + generate + build üç adımı burada tek komuta iner.
Proje iskeleti
cargo new ikili (binary) için src/main.rs, kütüphane (library) için src/lib.rs oluşturur ve git deposunu başlatır. Bir binary crate'in giriş noktası fn main()'dir; lib crate'in giriş noktası yoktur, başka crate'ler tarafından kullanılır.
cargo new merhaba # binary proje (src/main.rs)
cargo new mylib --lib # kütüphane (src/lib.rs)
# Üretilen düzen:
# merhaba/
# ├── Cargo.toml
# ├── .gitignore (target/ zaten yok sayılır)
# └── src/main.rs
Var olan bir dizinde başlatmak için cargo init kullanın — cargo new yeni bir alt dizin açar, cargo init bulunduğunuz dizine iskeleti yerleştirir. Bu, var olan bir C projesini Rust'a taşırken işe yarar.
build, run ve --release
Varsayılan derleme debug profilidir: optimizasyon yok, debug sembolleri açık, hızlı derlenir. Üretim için --release verirsiniz; bu, gcc'deki -O0 -g ile -O2/-O3 arasındaki seçime denktir. Çıktılar target/debug/ ve target/release/ altına ayrılır.
cargo build # debug → target/debug/merhaba
cargo build --release # optimize → target/release/merhaba
cargo run # derle + çalıştır (debug)
cargo run --release -- --girdi data.bin # -- sonrası program argümanı
-- ayıracından sonraki her şey cargo'ya değil, çalıştırılan programa gider — tıpkı make run ARGS=... yerine doğrudan argüman geçmek gibi.
cargo check — hızlı tip kontrolü
En çok kullanacağınız komut muhtemelen cargo check olacak. Kod tam derlenmeden, yalnızca tip kontrolü ve borrow-check yapılır; kod üretimi (codegen) ve linkleme atlanır. Bu, build'den kat kat hızlıdır ve yazarken sürekli geri bildirim için idealdir.
cargo check # sadece tip/borrow kontrol, binary üretmez
cargo clean # target/ dizinini sil (make clean)
| Komut | Ne yapar | Hız |
|---|---|---|
cargo check | Tip + borrow kontrol, codegen yok | En hızlı |
cargo build | Tam derleme, binary üretir (debug) | Orta |
cargo build --release | Optimize binary | En yavaş |
cargo run | build + çalıştır | build kadar |
Bu bölümde
- cargo new ile binary (main.rs) ve --lib ile kütüphane (lib.rs) iskeleti ürettik
- debug vs --release ayrımını ve target/ dizin yapısını gördük
--ile cargo argümanı ile program argümanını ayırdık- cargo check'in build'den çok daha hızlı geri bildirim verdiğini öğrendik
03 Cargo.toml anatomisi
Cargo.toml, projenin manifest dosyasıdır — CMakeLists.txt + paket metaverisi + bağımlılık listesinin tek dosyada birleşmiş hâli. TOML formatındadır, deklaratiftir.
Manifest birkaç tablodan oluşur. [package] kimlik ve sürüm bilgisini, [dependencies] üretim bağımlılıklarını, [dev-dependencies] yalnızca test/bench için olanları, [features] opsiyonel derleme bayraklarını, [[bin]] ise birden fazla ikili hedefi tanımlar.
[package]
name = "olcum-aleti"
version = "0.3.1"
edition = "2021" # dil sürümü kapısı (2015/2018/2021/2024)
rust-version = "1.74" # MSRV: minimum desteklenen rustc
license = "MIT OR Apache-2.0"
description = "Seri port üzerinden ölçüm toplayıcı"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serialport = "4.3"
anyhow = "1.0"
[dev-dependencies]
criterion = "0.5" # sadece bench/test derlemesinde linklenir
[features]
default = ["tls"]
tls = ["dep:rustls"] # "tls" özelliği rustls bağımlılığını açar
veri-kaydi = [] # kod içinde #[cfg(feature = "veri-kaydi")]
[[bin]]
name = "toplayici"
path = "src/bin/toplayici.rs"
edition — geriye uyumsuz dil sürümleri
edition, dilin geriye uyumsuz değişikliklerini opt-in yapan kapıdır (2015, 2018, 2021, 2024). Farklı edition'daki crate'ler aynı projede sorunsuz birlikte çalışır — bu, C++ standardını (-std=c++17) seçmeye benzer ama crate başına bağımsızdır. rust-version ise MSRV'dir (Minimum Supported Rust Version); bağımlılık çözümleyici buna saygı duyar.
Bir binary crate'te varsayılan ikili src/main.rs'tir ve ek [[bin]] tanımlamadan src/bin/*.rs altındaki her dosya otomatik ayrı bir binary olur. Aynı şekilde examples/, tests/, benches/ dizinleri konvansiyonla taranır — cmake'te her hedefi elle add_executable ile bildirmenin tersine.
Bu bölümde
- Cargo.toml'ın [package], [dependencies], [dev-dependencies], [features], [[bin]] tablolarını çözdük
- edition'ın crate başına seçilen geriye uyumsuz dil sürümü olduğunu gördük
- rust-version (MSRV) ile minimum derleyici sürümünü beyan etmeyi öğrendik
- src/bin/, examples/, tests/ dizinlerinin otomatik hedef bulma kuralını tanıdık
04 Bağımlılıklar & crates.io
crates.io merkezi paket kayıt defteridir; cargo add bağımlılığı manifest'e ekler. pkg-config / apt / Conan üçlüsüyle uğraşmak yerine tek komutla sürüm çözülür ve indirilir.
cargo add
Bağımlılığı elle Cargo.toml'a yazmak yerine cargo add kullanılır; en uygun sürüm aralığını otomatik yerleştirir ve istenirse özellikleri açar.
cargo add serde --features derive
cargo add tokio --features "rt-multi-thread,macros"
cargo add anyhow@1.0 # belirli aralık
cargo add criterion --dev # [dev-dependencies]'e ekle
cargo remove serde # kaldır
Sürüm aralıkları (^, =, ~)
Sürüm belirteci SemVer aralığı tanımlar. Çıplak "1.2.3" aslında ^1.2.3 demektir: uyumlu güncellemelere (aynı major) izin verir. Bu, üst sınırı serbest bırakan >=1.2.3, <2.0.0 ile eşdeğerdir.
| Belirteç | Anlamı | İzin verilen |
|---|---|---|
"1.2.3" / ^1.2.3 | Uyumlu (caret) | >=1.2.3, <2.0.0 |
~1.2.3 | Yama düzeyi (tilde) | >=1.2.3, <1.3.0 |
=1.2.3 | Tam sabit | yalnızca 1.2.3 |
"1.2.*" | Joker | >=1.2.0, <1.3.0 |
"*" | Herhangi (önerilmez) | en son uyumlu |
Özellik seçimi: default-features = false
Çoğu crate, bazı özellikleri varsayılan açık (default) getirir. Gereksiz bağımlılıkları kesmek (binary boyutu, no_std, derleme süresi) için varsayılanı kapatıp yalnızca istediğinizi seçersiniz. Bu, otoconf'taki --disable-X bayraklarına benzer ama derleyici düzeyinde, ölü kod bırakmadan çalışır.
[dependencies]
# std'yi kapat, no_std + serde derive aç
serde = { version = "1.0", default-features = false, features = ["derive"] }
# git deposundan, belirli branch/tag/rev
mylib = { git = "https://github.com/org/mylib", tag = "v0.4.0" }
# yerel yol (monorepo / yan yana geliştirme)
ortak = { path = "../ortak" }
git ve path bağımlılıkları crates.io'ya yayınlanamaz — cargo publish bunları reddeder. Yerel/git bağımlılıkları yalnızca uygulamalarda ve henüz yayınlanmamış geliştirmede kullanın; yayınlanacak bir kütüphane tüm bağımlılıklarını crates.io sürümüne (veya yayınlanmış sürüme) bağlamalıdır.
Vendoring
İnternetsiz/air-gapped build veya tedarik zinciri denetimi için bağımlılıkları repoya gömebilirsiniz. cargo vendor tüm kaynak ağacını vendor/ altına kopyalar ve kullanılacak .cargo/config.toml parçasını yazdırır — yum/apt mirror veya Conan cache mantığına benzer.
cargo vendor vendor/ # tüm bağımlılık kaynaklarını kopyala
# Çıktıdaki [source.crates-io] yönlendirmesini .cargo/config.toml'a yapıştırın
Bu bölümde
- cargo add / remove ile bağımlılık ve özellik yönetimini öğrendik
- ^, ~, =, * sürüm belirteçlerinin tam anlamlarını tabloladık
- default-features = false ile gereksiz bağımlılıkları keserek özellik seçimi yaptık
- git/path bağımlılığını ve air-gapped build için cargo vendor'ı gördük
05 Cargo.lock & SemVer
Cargo.lock, çözülmüş tam sürüm grafiğini sabitler — reproducible build'in anahtarıdır. C/C++'ta neredeyse hiç olmayan bu kilit dosyası, "bende çalışıyordu" sorununu kökten çözer.
Lock dosyasının rolü
Cargo.toml aralık belirtir (serde = "1.0"); Cargo.lock ise o aralıktan tam olarak hangi sürümün seçildiğini (örn. serde 1.0.210) ve tüm transitif bağımlılıkların kesin sürümlerini kaydeder. Sonraki build'de cargo, lock varsa onu kullanır — sürümler kaymaz.
# Otomatik üretilir — elle düzenlenmez
[[package]]
name = "serde"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e3592472072e6e22e0a54d5904d9fe..."
Commit etmek: binary mı, library mi?
Kural nettir ve uygulama ile kütüphane için farklıdır:
| Crate türü | Cargo.lock commit? | Neden |
|---|---|---|
| Binary / uygulama | Evet | Dağıtılan artefaktın birebir reproducible olması için |
| Library (yayınlanan) | Genelde hayır | Tüketiciler kendi grafiklerini çözer; lib'in lock'u onları bağlamaz |
Modern öneri yumuşamıştır: bir kütüphane reposunda da Cargo.lock'u commit etmek, CI'da deterministik testler için makuldür. Ancak yayınlanan crate kullanıcıları yine kendi Cargo.lock'larını üretir — kütüphanenin lock'u son kullanıcıyı kilitlemez.
cargo update ve SemVer sözleşmesi
cargo update lock'taki sürümleri Cargo.toml aralığı içinde en yenisine taşır. SemVer sözleşmesi gereği aynı major içindeki güncellemeler API kırmaz — major.minor.patch anlamlarına saygı, ekosistemin güven temelidir.
cargo update # tüm bağımlılıkları aralık içinde tazele
cargo update -p serde # sadece serde'yi güncelle
cargo update -p serde --precise 1.0.210 # belirli sürüme sabitle
# CI: lock'u kabul etme, salt-okunur doğrula
cargo build --locked # Cargo.lock değişirse hata ver
cargo build --offline # ağa hiç çıkma (önceden indirilmiş)
Bu bölümde
- Cargo.toml'ın aralık, Cargo.lock'un tam çözülmüş sürüm grafiği olduğunu ayırt ettik
- Binary'de lock'u commit et, library'de genelde etme kuralını öğrendik
- cargo update ve --precise ile kontrollü sürüm yükseltmeyi gördük
- SemVer'in major/minor/patch sözleşmesini ve --locked ile CI garantisini tanıdık
06 clippy — lint
clippy, rustc'nin ötesinde 700'den fazla lint sunan resmi linter'dır — clang-tidy'nin Rust karşılığı, ama kurulumu sıfır ve yanlış pozitifi düşük.
Derleyici zaten bellek güvenliğini garanti eder; clippy bir adım öteye geçip deyimsel olmayan (non-idiomatic), gereksiz veya performans açısından zayıf kalıpları yakalar. clang-tidy'de check setlerini seçip yapılandırmaya harcadığınız zamanın çoğu burada yoktur — makul varsayılanlar hazır gelir.
cargo clippy # tüm hedefleri lint'le
cargo clippy --all-targets --all-features
cargo clippy --fix # otomatik düzeltilebilenleri uygula
Yaygın lint örnekleri
clippy'nin yakaladığı tipik kalıplar, C'den gelen alışkanlıklarla yazılan Rust'ta sık görülür:
| Lint | Yakaladığı |
|---|---|
needless_range_loop | for i in 0..v.len() → for x in &v |
redundant_clone | Gereksiz .clone() çağrıları |
unwrap_used | Üretimde .unwrap() (pedantic grubunda) |
too_many_arguments | Aşırı parametreli fonksiyonlar |
manual_map | Elle yazılmış match yerine .map() |
allow / deny ile lint kontrolü
Tek tek lint'leri kod içinde #[allow(...)] ile bastırabilir, crate genelinde #![deny(...)] ile hata seviyesine yükseltebilirsiniz. Bilinçli bir istisnayı satır içinde, gerekçesiyle birlikte bastırmak iyi pratiktir.
// Crate genelinde: belirli lint grubunu hata yap
// (src/main.rs veya lib.rs başında)
#![deny(clippy::unwrap_used)]
#![warn(clippy::pedantic)]
// Tek bir yerde bilinçli istisna
#[allow(clippy::too_many_arguments)] // FFI imzası sabit
fn ffi_cagri(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
CI'da sert kapı: -D warnings
CI'da kaliteyi zorunlu kılmak için tüm uyarıları hataya çevirirsiniz. Bu, -Werror'ın clippy karşılığıdır ve PR'ların lint temiz olmadan birleşmesini engeller.
# CI adımı: tek bir uyarı bile build'i kırsın
cargo clippy --all-targets --all-features -- -D warnings
clippy lint'leri gruplara ayrılır: correctness (varsayılan hata), style/complexity/perf (varsayılan uyarı), pedantic ve nursery (opt-in, gürültülü olabilir). Yeni projede pedantic'i açıp gerçekten rahatsız eden lint'leri tek tek allow'lamak iyi bir başlangıçtır.
Bu bölümde
- cargo clippy ile deyimsel olmayan ve zayıf kalıpları yakalamayı öğrendik
- needless_range_loop, redundant_clone gibi yaygın lint'leri tanıdık
- #[allow] / #![deny] ile lint seviyelerini satır ve crate düzeyinde kontrol ettik
- CI'da -D warnings ile lint temizliğini zorunlu kıldık
07 rustfmt — biçimlendirme
rustfmt, kodu tek bir resmi stile biçimlendirir — clang-format gibi, ama topluluk genelinde fiili tek standart vardır. Stil tartışmaları code review'dan tamamen kalkar.
clang-format dünyasında her ekip kendi .clang-format'ını çatıştırır; LLVM, Google, WebKit stilleri arasında seçim yapılır. Rust'ta varsayılan tek doğru stil kültürü hâkimdir: çoğu proje varsayılanları olduğu gibi kullanır, böylece tüm ekosistem kodu aynı görünür.
cargo fmt # tüm projeyi yerinde biçimlendir
cargo fmt -- --check # değişiklik yapmaz, biçimsizse exit≠0
rustfmt.toml ile ince ayar
Gerekirse repo köküne rustfmt.toml koyarsınız. Çoğu ayar nightly'de açıktır; stable'da güvenle kullanılabilenler sınırlıdır. Edition, biçimlendirmeyi de etkilediği için belirtilmelidir.
edition = "2021" # dil sürümüyle uyumlu biçimlendirme
max_width = 100 # satır genişliği (varsayılan 100)
tab_spaces = 4
# Aşağıdakiler nightly gerektirir:
# group_imports = "StdExternalCrate"
# imports_granularity = "Crate"
CI'da fmt --check
Biçim tutarlılığını zorunlu kılmak için CI'da --check kullanılır: kod biçimsizse pipeline kırılır ve geliştirici cargo fmt çalıştırmaya yönlendirilir. Bu, biçim diff'lerinin gerçek değişiklikleri boğmasını engeller.
# CI adımı: biçimsiz kod build'i kırsın
cargo fmt --all -- --check
Bazı rustfmt.toml seçenekleri yalnızca nightly rustfmt'te çalışır. Stable toolchain'de bunları koyarsanız sessizce yok sayılırlar ya da uyarı verirler — CI ile yerel makinenin farklı toolchain kullanması "neden farklı biçimlendi" karmaşasına yol açar. rust-toolchain.toml ile fmt çalıştıran toolchain'i sabitleyin.
Bu bölümde
- cargo fmt ile tek resmi stile biçimlendirmeyi öğrendik
- rustfmt.toml ile edition, max_width gibi ayarları yaptık
- CI'da fmt --check ile biçim tutarlılığını zorunlu kıldık
- Bazı seçeneklerin nightly gerektirdiğini ve toolchain sabitlemenin önemini gördük
08 rust-analyzer — IDE/LSP
rust-analyzer, Rust'ın resmi LSP sunucusudur — clangd'nin karşılığı. Editörden bağımsız zengin geri bildirim sağlar: tamamlama, tip ipuçları, makro açma, anlık düzeltme.
clangd'nin compile_commands.json'a ihtiyaç duyması gibi, rust-analyzer da Cargo.toml'ı okuyarak projeyi anlar — ancak bunu otomatik yapar, ekstra üretim adımı gerekmez. LSP protokolü sayesinde aynı sunucu VS Code, Neovim, Helix, Emacs ve Zed'de çalışır.
LSP'nin sağladıkları
Editör entegrasyonu
VS Code'da resmi rust-analyzer eklentisi sunucuyu otomatik indirir. Diğer editörlerde sunucu ikilisini rustup ile alıp LSP istemcisini ona yönlendirirsiniz.
# Sunucuyu bileşen olarak kur (Neovim/Helix/Emacs)
rustup component add rust-analyzer
# İkilinin yolu (LSP istemcisine bunu ver)
rustup which rust-analyzer
rust-analyzer arka planda cargo check çalıştırarak teşhisleri (diagnostics) toplar. Büyük projelerde ilk indeksleme CPU yer; rust-src bileşeni kuruluysa std'ye go-to-def de çalışır. clangd'deki "background indexing" ile aynı mantıktır.
clangd ile kıyas
| Özellik | clangd (C/C++) | rust-analyzer |
|---|---|---|
| Proje keşfi | compile_commands.json üret gerekir | Cargo.toml'dan otomatik |
| Makro açma | Sınırlı (preprocessor) | Tam (derive + declarative) |
| Tip ipuçları | auto için kısmi | Kapsamlı inlay hints |
| Bağımlılığa atla | Sistem başlıklarına | crate kaynağına / std'ye |
| Kurulum | Derleme veritabanı kur | rustup component add |
Bu bölümde
- rust-analyzer'ın resmi LSP sunucusu ve clangd'nin karşılığı olduğunu öğrendik
- inlay hints, go-to-def, macro expand, quick fix yeteneklerini tanıdık
- rustup component add ile sunucuyu kurup editöre bağlamayı gördük
- Cargo.toml'dan otomatik proje keşfinin compile_commands.json derdini ortadan kaldırdığını kıyasladık
09 Workspace, profiller, faydalı komutlar
Workspace çok-crate projeleri tek hedef dizini ve tek lock dosyasıyla birleştirir; profiller derleme optimizasyonunu ayarlar. Bölüm, günlük kullanışlı komut tablosuyla kapanır.
Workspace — çok-crate proje
cmake'te alt projeleri add_subdirectory ile birleştirmek gibi, Cargo workspace birden çok crate'i tek bir build birimi yapar. Tüm üyeler aynı target/ ve aynı Cargo.lock'u paylaşır — bağımlılıklar bir kez derlenir, sürümler tutarlı kalır.
# Kök Cargo.toml — workspace tanımı
[workspace]
resolver = "2"
members = ["cekirdek", "cli", "daemon"]
# Üyelerin paylaştığı bağımlılık sürümleri
[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
# Üye Cargo.toml içinde:
# serde = { workspace = true } ← sürümü kökten miras al
[profile.release] — derleme profilleri
Profiller, gcc'nin -O/-flto bayraklarının deklaratif karşılığıdır. opt-level optimizasyon seviyesi, lto link-time optimization, codegen-units paralel kod üretimi birimleridir (azaltmak optimizasyonu artırır ama derlemeyi yavaşlatır).
[profile.release]
opt-level = 3 # 0..3 veya "s"/"z" (boyut için)
lto = true # link-time optimization (gcc -flto)
codegen-units = 1 # tek birim → daha iyi opt, yavaş derleme
panic = "abort" # unwind tablosunu at → küçük binary
strip = true # sembolleri çıkar (strip komutu gibi)
Faydalı komutlar
Günlük döngüde sürekli işinize yarayacak komutlar — testten doküman üretimine, bağımlılık grafiğinden makro açmaya:
cargo test # tüm testler (birim + entegrasyon + doc-test)
cargo test -- --nocapture # println! çıktısını göster
cargo doc --open # API doc üret + tarayıcıda aç (Doxygen)
cargo bench # benchmark (criterion / nightly bench)
cargo tree # bağımlılık grafiğini ağaç olarak yazdır
cargo tree -i serde # serde'yi kim çekiyor? (ters bağımlılık)
cargo expand # makroları aç (cargo-expand, nightly)
cargo expand ve cargo audit gibi araçlar çekirdek cargo'ya değil, cargo eklentilerine dayanır: cargo install cargo-expand ile kurulan herhangi bir cargo-X ikilisi otomatik olarak cargo X alt komutu olur. Bu, cargo'yu git'in alt komut modeline benzer şekilde genişletilebilir kılar.
| Komut | İşlev | C/C++ karşılığı |
|---|---|---|
cargo test | Test koşumu | CTest / GoogleTest |
cargo doc --open | API dokümantasyonu | Doxygen |
cargo bench | Performans ölçümü | Google Benchmark |
cargo tree | Bağımlılık grafiği | ldd / depgraph |
cargo expand | Makro açma | gcc -E (preprocessor) |
cargo audit | Güvenlik açığı taraması | (yok / harici) |
Bu bölümde
- Workspace ile çok-crate projeyi tek target/ ve tek lock altında birleştirdik
- [profile.release] opt-level / lto / codegen-units ile derleme çıktısını ayarladık
- test, doc, bench, tree, expand gibi günlük komutları C/C++ karşılıklarıyla tabloladık
- cargo-X eklenti modeliyle araç zincirini genişletmeyi öğrendik