# Bazel 1: Bazel nima va nega kerak — build tizimlari evolyutsiyasi, super-kuchlar va motivatsiya

> **Holat:** 2026-yil oktabr. Bu dars build tizimi nima ekanini, Xcode qayerda og'riy boshlashini va Bazel qanday g'oyaga asoslanishini noldan tushuntiradi. Kod misollari Bazel 9.3.0 (Bazelisk 1.29.0), rules_swift 4.2.1, apple_support 2.10.1 va Xcode 27.1 bilan Apple M4 Pro'da (12 core, 24 GB) tekshirilgan.

> **Bu darsdan keyin siz:** build tizimi iOS ilovangiz uchun aniq nima qilishini, Xcode'ning qaysi joyi katta loyihada og'riqqa aylanishini va Bazel bu og'riqni qaysi mexanizm bilan yo'qotishini tushunib, 20 darslik kursda sizni nima kutayotganini bilib olasiz.

- Build tizimining ishini aniq konveyer sifatida ko'rasiz: Swift kompilyatsiyasi → linking → `.app` yig'ish → imzolash → `.ipa`.
- Xcode'ning modelini (target, build phase, DerivedData) va uning katta jamoada qayerda sinishini — `project.pbxproj` merge konfliktlari, yashirin bog'liqliklar, "clean qilsam tuzaladi" sindromi, jamoa/CI uchun umumiy cache yo'qligi — nomma-nom tushunasiz.
- Bazel'ning markaziy g'oyasini bilasiz: build — bu e'lon qilingan kirishlardan chiqishlar hosil qiluvchi **sof funksiya**; undan kelib chiqadigan yetti super-kuchni mexanizmi bilan ko'rasiz.
- Olti qatorlik BUILD fayl va uning haqiqiy `bazel build`/`bazel test` natijasini (shu mashinada o'lchangan raqamlar bilan) ko'rasiz.
- Spotify, Airbnb kabi kompaniyalar Bazel'dan iOS uchun nima deb foydalanganini va Asana kabi jamoalar nega boshqa yo'l tanlaganini — faqat manbasi bor raqamlar bilan — bilib olasiz.
- Bazel sizga, hatto bugun Xcode'da ishlasangiz ham, nega foydali ekanini va 20 darslik yo'l xaritasini ko'rasiz.

## Mundarija

1. [Build tizimi nima va iOS ilovasida nimani bajaradi](#build-tizimi)
2. [Xcode qanday quradi va u qayerda og'riy boshlaydi](#xcode-ogriq)
3. [Bazel'ning asosiy g'oyasi: build — bu sof funksiya](#asosiy-goya)
4. [Bazel'ning yetti super-kuchi](#super-kuchlar)
5. [Birinchi ta'm: olti qatorlik BUILD fayl va haqiqiy natija](#birinchi-tam)
6. [Real dunyo: kim Bazel'dan foydalanadi va nima deydi](#real-dunyo)
7. [Halol tomoni: narxi, cheklovlari va kim boshqa yo'l tanlagan](#halol-tomoni)
8. [Kim Bazel'ni o'rganishi kerak (Xcode'da ishlasangiz ham)](#kimga)
9. [Kurs xaritasi: 20 dars, noldan ekspertgacha](#kurs-xaritasi)
10. [Amaliy mashqlar](#mashqlar)
11. [O'zingizni tekshiring](#checklist)
12. [Xulosa](#xulosa)
13. [Manbalar](#manbalar)

---

## 1. Build tizimi nima va iOS ilovasida nimani bajaradi {#build-tizimi}

Siz Xcode'da ⌘R bosganingizda, aslida bir dasturchi uchun ko'rinmaydigan konveyer ishga tushadi. `MyApp.swift` faylidan simulyatordagi ishlayotgan ilovagacha bo'lgan yo'lda bir nechta bosqich bor, va ularning har biri alohida vosita (tool) tomonidan bajariladi. Keling, bu konveyerni nomma-nom ko'rib chiqaylik, chunki Bazel ham, Xcode ham xuddi shu ishni bajaradi — faqat **turlicha boshqaradi**.

Oddiy bir iOS ilovasi quriladigan bosqichlar:

1. **Kompilyatsiya (compile).** `swiftc` kompilyatori har bir `.swift` faylni mashina kodiga (`.o` object fayl) aylantiradi. Agar loyihada Objective-C bo'lsa, `clang` ularni alohida kompilyatsiya qiladi. Bu bosqichda tip tekshiruvi (type checking) ham bo'ladi — xatolaringizning aksariyati shu yerda chiqadi.
2. **Linking.** Linker (Xcode 27'gacha `ld64`, endi yangi linker — Xcode 27 release notes'da `ld64` olib tashlangan) barcha object fayllarni va kutubxonalarni bitta bajariluvchi binar faylga birlashtiradi. "Undefined symbol" xatosini ko'rgan bo'lsangiz — u aynan shu bosqichdan.
3. **Resurslarni qayta ishlash.** Asset catalog (`.xcassets`) `actool` bilan `Assets.car` ga, storyboard/xib `ibtool` bilan, `.strings`/`.xcstrings` lokalizatsiya fayllari o'z formatiga aylantiriladi.
4. **Bundle yig'ish (`.app`).** Yuqoridagilarning hammasi — binar, resurslar, `Info.plist` — ma'lum tuzilishdagi `MyApp.app` papkasiga joylashtiriladi.
5. **Kod imzolash (codesign).** `.app` raqamli sertifikat va provisioning profil bilan imzolanadi, aks holda qurilma uni ishga tushirmaydi (simulyator imzoga unchalik qattiq talabchil emas, qurilma esa qattiq).
6. **Paketlash (`.ipa`).** App Store yoki TestFlight uchun `.app` qo'shimcha metama'lumotlar bilan `.ipa` arxiviga joylanadi.

Shu yerda muhim bir narsani tushunib oling: **bu bosqichlarning hech biri Xcode yoki Bazelga xos emas.** Ikkala vosita ham `swiftc`, `ld`, `actool`, `codesign` kabi Apple'ning bir xil asboblarini chaqiradi. Farq — bu asboblarni **kim, qachon va necha marta** chaqirishni boshqarishida. Aynan shu "boshqaruv" katta loyihada hamma narsani hal qiladi: build necha daqiqa davom etadi, natija takrorlanadiganmi, ikki dasturchi bir xil kirishdan bir xil chiqishni oladimi.

Bazel bu bosqichlarni "action" deb ataydi va ularning aniq nomlarini ko'rasiz: `rules_apple` kutubxonasi iOS ilovasini qurganda `BundleApp`, linking, `SwiftStdlibCopy`, imzolash kabi action'larni yaratadi (buni 8-darsda o'z ko'zingiz bilan ko'rasiz). Hozircha asosiysi — bir fikr:

> **🧠 Esda tuting:** Build tizimi — bu "kompilyator" emas. Bu kompilyator, linker, resurs asboblari va imzolovchini **to'g'ri tartibda, kerakli paytda va imkon qadar parallel** chaqiradigan dirijyor. Dirijyor qanchalik aqlli bo'lsa, build shunchalik tez va ishonchli bo'ladi.

Shu nuqtadan boshlab savol o'zgaradi. "Qaysi vosita Swift'ni tezroq kompilyatsiya qiladi?" — noto'g'ri savol, chunki ikkalasi ham bir xil `swiftc` ni chaqiradi. To'g'ri savol: **"Qaysi vosita keraksiz ishni qilmaslikni yaxshiroq biladi?"** Chunki eng tez kompilyatsiya — umuman qilinmagan kompilyatsiya. Mana shu yerda build tizimlari bir-biridan keskin farq qiladi.

---

## 2. Xcode qanday quradi va u qayerda og'riy boshlaydi {#xcode-ogriq}

Xcode'ni yomonlash uchun emas — u ajoyib IDE va kichik-o'rta loyihalar uchun deyarli har doim to'g'ri tanlov — balki uning modelini aniq tushunish uchun ko'rib chiqamiz. Chunki Bazel aynan Xcode modelining chegaralariga javoban paydo bo'lgan.

### Xcode modeli: target, build phase, scheme, DerivedData

Xcode loyihasi **target**'lardan iborat. Har bir target (masalan, ilova, framework, test to'plami) ichida **build phase**'lar ketma-ketligi bor: "Compile Sources", "Link Binary With Libraries", "Copy Bundle Resources", "Run Script" va hokazo. Siz ⌘B bosganingizda Xcode bu fazalarni tartib bilan bajaradi. **Scheme** qaysi target'larni va qaysi konfiguratsiyada (Debug/Release) qurishni belgilaydi. Qurilgan hamma narsa — oraliq fayllar, indekslar, binarlar — `~/Library/Developer/Xcode/DerivedData` ichiga tushadi.

Bu model tanish va qulay. Lekin uni "**task-based**" (vazifaga asoslangan) build tizimi deb atashadi: har bir build phase, ayniqsa "Run Script", ixtiyoriy kod/skript bo'lishi mumkin. Bazel'ning rasmiy hujjatlari aynan shu modelni va uning cheklovlarini batafsil tahlil qilgan ("Task-Based Build Systems" sahifasi). Asosiy muammo bitta jumlada:

> Task-based tizimlar **muhandisga juda ko'p kuch, tizimning o'ziga juda kam kuch beradi.** Tizim skript nima qilishini bilmagani uchun, u qachon ishni qayta bajarish kerakligini aniq ayta olmaydi — natijada ko'pincha "ehtiyot shart" hammasini qaytadan quradi.

Kichik loyihada bu sezilmaydi. Katta loyihada esa bu to'rtta aniq og'riqqa aylanadi.

### Og'riq 1: `project.pbxproj` va merge konfliktlar

Xcode loyihasining butun tuzilishi — qaysi fayl qaysi target'da, build sozlamalari, fayllar tartibi — bitta `project.pbxproj` faylida saqlanadi. Bu fayl mashinaga mo'ljallangan, uzun va deyarli o'qib bo'lmaydigan matn. Ikki dasturchi bir vaqtda ikki xil branch'da fayl qo'shsa yoki sozlama o'zgartirsa, `git merge` paytida shu faylda konflikt chiqadi — va uni qo'lda hal qilish iztirob.

Bu muammo shunchalik haqiqiyki, uni hal qilish uchun alohida vositalar paydo bo'lgan. Tuist (biz bu kursning Tuist modulida o'rganamiz) Xcode 16'ning "synchronized groups" imkoniyatiga asoslangan `buildableFolders` ni qo'shdi; uning rasmiy e'loniga ko'ra, bunda "Xcode tashqarisida (agent, CLI, CI tomonidan) qo'shilgan fayllar endi qayta generatsiya talab qilmaydi va `pbxproj` merge konfliktlari kamayadi". Ya'ni butun bir imkoniyat shunchaki bitta faylning konflikt muammosini yumshatish uchun yaratilgan.

### Og'riq 2: yashirin bog'liqliklar (implicit dependencies)

Xcode odatiy holda "Find Implicit Dependencies" rejimida ishlaydi: u target'lar orasidagi bog'liqlikni o'zi taxmin qiladi. Qulay — lekin bu bog'liqliklar hech qayerda to'liq, aniq yozilmagan. Natijada tizim "A target'i B'ga bog'liqmi?" degan savolga ba'zan noto'g'ri javob beradi. Bazel hujjatlari task-based tizimlarning aynan shu kasalligini sanaydi: "A vazifasi B ishlab chiqaradigan faylga bog'liq. B egasi boshqalar unga tayanishini bilmay, chiqish joyini o'zgartiradi. Buni kimdir A'ni ishga tushirib, u sinmaguncha sezib bo'lmaydi."

### Og'riq 3: "clean qilsam tuzaladi" sindromi

Siz buni ko'rgansiz: build tushunarsiz xato bilan sinadi, siz ⇧⌘K (Clean Build Folder) bosasiz, DerivedData o'chadi, va keyingi build ishlaydi. Nega? Chunki inkremental build **noto'g'ri** holatga tushib qolgan edi — tizim nimadir o'zgarganini sezmay, eski natijani qayta ishlatdi yoki aksincha.

Bazel hujjatlari buni task-based tizimlarning bevosita oqibati deb ataydi: "Muhandislar har build'dan oldin clean qilish odatiga o'rganib qolishadi — bu esa inkremental build'ning butun ma'nosini yo'qqa chiqaradi." Agar siz har safar ishonch uchun clean qilsangiz, demak sizda inkremental build yo'q — har safar noldan quryapsiz.

> **⚠️ Diqqat:** "Clean qilsam tuzaladi" — bu sizning aybingiz emas va "noto'g'ri" kod belgisi ham emas. Bu task-based build tizimining strukturaviy kamchiligi: tizim ishni qayta bajarish kerakmi-yo'qmi degan savolga har doim ham to'g'ri javob bera olmaydi, shuning uchun ba'zan xato qiladi.

### Og'riq 4: jamoa/CI uchun umumiy cache yo'q (yaqingacha)

Eng kattasi — bu. Sizning DerivedData'ingiz faqat sizning mashinangizda. Hamkasbingiz xuddi shu commit'ni qurganda, u noldan quradi. CI serveri xuddi shu commit'ni yana noldan quradi. Ya'ni bir xil kirishdan bir xil chiqish o'nlab marta qayta hisoblanadi — har bir mashinada alohida.

Apple bu bo'shliqni faqat yaqinda, Xcode 26 bilan tan oldi: unga **ixtiyoriy** (odatiy holda o'chiq) kompilyatsiya cache'i qo'shildi — `COMPILATION_CACHE_ENABLE_CACHING=YES`. U content-addressed storage (CAS) va action cache modeliga asoslanadi — bu aynan Bazel 10 yildan beri ishlatadigan model. Ushbu mashinada (Xcode 27.1) buni tekshirdik: `SWIFT_ENABLE_EXPLICIT_MODULES = YES` va `COMPILATION_CACHE_CAS_PATH` sozlamalari bor, lekin `COMPILATION_CACHE_ENABLE_CACHING` hali ham odatiy holda yoqilmagan. Ya'ni Apple Bazel modelini ko'chira boshladi — bu Bazel g'oyasining qanchalik to'g'ri ekanining eng kuchli dalili.

Shuni ham halollik bilan aytaylik: Xcode 26 cache'i hamma narsani qamramaydi. Bir manbaga (Bitrise FAQ) ko'ra, u `Ld` (linking), `CompileStoryboard`, `CompileXIB`, `PhaseScriptExecution`, `CompileAssetCatalogVariant` kabi action'larni cache qilmaydi — faqat kompilyatsiyani. Bazel esa linking va bundling'ni ham cache qiladi.

> **🚀 Motivatsiya:** Katta jamoada eng ko'p vaqt yeydigan narsa — bir xil ishni qayta-qayta qilish. Agar sizning CI'ingiz har PR'da butun ilovani noldan qursa va 70 daqiqa ketsa (Monzo jamoasi aynan shu holatga tushgan), muammo kompilyatorning sekinligida emas — tizim keraksiz ishni qilayotganida. Bazel'ning butun falsafasi shunga qurilgan: **eng tez ish — umuman qilinmagan ish.**

Endi savol tug'iladi: tizim qanday qilib "bu ishni qayta qilish shart emas" ekanini **ishonch bilan** biladi? Javob — Bazel'ning asosiy g'oyasida.

---

## 3. Bazel'ning asosiy g'oyasi: build — bu sof funksiya {#asosiy-goya}

Bazel boshqa bir sinfga tegishli: u **artifact-based** (artefaktga asoslangan) build tizimi. Farqni bitta jumlada aytsak:

> Task-based tizimda siz tizimga **qanday** qurishni aytasiz (qadamma-qadam skript). Artifact-based tizimda siz faqat **nimani** qurishni aytasiz (deklarativ ro'yxat), **qanday** qurish — tizimning ishi.

Buni oshxona bilan solishtiring. Task-based build — bu oshpazga qadamma-qadam buyruq berish: "gazni yoq, tovani qo'y, yog' sol, 3 daqiqa kutt...". Agar bir qadamni o'tkazib yuborsangiz yoki tartibni buzsangiz — taom buziladi, va oshpaz nega buzilganini bilmaydi. Artifact-based build — bu menyu berish: "menga osh kerak, mana masalliqlar". Oshxona qanday pishirishni o'zi biladi, qaysi ishni parallel qilishni o'zi hal qiladi, va agar kecha aynan shu oshni pishirgan bo'lsa — qaytadan pishirmay, tayyorini beradi.

### Build — matematik funksiya

Bazel hujjatlari bu g'oyani funksional dasturlash bilan tushuntiradi. An'anaviy imperativ til (Java, C, Python) — bu ketma-ket bajariladigan buyruqlar ro'yxati, xuddi task-based build kabi. Funksional til (Haskell, ML) esa — matematik tenglamalar to'plami: siz **natijani** tasvirlaysiz, uni qachon va qanday hisoblashni kompilyator hal qiladi.

Build tizimi aynan shunga mos keladi, chunki butun build — bu bitta matematik funksiya:

```text
build(manba_fayllar, asboblar, sozlamalar) → binarlar
```

Agar bir funksiyaga bir xil kirish bersangiz, u doim bir xil chiqish qaytaradi. Demak, agar kirish o'zgarmagan bo'lsa — chiqishni qayta hisoblash shart emas, eskisini ishlatish mumkin. Bazel'ning tezligi va to'g'riligi — hammasi shu bitta g'oyadan kelib chiqadi.

### BUILD fayl — deklaratsiya, skript emas

Bazel'da `BUILD` fayllar imperativ buyruqlar emas, **deklarativ manifest**: nimani qurish, uning bog'liqliklari va cheklangan sozlamalar. Mana Bazel hujjatlaridagi klassik misol (Java, hozircha g'oyani ko'rsatish uchun):

```starlark
java_binary(
    name = "MyBinary",
    srcs = ["MyBinary.java"],
    deps = [":mylib"],
)

java_library(
    name = "mylib",
    srcs = ["MyLibrary.java", "MyHelper.java"],
    deps = ["//java/com/example/common"],
)
```

Bu yerda `java_binary` va `java_library` — **target**'lar, har biri bitta artefaktga mos keladi. Har bir target'da `name` (nomi), `srcs` (manba fayllar) va `deps` (bog'liqliklar) bor. Siz `bazel build :MyBinary` deganingizda, Bazel:

1. Barcha `BUILD` fayllarni o'qib, target'lar orasidagi bog'liqlik **grafini** quradi.
2. `MyBinary` ning transitiv (zanjirli) bog'liqliklarini aniqlaydi.
3. Har bir bog'liqlikni to'g'ri tartibda quradi — bog'liqligi yo'q target'lardan boshlab, imkon qadar parallel.
4. Oxirida `MyBinary` ni yig'adi.

Ikkinchi marta `bazel build :MyBinary` deganingizda — hech narsa o'zgarmagan bo'lsa — Bazel bir soniyadan kamroq vaqtda "target is up to date" deb chiqadi. Chunki u biladi: har bir target faqat kompilyatorni ishga tushirish natijasi, kompilyator chiqishi esa faqat kirishlariga bog'liq. Kirishlar o'zgarmagan ekan — chiqishni qayta ishlatsa bo'ladi. Va bu tahlil har bir darajada ishlaydi: agar `MyBinary.java` o'zgarsa, Bazel `MyBinary` ni qayta quradi, lekin `mylib` ni qayta ishlatadi.

### Content hashing va action key

Bazel "kirish o'zgardimi?" degan savolga **fayl sanasiga** (timestamp) qarab emas, **mazmun hash'iga** (content hash) qarab javob beradi. Har bir action uchun u "action key" hisoblaydi — bu action'ning buyruq qatori, muhit o'zgaruvchilari, barcha kirish fayllarining digest'lari va platformasidan tashkil topadi. Agar action key o'zgarmagan bo'lsa — chiqish cache'dan olinadi. Bu mexanizmni 10-darsda chuqur ochamiz; hozircha asosiysi — Bazel ishni **ishonch bilan** o'tkazib yuboradi, "ehtimol o'zgargandir" degan taxmin bilan emas.

### Hermetiklik va sandboxing

Bazel har bir action'ni **sandbox** ichida bajaradi: action faqat o'zi e'lon qilgan kirishlarni ko'radi, boshqa hech narsani. Agar action e'lon qilmagan faylga murojaat qilmoqchi bo'lsa — u topilmaydi va action sinadi. Bu qattiq ko'rinadi, lekin aynan shu narsa buildni **hermetik** (yopiq, takrorlanadigan) qiladi: sizning mashinangizdagi tasodifiy fayl buildga ta'sir qila olmaydi, shuning uchun bir xil manba doim bir xil binar beradi — bit-bitigacha.

Tashqi bog'liqliklar (kutubxonalar) ham nazoratda: ularning har biri `MODULE.bazel.lock` faylida kriptografik hash bilan yozib qo'yiladi. Bog'liqlik serveri buzilsa yoki kimdir faylni almashtirsa — hash mos kelmaydi va build to'xtaydi. Bu ta'minot zanjiri (supply chain) xavfsizligi uchun katta yutuq.

### {Fast, Correct} — Choose two

Bazel'ning rasmiy shiori — `{Fast, Correct} — Choose two` (README'da shunday yozilgan). An'anaviy maqol "tez, arzon, sifatli — ikkitasini tanla" deydi. Bazel esa ataylab aytadi: **tezlik va to'g'rilik — ikkalasini ham olasiz.** Chunki ikkalasi bir ildizdan o'sadi: Bazel kirishlarni aniq bilgani uchun keraksiz ishni o'tkazib yuboradi (tezlik), va aniq bilgani uchun kerakli ishni hech qachon o'tkazib yubormaydi (to'g'rilik). Hujjatlardagi iborasi bilan: "Cheksiz `make clean` chaqiruvlariga va manba kodida allaqachon tuzatilgan, lekin hech qachon qayta qurilmagan 'arvoh' xatolarni quvlashga xayr ayting."

![Xcode'ning task-based modeli va Bazel'ning action grafi + cache modelini yonma-yon solishtiruvchi diagramma](/lessons/images/bazel/bazel_01_xcode_vs_bazel.svg)

Yuqoridagi diagramma ikki modelni yonma-yon qo'yadi. Chapda Xcode: build phase'lar ketma-ketligi, har biri "qora quti", va holat chalkashganda yagona yechim — Clean. O'ngda Bazel: e'lon qilingan kirishlardan action grafi quriladi, har bir action'ning natijasi content hash bilan cache'lanadi, va o'zgarmagani cache'dan olinadi — mashinangizda ham, jamoada ham, CI'da ham.

Ikki modelni bir qarashda jadval ham ko'rsatadi. Har bir satr bu darsda ko'rgan mexanizmdan kelib chiqadi:

| O'lchov                  | Xcode (task-based)                 | Bazel (artifact-based)            |
| ------------------------ | ---------------------------------- | --------------------------------- |
| Asosiy model             | build phase ketma-ketligi          | action grafi (deklarativ)         |
| Inkremental to'g'rilik   | kafolatlanmagan ("clean fixes it") | content hash bilan kafolatlangan  |
| Jamoa/CI umumiy cache    | yo'q (Xcode 26'dan ixtiyoriy)      | bor (disk + remote), standart     |
| Parallellik              | cheklangan                         | action grafi bo'yicha to'liq      |
| Ko'p til / monorepo      | yo'q (faqat Apple)                 | bor (iOS/Android/backend/tooling) |
| Build grafini so'rovlash | yo'q                               | `bazel query`                     |
| Test natijasi cache'i    | yo'q                               | bor (`(cached) PASSED`)           |
| IDE integratsiyasi       | native (birinchi klass)            | `rules_xcodeproj` orqali          |
| Konfiguratsiya fayli     | `project.pbxproj` (merge og'riq)   | `BUILD` (kichik, o'qiladigan)     |
| O'rganish egri chizig'i  | past                               | balandroq (Starlark)              |

Diqqat: bu jadval "Bazel har doim yaxshiroq" degani emas. Oxirgi ikki satr (IDE integratsiyasi va o'rganish egri chizig'i) Xcode foydasiga — va kichik loyihada aynan ular hal qiluvchi bo'lishi mumkin. 7- va 8-bo'limlarda buni halol tortib ko'ramiz.

### Qisqa tarix: Blaze'dan Bazel 9'gacha

Bazel osmondan tushmagan — u Google ichidagi 15 yillik tajribadan o'sgan:

- **~2006, Google ichida — "Blaze".** Google o'z serverlarini katta, generatsiya qilingan Makefile'lar bilan qurar edi; bu "sekin va ishonchsiz buildlarga olib keldi" (Bazel FAQ). Yechim sifatida Blaze yaratildi. "Blaze" hali ham Bazel kodida ichki nom — hujjatlar: "Blaze'ni Bazel deb atang".
- **2015 — Bazel ochiq kodga chiqdi.** Google Blaze'ning ochiq versiyasini Bazel nomi bilan chiqardi; 2015-yil sentyabrda u beta bosqichiga yetdi ("Bazel Builder Blasts Beyond Beta Barrier", blog.bazel.build). Bazel Blaze bilan ko'p kodni bo'lishadi.
- **2019-yil 10-oktabr — Bazel 1.0.** Birinchi umumiy (GA) relizi; semantik versiyalashga o'tdi va LTS (uzoq muddatli qo'llab-quvvatlash) siyosatini kiritdi.
- **Bzlmod davri.** Tashqi bog'liqliklarni boshqarishning eski `WORKSPACE` usuli o'rniga `MODULE.bazel` (Bzlmod) keldi. Bazel 8 `WORKSPACE` ni odatiy holda o'chirdi, **Bazel 9 (2026-yil 20-yanvar) esa `WORKSPACE` kodini butunlay olib tashladi** — endi faqat `MODULE.bazel`. Eski `WORKSPACE`'ga asoslangan har qanday qo'llanma eskirgan.
- **Bugun.** Barqaror reliz — **Bazel 9.3.0** (2026-yil 7-oktabr), 8.x LTS liniyasida 8.8.1, va 10.0.0rc1 prereliz. Biz butun kursda `.bazelversion` ni aniq `9.3.0` ga qotiramiz (takrorlanadigan build uchun).

> **🧠 Esda tuting:** Bazel "yangi, sinovdan o'tmagan" vosita emas. U Google ichida kuniga millionlab build qiladigan tizimning ochiq versiyasi, 2015-yildan ommaviy, 2019-yildan 1.0. Siz o'rganayotgan model — eng katta kod bazalarida pishib yetilgan.

---

## 4. Bazel'ning yetti super-kuchi {#super-kuchlar}

Endi g'oyadan amaliyotga o'tamiz. Quyidagi yetti xususiyat — Bazel'ning "super-kuch"lari. Har birini qisqa mexanizm va imkon bo'lsa shu mashinada o'lchangan haqiqiy raqam bilan ko'rsatamiz. Raqamlar 5-bo'limdagi kichik misol loyihadan olingan (Apple M4 Pro, Xcode 27.1, Bazel 9.3.0).

**1. To'g'ri inkremental build.** Bazel faqat o'zgargan narsani va unga bog'liq narsalarni qayta quradi — na ko'p, na kam. Misol loyihada `App/main.swift` da bitta qatorni o'zgartirib qayta qurganimda, Bazel butun 295 ta action o'rniga **atigi 4 ta process** ishlatdi va build **0.916 soniyada** tugadi: faqat ilova qayta kompilyatsiya qilindi, kutubxona o'zgarmagani uchun qayta ishlatildi. Bu "clean qilsam tuzaladi" dunyosidan butunlay boshqa dunyo — bu yerda inkremental buildga **ishonish** mumkin.

**2. Hermetiklik va sandboxing.** Har bir action izolyatsiya qilingan quti ichida, faqat e'lon qilingan kirishlar bilan ishlaydi. Natijada bir xil manba bir xil chiqish beradi — sizning noutbukingizda, hamkasbingizning mashinasida va CI'da bir xil, bit-bitigacha. "Menda ishlaydi, CI'da ishlamaydi" muammosi tizim darajasida hal qilinadi.

**3. Jamoa va CI uchun umumiy cache.** Build natijalari disk cache yoki remote (tarmoq) cache'ida saqlanadi va **butun jamoa bilan bo'lishiladi**. Misol loyihada: birinchi, sovuq build (hamma narsa noldan) **60.4 soniya** davom etdi; lekin disk cache to'lgach, output base tozalangan "yangi jamoadosh / ikkinchi checkout" holati atigi **1.8–2.5 soniya** oldi (177 ta disk cache hit). Remote cache'da bu "yangi jamoadosh" boshqa mashinada bo'lsa ham xuddi shunday tez bo'ladi — bu jamoaviy tejamkorlikning asosi.

**4. Parallel va remote execution.** Bazel action grafini tahlil qilib, bir-biriga bog'liq bo'lmagan action'larni bir vaqtda ishga tushiradi — barcha CPU yadrolaringizdan foydalanib. Bundan ham nariga borib, action'larni remote execution orqali boshqa mashinalarga tarqatish mumkin (iOS uchun bu macOS "worker"larni talab qiladi — buni 18-darsda ochamiz). Google ichida minglab action bir vaqtda bajariladi.

**5. Bitta vosita — barcha tillar.** Bazel faqat iOS uchun emas: bir xil tool va bir xil `BUILD` fayllar bilan iOS, Android, backend (Go, Java, C++), va ichki asboblaringizni quradi. Monorepo (yagona ulkan repozitoriy)da siz client/server protokolini bitta commit'da o'zgartirib, yangilangan mobil ilova yangilangan server bilan ishlashini bir buildda tekshira olasiz. Xcode buni hech qachon qila olmaydi.

**6. `bazel query` — build grafini so'rovlash.** Bazel butun bog'liqlik grafini biladi, va siz undan so'rashingiz mumkin: "`//App` nimalarga bog'liq?", "bu faylni o'zgartirsam, qaysi test'lar ta'sirlanadi?". Aynan shu so'rov CI'da "faqat o'zgargan narsaga tegishli test'larni ishga tushir" degan super-kuchni beradi (11-darsda qo'llaymiz). Xcode'da bunday so'rov umuman yo'q.

**7. Cache'langan test natijalari.** Bazel test natijasini ham cache qiladi: agar test va uning kirishlari o'zgarmagan bo'lsa, test **qayta ishga tushmaydi** — natija cache'dan olinadi. Misol loyihada ilovani o'zgartirib, keyin kutubxona test'ini ishga tushirganimda: test `(cached) PASSED in 2.0s` deb chiqdi va **0 ta test aslida bajarildi**, chunki test'ning kirishlari (kutubxona + test kodi) o'zgarmagan edi. Katta loyihada bu minglab keraksiz test ishga tushishini o'chiradi.

![Bazel'ning yettita super-kuchini qisqa mexanizmi bilan ko'rsatadigan kartochkalar diagrammasi](/lessons/images/bazel/bazel_01_superpowers.svg)

Diagrammadagi yettita kartochka — yuqoridagi yetti super-kuch, har birida bir qatorli mexanizm. Diqqat qiling: ularning hammasi bitta ildizdan — "build sof funksiya" g'oyasidan — o'sadi. To'g'ri inkremental build, cache va test cache — bularning barchasi "kirish o'zgarmasa, chiqishni qayta ishlatish mumkin" qoidasining turli ko'rinishlari.

> **💡 Pro tip:** Super-kuchlarni bitta mantra bilan eslang: **"Bir ishni ikki marta qilma."** Bazel'ning hamma yutug'i shu — bir xil kirishdan bir xil chiqish bir marta hisoblanadi, keyin hamma (siz, jamoa, CI) uni qayta ishlatadi. Qolgan hamma narsa — texnik tafsilot.

---

## 5. Birinchi ta'm: olti qatorlik BUILD fayl va haqiqiy natija {#birinchi-tam}

Nazariya yetarli — keling, Bazel'ni ishda ko'raylik. O'rnatish va har bir faylni batafsil tushuntirish keyingi, 2-darsning ishi; bu yerda shunchaki **ta'm** beramiz: bir nechta kichik fayl, bitta buyruq, haqiqiy natija. Hammasi shu mashinada haqiqatan qurilgan va ishga tushirilgan.

Kichik bir "Salom" loyihasi: bitta kutubxona (`swift_library`), uni ishlatadigan macOS buyruq qatori dasturi (`swift_binary`) va bitta test (`swift_test`). Fayllar tuzilishi:

```text
salom-taste/
├── .bazelversion          # qaysi Bazel versiyasi
├── MODULE.bazel           # tashqi bog'liqliklar
├── App/
│   ├── BUILD.bazel        # dasturning "retsepti"
│   └── main.swift
└── Salom/
    ├── BUILD.bazel        # kutubxona + test retsepti
    ├── Sources/Salom.swift
    └── Tests/SalomTests.swift
```

`.bazelversion` — bitta qator, Bazel versiyasini qotiradi:

```text
9.3.0
```

`MODULE.bazel` — qaysi rule'lardan foydalanishni e'lon qiladi (apple_support macOS/Xcode toolchain'ini beradi, rules_swift Swift kompilyatsiyasini):

```starlark
# MODULE.bazel
module(name = "salom_taste", version = "1.0.0")

bazel_dep(name = "apple_support", version = "2.10.1")
bazel_dep(name = "rules_swift", version = "4.2.1")
```

Kutubxona kodi — bitta sof funksiya:

```swift
// Salom/Sources/Salom.swift
public func salomXabari(_ ism: String) -> String {
    "Salom, \(ism)! Bu Bazel bilan qurilgan."
}
```

Mana o'sha olti qatorlik BUILD fayl — dasturning butun "retsepti". Diqqat qiling: bu yerda **qanday** kompilyatsiya qilish haqida bir og'iz ham yo'q, faqat **nima** (nomi, manbalar, bog'liqlik):

```starlark
# App/BUILD.bazel
load("@rules_swift//swift:swift.bzl", "swift_binary")

swift_binary(
    name = "salom",
    srcs = ["main.swift"],
    deps = ["//Salom"],
)
```

Dastur kutubxonadan foydalanadi:

```swift
// App/main.swift
import Salom

print(salomXabari("dunyo"))
```

Kutubxona va test bitta BUILD faylda:

```starlark
# Salom/BUILD.bazel
load("@rules_swift//swift:swift.bzl", "swift_library", "swift_test")

swift_library(
    name = "Salom",
    srcs = ["Sources/Salom.swift"],
    module_name = "Salom",
    visibility = ["//visibility:public"],
)

swift_test(
    name = "SalomTests",
    srcs = ["Tests/SalomTests.swift"],
    deps = [":Salom"],
)
```

Test — oddiy XCTest (Bazel uni macOS'da simulyatorsiz, to'g'ridan-to'g'ri ishga tushiradi):

```swift
// Salom/Tests/SalomTests.swift
import XCTest
@testable import Salom

final class SalomTests: XCTestCase {
    func testXabarIsmniOzIchigaOladi() {
        XCTAssertEqual(salomXabari("Azimjon"),
                       "Salom, Azimjon! Bu Bazel bilan qurilgan.")
    }
}
```

Endi dasturni ishga tushiramiz. `bazel run` kerak bo'lsa avval quradi, keyin ishga tushiradi:

```bash
bazel run //App:salom
```

Natija:

```text
INFO: Found 1 target...
Target //App:salom up-to-date:
  bazel-bin/App/salom
INFO: Running command line: bazel-bin/App/salom
Salom, dunyo! Bu Bazel bilan qurilgan.
```

Test'ni ishga tushiramiz:

```bash
bazel test //Salom:SalomTests
```

```text
INFO: Found 1 test target...
//Salom:SalomTests                                    PASSED in 2.0s

Executed 1 out of 1 test: 1 test passes.
```

Endi super-kuchlarni o'z ko'zingiz bilan ko'ring. **Hech narsa o'zgartirmay** test'ni qayta ishga tushiring:

```text
//Salom:SalomTests                           (cached) PASSED in 2.0s

Executed 0 out of 1 test: 1 test passes.
```

`(cached) PASSED` va `Executed 0 out of 1 test` — test umuman ishga tushmadi, natija cache'dan keldi, chunki kirishlar o'zgarmadi. Endi `App/main.swift` da bitta qatorni o'zgartirib (`"dunyo"` → `"Bazel"`) qayta quramiz — Bazel atigi kerakli qismni qayta kompilyatsiya qiladi:

```text
INFO: Elapsed time: 0.916s, Critical Path: 0.82s
INFO: 4 processes: 2 internal, 1 darwin-sandbox, 1 worker.
```

295 ta action o'rniga **4 ta process** — faqat ilova qayta qurildi, kutubxona va test'lar tegilmadi.

### O'lchangan raqamlar

Mana shu kichik loyihada aniq o'lchangan vaqtlar. Bu raqamlar faqat shu misol va shu mashina uchun — lekin ular nisbatni aniq ko'rsatadi:

| Holat                                                                     | Vaqt                  | Izoh                                                                                                                             |
| ------------------------------------------------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Birinchi (sovuq) build: output base tozalangan, disk cache o'chirilgan    | **60.4 s**            | ko'p vaqt rules_swift'ning worker vositasini (abseil kutubxonasidan) kompilyatsiya qilishga ketadi — mashinaga bir martalik narx |
| Toza output base, lekin disk cache to'la ("yangi jamoadosh" / 2-checkout) | **1.8–2.5 s**         | 177 ta disk cache hit — ish allaqachon bir marta hisoblangan                                                                     |
| O'zgarishsiz qayta build (no-op)                                          | **0.125 s**           | "up-to-date", hech narsa qilinmaydi                                                                                              |
| `App/main.swift` da 1 qator o'zgartirib qayta build                       | **0.916 s**           | atigi 4 ta process, faqat ilova qayta kompilyatsiya                                                                              |
| Test birinchi marta                                                       | ~16.8 s               | kompilyatsiya + ishga tushirish                                                                                                  |
| Test o'zgarishsiz qayta                                                   | **`(cached) PASSED`** | 0 ta test bajariladi, natija cache'dan                                                                                           |

> **📊 Real raqamlar:** Apple M4 Pro (12 core, 24 GB), Xcode 27.1 (27A9275), Bazel 9.3.0, rules_swift 4.2.1, apple_support 2.10.1 bilan shu misol loyihada o'lchangan (2026-10-13). Taqqoslash uchun: xuddi shu mashinada o'lchangan ikki modulli SwiftUI iOS ilovasida sovuq build 83.7 s, disk cache bilan qayta build 1.9 s, bir Swift faylni o'zgartirib inkremental build 3.0 s chiqqan.

Diqqat qiling: 60.4 soniya "sovuq" raqam sizni cho'chitmasin. U mashinada **bir marta** to'lanadi (worker vositasi kompilyatsiyasi), keyin disk cache orqali hamma build va hamma jamoadosh undan foydalanadi. Kundalik hayot — bu 0.1–1 soniyalik inkremental buildlar va cache'langan test'lar. Aynan shu narsa Xcode'ning "clean qilib, 2 daqiqa kutish" dunyosidan farq qiladi.

### Build grafini ko'rish: `bazel query`

Xuddi shu kichik loyihada Bazel'ning 6-super-kuchini — build grafini so'rovlashni — ham sinab ko'rsak bo'ladi. "`salom` dasturi nimalarga bog'liq?" degan savolga Bazel aniq javob beradi:

```bash
bazel query 'deps(//App:salom)' --output label
```

```text
//App:main.swift
//App:salom
//Salom:Salom
//Salom:Sources/Salom.swift
```

Teskari savol yanada qiziq: "`Salom` kutubxonasini o'zgartirsam, nima ta'sirlanadi?" — `rdeps` (reverse deps) buni aytadi:

```bash
bazel query 'rdeps(//..., //Salom:Salom)'
```

```text
//App:salom
//Salom:Salom
//Salom:SalomTests
```

Ya'ni `Salom`'ni o'zgartirsak, `salom` dasturi ham, `SalomTests` test'i ham qayta qurilishi/ishga tushishi kerak — boshqa hech nima. Katta loyihada aynan shu so'rov CI'ga "faqat shu o'zgarishdan ta'sirlangan test'larni ishga tushir" deyish imkonini beradi (11-darsda qo'llaymiz). Xcode'da bunday savolga javob beradigan vosita yo'q — bog'liqliklarni o'z xotirangizda saqlashga majbursiz.

---

## 6. Real dunyo: kim Bazel'dan foydalanadi va nima deydi {#real-dunyo}

Bu kursning qattiq qoidasi — faqat manbasi bor raqamlar. Shuning uchun quyida har bir da'vo ortida havola bor, va qaysi raqam vendor (sotuvchi) tomonidan e'lon qilinganini alohida belgilaymiz.

### Kimlar Bazel'ni iOS uchun ishlatadi

`rules_xcodeproj` (Bazel loyihasidan Xcode loyihasi generatsiya qiluvchi vosita, 9-darsda o'rganamiz) o'z README'sida foydalanuvchilarini sanaydi. Bu ro'yxatni biz disk'dagi manba nusxada o'z ko'zimiz bilan tekshirdik: **Cash App, Lyft, Reddit, Robinhood, Slack, Snap, Spotify, Square, Tinder, Gojek, Mercari, Faire Wholesale, Envoy Mobile.** Bular — iOS ilovalarini Bazel bilan quradigan, nomi tanish kompaniyalar. Bu ro'yxatning o'zi bir dalil: Bazel katta iOS jamoalarida sinovdan o'tgan.

### Spotify: p75 kutish vaqti to'rt baravar qisqardi

Spotify iOS ilovasini Buck'dan keyin Bazel'ga o'tkazdi. InfoQ'ning xabariga ko'ra (2023-yil 21-oktabr, Sergio De Simone; asl post Spotify muhandisi Patrick Balestra'niki): PR'ni merge qilishdan oldingi **p75 (75-protsentil) kutish vaqti** 2022-yil mayda ~80 daqiqa edi, Bazel'dan keyin ~20 daqiqaga tushdi — "to'rt baravar". Eng og'ir CI konfiguratsiyasi (3 millionga yaqin qator kod va 800+ test target bilan) Xcode'da 45+ daqiqa olardi, Bazel'da 10 daqiqadan kamga tushdi. Spotify 3 yil tajriba qilgach, 2020-yilda Bazel'ni rasmiy build tizimi qilib tanladi va yutuqni "Bazel'ning samarali remote cache'i" bilan bog'ladi.

### Airbnb: generatsiya −60%, Xcode ochilishi −70%

Airbnb iOS build tizimini Buck'dan Bazel'ga ko'chirdi. InfoQ'ga ko'ra (2024-yil 21-fevral, asl post muhandislar Qing Yang va Andy Bartholomew'niki): maqsad "backend va frontend bo'ylab yagona, samarali build tajribasi" edi. Buck bilan taqqoslaganda loyiha generatsiyasi **60%** tezlashdi, Xcode ochilish vaqti **70%'dan ko'proq** qisqardi. Inkremental buildlar ham yaxshilandi, lekin asl post aniq foiz keltirmaydi (shuning uchun biz ham keltirmaymiz).

> **🏢 Real-world:** Rappi ham Bazel'ni (Buck o'rniga) tanladi, lekin bir muammoga duch keldi: CocoaPods pod'lari o'rtasida bo'lishilgan **private header**'lar tufayli sandboxing'ni o'chirishga majbur bo'ldi. Bu — Bazel'ning hermetiklik talabining real narxi: agar kodingiz e'lon qilinmagan fayllarga tayansa, Bazel buni sezadi va to'xtaydi; ba'zan sandboxing'ni o'chirish tezroq yo'l bo'ladi, lekin shunda hermetiklikning bir qismini yo'qotasiz.

### Raqamlarga qanday qarash kerak

Bu raqamlar ilhomlantiradi, lekin ularni to'g'ri o'qish muhim:

- **Har bir raqam — bir kompaniyaning o'z o'tmishi bilan taqqoslovi.** "Bazel Xcode'dan X% tez" degan universal haqiqat yo'q. Spotify o'z Xcode/Buck sozlamasi bilan, Airbnb o'z Buck sozlamasi bilan taqqoslagan.
- **Uch tomonlama (Bazel vs Tuist vs Xcode) neytral benchmark umuman mavjud emas** — biz qidirdik, topilmadi. Mavjud raqamlarning aksariyati yo kompaniyaning o'z o'tmishi bilan taqqoslovi, yo vendor (masalan Tuist yoki BuildBuddy) tomonidan o'tkazilgan.
- **"Katta iOS jamoasi" degani — yuzlab modul va o'nlab muhandis.** Keyingi bo'limda ko'ramizki, kichik jamoalar ko'pincha ataylab boshqa yo'l tanlaydi, va bu to'g'ri qaror.

> **⚠️ Diqqat:** Gojek va Bumble haqida internetda yuradigan ba'zi raqamlarni (masalan "Gojek CI 30 daqiqadan 10 daqiqaga") biz bu darsga **kiritmadik**, chunki birlamchi manbalarni (Medium maqolalari) ocha olmadik — ular 403 qaytardi. Manbasini tekshira olmagan raqamni keltirmaslik — bu kursning qoidasi.

---

## 7. Halol tomoni: narxi, cheklovlari va kim boshqa yo'l tanlagan {#halol-tomoni}

Bu kurs sizga Bazel'ni sotmaydi — o'rgatadi. Shuning uchun uning narxini ham xuddi super-kuchlari kabi ochiq aytamiz. Bazel — bepul vaqt-mashinasi emas; u aniq qiymatga ega.

### Narxi va cheklovlari

**O'rganish egri chizig'i va Starlark.** Bazel'ning BUILD fayllari `Starlark` tilida yoziladi (Python'ning qism to'plami, 4-darsda o'rganamiz). Bu yangi til va yangi tafakkur modeli. Asana muhandislari o'z tajribalarini (bu Tuist haqida, lekin Bazel bilan solishtirib) shunday yozgan: ular Bazel'ni rad etishdi, chunki u "juda og'ir asboblar to'plami bo'lib, yangi mental modellar talab qiladi".

**Xcode bilan integratsiya — alohida vosita talab qiladi.** Bazel BUILD fayllar bilan ishlaydi, Xcode esa `.xcodeproj` bilan. Ularni bog'lash uchun `rules_xcodeproj` kerak. Va bu integratsiyaning ochiq kamchiliklari bor:

- **SwiftUI Preview** hali ham to'liq ishlamaydi. `rules_xcodeproj` README'si "Xcode Previews" ni imkoniyat sifatida sanaydi, lekin 4.1.0 generatori hali ham `ENABLE_DEBUG_DYLIB = NO` o'rnatadi (muammo #3042), va bu Xcode 16+ preview'lariga to'sqinlik qiladi. Native preview qo'llab-quvvatlash so'rovi (muammo #3201) 2025-yil iyundan beri ochiq; buni hal qiladigan PR (#3325) ham hali ochiq, hech narsa reliz qilinmagan. Ya'ni Bazel generatsiya qilgan loyihada SwiftUI Preview'ga hozircha tayanib bo'lmaydi.
- **Xcode'ning Archive amali** `rules_xcodeproj` loyihalarida qo'llab-quvvatlanmaydi — App Store uchun `.ipa` ni to'g'ridan-to'g'ri `bazel build` bilan quriladi (BuildBuddy'ning migratsiya qo'llanmasi va rules_xcodeproj FAQ). Tanish "Product → Archive → Organizer" oqimi o'zgaradi.

**Migratsiya — oson emas.** Spotify Bazel bilan 3 yil **tajriba** qilgach, 2020-yilda uni rasmiy qilib oldi. Qo'shimcha narx: rule'larning major (katta) versiyalari tez-tez sinadi — `rules_xcodeproj` 2.0.0 (2024-yil aprel) → 3.0.0 (2025-yil iyun) → 4.0.0 (2026-yil mart), har biri buzuvchi o'zgarishlar bilan. Bu — doimiy saqlash (maintenance) narxi.

**rules_ios eskirmoqda.** Bir vaqtlar mashhur bo'lgan muqobil `rules_ios` ruleset'idan Square (uning asosiy homiysi) 2025-yil noyabrda **faol hissa qo'shishni to'xtatdi va undan ko'chmoqda** (muhokama #952); u o'rniga `rules_apple` + `rules_swift` ni tavsiya qiladi. Shuning uchun bu kurs faqat `rules_apple` + `rules_swift` ni o'rgatadi — biz zamonaviy va qo'llab-quvvatlanadigan yo'ldamiz.

**Katta miqyosda — build muhandisi kerak.** iOS uchun remote execution macOS "worker" pool'larini talab qiladi (Apple toolchain'lari Linux'da ishlamaydi) — bu qimmat va murakkab (MacStadium/Orka hujjatlari). Shuning uchun amaliy yutuq ko'pincha remote **cache**da (execution emas). Umuman, katta Bazel sozlamasi odatda hech bo'lmaganda bitta maxsus build/platforma muhandisini talab qiladi.

Mana shu cheklovlarning qisqa jadvali:

| Kamchilik                      | Nimani anglatadi                                | Qachon muhim                   |
| ------------------------------ | ----------------------------------------------- | ------------------------------ |
| Starlark + yangi model         | BUILD fayllar va mental modelni o'rganish kerak | boshida, butun jamoa uchun     |
| rules_xcodeproj kerak          | Xcode integratsiyasi to'g'ridan-to'g'ri emas    | kundalik Xcode ishi            |
| SwiftUI Preview gap            | preview'ga tayanib bo'lmaydi (#3201 ochiq)      | UI'ni preview bilan ishlaganda |
| Archive qo'llab-quvvatlanmaydi | `.ipa` ni `bazel build` bilan quriladi          | App Store'ga chiqarishda       |
| Major versiyalar sinadi        | 2.0→3.0→4.0 ~2 yilda                            | har yangilanishda              |
| Remote execution qimmat        | macOS worker pool kerak                         | juda katta jamoada             |

### Kim ataylab boshqa yo'l tanlagan

Eng foydali tajriba — Bazel'ni **rad etgan** jamoalarniki, chunki ular nega kerak emasligini aniq tushuntirib bergan.

**Asana → Tuist.** Asana (2022-yil boshida ~10 muhandis, ~300 ming qator Swift, deyarli hammasi bitta target'da) Bazel o'rniga Tuist'ni tanladi (post 2023-yil 21-fevral). Rad etish sabablari (asl matndan): Bazel'da "developer experience bilan jiddiy muammolar" bor edi, u "yangi mental modellar talab qiladigan juda og'ir asboblar to'plami", va "breakpoint'lar bilan ish oqimini buzadigan muammolar" bor edi. Tuist bilan natijalar: funksiyani o'zgartirib simulyatorda qayta qurish odatda ~45 soniyadan (Intel'da ~90 s edi) median 15 soniyaga (Scalyr log) tushdi; Inbox modulida bir qator o'zgartirish 30–50 soniyadan 4 soniyaga tushdi. Narxi: `git checkout` 5–15 soniya sekinlashdi, modullarga bo'lish ~3 oy oldi, va muhandislarning "faqat ozchiligi" Tuist ichki ishidan qulay his qildi.

**Back Market → Tuist.** Back Market ham (iOS-only, ikki ilovali sozlama) Bazel o'rniga Tuist'ni tanladi — Bazel ularning hajmi uchun ortiqcha edi. (Aniq raqamlarini keltirmaymiz, chunki asl postni ocha olmadik.)

> **🧠 Esda tuting:** Bazel'ni rad etish — mag'lubiyat emas, muhandislik qarori. Agar sizda 10 ta muhandis va bitta ilova bo'lsa, Asana kabi Tuist (yoki shunchaki yaxshi sozlangan Xcode) to'g'riroq tanlov bo'lishi mumkin. Keyingi bo'limda qachon qaysi birini tanlashni aniq ko'ramiz.

---

## 8. Kim Bazel'ni o'rganishi kerak (Xcode'da ishlasangiz ham) {#kimga}

### Qachon Bazel kerak EMAS

Halollik bilan: ko'pchilik iOS loyihalari uchun Bazel ortiqcha. Quyidagi holatlarda uni tanlamang:

- **Bitta iOS ilova yoki kichik jamoa.** Asana ~10 muhandis / 300k qator bilan Tuist'ni tanladi — va bu to'g'ri qaror edi.
- **Maxsus build/platforma muhandisi yo'q.** Bazel rule'lari tez-tez sinadi; ularni kuzatib boradigan odam kerak.
- **SwiftUI Preview, Archive/Organizer yoki Xcode boshqaradigan imzolashga qattiq tayanasiz.** Bular Bazel + rules_xcodeproj'da buzilgan yoki cheklangan.
- **CI vaqtingiz allaqachon maqbul.** Agar PR 10 daqiqada o'tsa, migratsiya narxi o'zini oqlamaydi.
- **Backend/Android bilan monorepo kerak emas.** Bazel'ning eng katta kuchi — ko'p tilli monorepo; bu sizga kerak bo'lmasa, kuchning yarmi ishlamay qoladi.

### Qachon Bazel yutadi

- **Katta, ko'p ilovali yoki ko'p tilli monorepo** (iOS + Android + backend).
- **Yuzlab muhandis o'rtasida bo'lishiladigan remote cache** — bu yerda cache hit stavkasi hamma narsani hal qiladi (Google ichida 99%'dan yuqori).
- **Hermetik, takrorlanadigan CI** — "menda ishlaydi" muammosini tizim darajasida o'ldirish.
- **Har bir action'ni cache qilish** — jumladan linking va bundling, ularni Xcode 26 cache'i hali to'liq qamramaydi (bir manbaga ko'ra, `Ld` cache qilinmaydi).

### Nega bu Xcode'da ishlasangiz ham foydali

Faraz qilaylik, sizning kompaniyangiz hech qachon Bazel'ga o'tmaydi. Baribir bu kursni o'rganish foydali, chunki **g'oyalar ko'chadi**:

- **Tuist** (bu saytdagi parallel modul, [tuist-01-kirish-va-ornatish](/ios-lessons/tuist-01-kirish-va-ornatish)) binary cache, target hashing va selective testing'ni ishlatadi — bularning hammasi aynan "build sof funksiya" g'oyasidan. Bazel'ni tushunsangiz, Tuist'ni ancha osonroq o'zlashtirasiz.
- **Xcode 26+ kompilyatsiya cache'i** Bazel bilan **bir xil model**da ishlaydi: action cache + content-addressed storage (CAS). Apple Bazel g'oyasini ko'chirdi; siz asl g'oyani tushunsangiz, Apple'ning sozlamalarini ham tushunasiz.
- **Gradle** (Android) ham artifact-based tomon harakat qilmoqda; **Buck2** (Meta) to'g'ridan-to'g'ri Bazel modeliga qurilgan. Build grafi, action key, cache — bu tushunchalar barcha zamonaviy build tizimlarida bir xil.

Karyera nuqtai nazaridan: yuqorida ko'rgan ro'yxat (Spotify, Lyft, Reddit, Robinhood, Slack, Snap, Square, Tinder, Cash App, Gojek, Mercari...) — bu aynan platforma/infratuzilma muhandislarini yollaydigan kompaniyalar. Build tizimlarini tushunish — mobil infratuzilma (mobile infrastructure / developer experience) rollari uchun kam uchraydigan va qadrli ko'nikma. Biz bu yerda aniq ish e'lonlari sonini keltirmaymiz (manbasiz raqam keltirmaslik qoidasi), lekin yo'nalish aniq: bu bilim sizni oddiy ilova dasturchisidan ajratib turadi.

---

## 9. Kurs xaritasi: 20 dars, noldan ekspertgacha {#kurs-xaritasi}

Bu kurs sizni Bazel haqida hech narsa bilmaydigan holatdan — o'z rule'laringizni yozadigan, remote cache sozlaydigan va real loyihalarni Bazel'ga ko'chiradigan darajagacha olib boradi. 20 dars besh bosqichga bo'lingan.

![Bazel kursining 20 darsini besh bosqichga bo'lib ko'rsatuvchi yo'l xaritasi diagrammasi: asoslar, iOS, tezlik, loyihalar, ekspert](/lessons/images/bazel/bazel_01_roadmap.svg)

**1-bosqich — Asoslar (1–4-darslar).** Bu bosqichdan keyin siz minimal workspace qurib, asosiy tushunchalarni (target, label, rule, build graph) bilib, Starlark'da oddiy macro yoza olasiz.

- [1-dars](/ios-lessons/bazel-01-kirish) — Bazel nima va nega kerak (shu dars).
- [2-dars](/ios-lessons/bazel-02-ornatish) — O'rnatish va birinchi build: Bazelisk, `.bazelversion`, `MODULE.bazel`, `.bazelrc` va "Salom, Bazel!".
- [3-dars](/ios-lessons/bazel-03-tushunchalar) — Asosiy tushunchalar: workspace, package, target, label, rule, visibility va build graph.
- [4-dars](/ios-lessons/bazel-04-starlark) — Starlark tili: BUILD va `.bzl` fayllar, macro'lar, `select()` va konfiguratsiya.

**2-bosqich — iOS'ni Bazel bilan qurish (5–9-darslar).** Bu bosqichdan keyin siz SwiftUI ilovani qurib, test yozib, tashqi SPM paketlarni ulab, uni Xcode'da ocha olasiz.

- [5-dars](/ios-lessons/bazel-05-ios-ilova) — Birinchi iOS ilova: `rules_apple`, `rules_swift`, SwiftUI, `Info.plist` va simulyator.
- [6-dars](/ios-lessons/bazel-06-testlar) — Testlar: `ios_unit_test`, XCTest va Swift Testing, test cache, coverage va UI testlar.
- [7-dars](/ios-lessons/bazel-07-dependency) — Tashqi dependency'lar: Bzlmod, BCR, SPM paketlari va xcframework'lar.
- [8-dars](/ios-lessons/bazel-08-ilova-anatomiyasi) — Haqiqiy ilova anatomiyasi: resurslar, lokalizatsiya, widget extension, framework, entitlements va signing.
- [9-dars](/ios-lessons/bazel-09-xcode) — Xcode bilan ishlash: `rules_xcodeproj`, indexing, debugging, SwiftUI Preview va VS Code.

**3-bosqich — Jamoa miqyosidagi tezlik (10–11-darslar).** Bu bosqichdan keyin siz action key'ni tushunib, remote cache sozlab, CI'da faqat o'zgargan narsani qura olasiz.

- [10-dars](/ios-lessons/bazel-10-cache) — Cache: action key, disk cache, remote cache, Build without the Bytes va cache-miss detektivligi.
- [11-dars](/ios-lessons/bazel-11-ci-cd) — CI/CD: GitHub Actions, remote cache, faqat o'zgarganini build/test qilish va release.

**4-bosqich — Besh loyiha (12–16-darslar).** Bu bosqichdan keyin siz CLI'dan to 12 modulli "SuperApp" va monorepo'gacha real loyihalarni Bazel bilan qurgan bo'lasiz.

- [12-dars](/ios-lessons/bazel-12-loyiha-valyuta-cli) — Loyiha #1: "Valyuta" CLI — Swift kutubxona + macOS buyruq qatori + testlar va birinchi o'lchovlar.
- [13-dars](/ios-lessons/bazel-13-loyiha-vazifalar) — Loyiha #2: "Vazifalar" iOS ilova — 4 modul, SwiftUI, JSON persistence va testlar.
- [14-dars](/ios-lessons/bazel-14-loyiha-obhavo) — Loyiha #3: "Ob-havo" ilova — Networking, SPM dependency, resurslar va mock testlar.
- [15-dars](/ios-lessons/bazel-15-loyiha-superapp) — Loyiha #4: 12 modulli "SuperApp" va jamoaviy remote cache.
- [16-dars](/ios-lessons/bazel-16-loyiha-monorepo) — Loyiha #5: Monorepo — iOS ilova + macOS CLI + umumiy kutubxona, visibility, query va "faqat ta'sirlanganini test qil".

**5-bosqich — Ekspert va ustalik (17–20-darslar).** Bu bosqichdan keyin siz o'z rule'laringizni yozib, performance'ni profil qilib, real loyihani Bazel'ga ko'chira olasiz va qachon qaysi vositani tanlashni bilasiz.

- [17-dars](/ios-lessons/bazel-17-custom-rules) — O'z rule'laringiz: `genrule`, `rule()`, provider'lar, depset'lar, aspect'lar va toolchain'lar.
- [18-dars](/ios-lessons/bazel-18-performance-rbe) — Performance tuning va Remote Execution: profil, critical path, worker'lar, xotira va RBE.
- [19-dars](/ios-lessons/bazel-19-migratsiya) — Xcode/SPM loyihasidan Bazel'ga migratsiya: strategiya, bosqichma-bosqich o'tish va real hikoyalar.
- [20-dars](/ios-lessons/bazel-20-best-practices) — Best practices, troubleshooting va karyera: Bazel vs Tuist vs SPM, qachon nimani tanlash.

> **🚀 Motivatsiya:** Hoziroq hamma narsani tushunmasangiz — bu normal. Bu dars xarita, keyingi darslar — yo'l. 2-darsda birinchi `bazel build` ni o'z mashinangizda ko'rasiz, 5-darsda simulyatorda SwiftUI ilovangiz ishga tushadi, 15-darsda esa jamoaviy cache build vaqtini sezilarli qisqartirganini o'z o'lchovlaringiz bilan ko'rasiz. Har bir dars — bitta aniq ko'nikma.

---

## Amaliy mashqlar {#mashqlar}

Bu dars motivatsiya va tushunchalar haqida, shuning uchun mashqlar ham ko'proq kuzatish va o'lchashga qaratilgan. To'liq o'rnatish va qo'l bilan build 2-darsda.

1. **O'z og'riqlaringizni aniqlang.** Oxirgi marta qachon Xcode'da "Clean Build Folder" qilgansiz va nega? `project.pbxproj` tufayli `git merge` konflikti bo'lganmi? Uch-to'rt jumlada yozing — bu og'riqlarning qaysi biri Bazel hal qiladigan turdan ekanini 2-bo'limga qarab aniqlang.

2. **O'z CI baseline'ingizni o'lchang.** Joriy loyihangizda oxirgi 5 ta PR'da CI necha daqiqa ketgan (o'rtacha va eng yomoni)? Lokal clean build qancha vaqt oladi? Bu raqamlarni yozib qo'ying — bu "o'lchab ko'r, keyin qaror qil" (measure-before-adopt) usuli, va kurs oxirida Bazel qanchalik yordam berishini aynan shu raqamlar bilan solishtirasiz.

3. **Task-based va artifact-based farqini o'z so'zlaringiz bilan.** Nega task-based tizim (masalan, Xcode'ning "Run Script" fazalari) ba'zan keraksiz ishni qayta qiladi? Nega artifact-based tizim (Bazel) buni "ishonch bilan" o'tkazib yubora oladi? 3-bo'limga qaramasdan yozib ko'ring, keyin tekshiring.

4. ⭐ **Real raqamni toping.** 6-bo'limdagi adopter ro'yxatidan (Spotify, Lyft, Reddit, Slack, Snap, Cash App...) bitta kompaniyani tanlang, ularning muhandislik blogi yoki konferentsiya chiqishidan Bazel/build haqidagi materialni toping va bitta aniq raqamni manba havolasi bilan yozing. (Maslahat: "<kompaniya> engineering bazel ios" deb qidiring.)

5. ⭐ **O'z qaroringizni chiqaring.** 8-bo'limdagi "qachon kerak / qachon kerak emas" mezonlariga joriy loyihangiz uchun javob bering: jamoa hajmi? ilovalar soni? maxsus build muhandisi bormi? SwiftUI Preview'ga tayanasizmi? CI vaqti maqbulmi? Shu asosda — Bazel sizga kerakmi? Qaroringizni bir xatboshida asoslang.

6. **Kurs xaritasini belgilang.** 9-bo'limdagi 20 darsdan qaysi uchtasi sizning joriy ehtiyojingizga eng yaqinini belgilang (masalan, cache, CI/CD yoki migratsiya) — kursni o'qib borar ekansiz, shu darslarga alohida e'tibor bering.

---

## O'zingizni tekshiring {#checklist}

- [ ] Build tizimi iOS ilovasida bajaradigan oltita bosqichni (compile → link → resurs → bundle → imzolash → `.ipa`) sanab bera olaman.
- [ ] Task-based va artifact-based build tizimlari orasidagi farqni ("qanday"ni aytish vs "nima"ni aytish) tushuntira olaman.
- [ ] "Clean qilsam tuzaladi" sindromi nega task-based tizimning strukturaviy kamchiligi ekanini bilaman.
- [ ] "Build — bu sof funksiya" degani nimani anglatishini va bundan tezlik hamda to'g'rilik qanday kelib chiqishini aytib bera olaman.
- [ ] Bazel'ning content hashing / action key timestamp'ga emas, mazmunga qarashini bilaman.
- [ ] Bazel'ning yettita super-kuchidan kamida beshtasini mexanizmi bilan ayta olaman.
- [ ] Bazel'ni qachon tanlamaslik kerakligini (kichik jamoa, Preview'ga tayanish, maxsus muhandis yo'q) kamida uchta sabab bilan tushuntira olaman.
- [ ] `{Fast, Correct} — Choose two` shiorining ma'nosini va Blaze → Bazel tarixining asosiy sanalarini bilaman.

---

## Xulosa {#xulosa}

- **Build tizimi — dirijyor, kompilyator emas.** Xcode ham, Bazel ham bir xil Apple asboblarini (`swiftc`, `ld`, `codesign`) chaqiradi; farq — ularni qanchalik aqlli boshqarishda.
- **Xcode task-based model** katta loyihada to'rt joyda og'riydi: `project.pbxproj` merge konfliktlari, yashirin bog'liqliklar, "clean qilsam tuzaladi" sindromi va jamoa/CI uchun umumiy cache yo'qligi.
- **Bazel artifact-based**: siz faqat **nima**ni qurishni e'lon qilasiz, **qanday**ni tizim hal qiladi. Build — bu sof funksiya; kirish o'zgarmasa, chiqish qayta ishlatiladi.
- **Yetti super-kuch** bitta g'oyadan o'sadi: to'g'ri inkremental build, hermetiklik, jamoaviy cache, parallel/remote execution, ko'p tilli monorepo, `bazel query` va cache'langan test natijalari. Shu mashinada: 1 qatorlik o'zgarish → 0.9 soniyalik inkremental build, o'zgarmagan test → `(cached) PASSED`.
- **Real tajriba, manba bilan**: Spotify p75 kutish vaqtini 4 baravar (80→20 daqiqa) qisqartirdi, Airbnb loyiha generatsiyasini 60% tezlashtirdi. Lekin uch tomonlama neytral benchmark yo'q — har bir raqam kompaniyaning o'z o'tmishi bilan taqqoslovi.
- **Narxi ham bor**: Starlark o'rganish, `rules_xcodeproj`, SwiftUI Preview gap, Archive qo'llab-quvvatlanmasligi, tez sinadigan major versiyalar. Asana (~10 muhandis, bitta ilova) ataylab Tuist'ni tanladi — va bu to'g'ri qaror edi.
- **Bazel bilim sifatida qimmatli**, hatto Xcode'da qolsangiz ham: g'oyalar Tuist'ga, Xcode 26 kompilyatsiya cache'iga, Gradle va Buck2'ga ko'chadi.
- **Keyingi dars:** [Bazel 2: O'rnatish va birinchi build — Bazelisk, .bazelversion, MODULE.bazel, .bazelrc va "Salom, Bazel!"](/ios-lessons/bazel-02-ornatish)

---

## Manbalar {#manbalar}

1. [Bazel — Task-Based Build Systems](https://bazel.build/basics/task-based-builds) — task-based tizimlar va ularning kamchiliklari.
2. [Bazel — Artifact-Based Build Systems](https://bazel.build/basics/artifact-based-builds) — Bazel modeli, "build sof funksiya" g'oyasi, sandboxing, tashqi bog'liqlik hashing.
3. [Bazel — Why Bazel?](https://bazel.build/about/why) — fast / correct / extensible; Google'da 99%'dan yuqori cache hit.
4. [Bazel — FAQ](https://bazel.build/about/faq) — Blaze ichki nomi, Google'ning Makefile tarixi, nega Bazel yaratilgan.
5. [Bazel GitHub README](https://github.com/bazelbuild/bazel) — `{Fast, Correct} — Choose two` shiori.
6. [Bazel 9.0 blog (2026-01-20)](https://blog.bazel.build/2026/01/20/bazel-9.html) — WORKSPACE olib tashlandi, Bzlmod doimiy yoqilgan.
7. [Bazel 1.0 (2019-10-10)](https://blog.bazel.build/2019/10/10/bazel-1.0.html) va [Bazel Reaches 1.0 Milestone (2019-10-17)](https://blog.bazel.build/2019/10/17/bazel-reaches-10-milestone.html) — birinchi GA reliz, semantik versiyalash, LTS.
8. [Bazel reaches Beta (2015-09, Google Open Source blog)](https://opensource.googleblog.com/2015/09/building-build-system-bazel-reaches-beta.html) — Bazel'ning ochiq kodga chiqishi.
9. [Bazel GitHub Releases](https://github.com/bazelbuild/bazel/releases) — 9.3.0 (2026-10-07), 8.8.1, 10.0.0rc1 sanalari.
10. [rules_swift docs (rules.md)](https://github.com/bazelbuild/rules_swift/blob/main/doc/rules.md) — `swift_binary`, `swift_library`, `swift_test` atributlari.
11. [rules_apple](https://github.com/bazelbuild/rules_apple) — iOS rule'lari; `BundleApp`/linking/signing action'lari.
12. [rules_xcodeproj README](https://github.com/MobileNativeFoundation/rules_xcodeproj) — foydalanuvchilar ro'yxati (Cash App, Lyft, Reddit, Slack, Snap, Spotify, Square, Tinder, Gojek, Mercari...).
13. [rules_xcodeproj — SwiftUI Preview support (issue #3201)](https://github.com/MobileNativeFoundation/rules_xcodeproj/issues/3201) — ochiq preview muammosi.
14. [rules_ios — maintainers winding down (discussion #952)](https://github.com/bazel-ios/rules_ios/discussions/952) — Square faol hissani to'xtatmoqda, rules_apple + rules_swift tavsiyasi.
15. [How Spotify Transitioned to Bazel (InfoQ, 2023-10-21)](https://www.infoq.com/news/2023/10/spotify-bazel-ios-transition/) — p75 kutish vaqti 80→20 daqiqa, eng og'ir CI 45+→<10 daqiqa.
16. [Airbnb migrates iOS build from Buck to Bazel (InfoQ, 2024-02-21)](https://www.infoq.com/news/2024/02/airbnb-bazel-migration-ios/) — generatsiya −60%, Xcode ochilishi −70%.
17. [Asana — Scaling a mature iOS codebase with Tuist (2023-02-21)](https://asana.com/inside-asana/scaling-a-mature-ios-codebase-with-tuist) — nega Bazel rad etilgan, Tuist raqamlari.
18. [BuildBuddy — How to migrate an iOS app to Bazel (2024-03-13)](https://www.buildbuddy.io/blog/how-to-migrate-an-ios-app-to-bazel/) — migratsiya bosqichlari, Archive qo'llab-quvvatlanmasligi.
19. [Tuist — Xcode compilation cache (2025-10-22)](https://tuist.dev/blog/2025/10/22/xcode-cache) — Xcode 26 cache'i action cache + CAS modeli (Bazel kabi); cache qilinmaydigan action'lar.
