Bermigrasi dari Xcode ke Bazel

Halaman ini menjelaskan cara membangun atau menguji project Xcode dengan Bazel. Dokumen ini menjelaskan perbedaan antara Xcode dan Bazel, serta memberikan langkah-langkah untuk mengonversi project Xcode menjadi project Bazel. Artikel ini juga memberikan solusi pemecahan masalah untuk mengatasi error umum.

Perbedaan antara Xcode dan Bazel

  • Bazel mengharuskan Anda menentukan setiap target build dan dependensinya secara eksplisit, serta setelan build yang sesuai melalui aturan build.

  • Bazel mewajibkan semua file yang menjadi dependensi project ada dalam direktori ruang kerja atau ditentukan sebagai dependensi dalam file MODULE.bazel.

  • Saat mem-build project Xcode dengan Bazel, file BUILD menjadi sumber tepercaya. Jika Anda mengerjakan project di Xcode, Anda harus membuat versi baru project Xcode yang cocok dengan file BUILD menggunakan rules_xcodeproj setiap kali Anda memperbarui file BUILD. Perubahan tertentu pada file BUILD, seperti menambahkan dependensi ke target, tidak memerlukan pembuatan ulang project yang dapat mempercepat pengembangan. Jika Anda tidak menggunakan Xcode, perintah bazel build dan bazel test memberikan kemampuan build dan pengujian dengan batasan tertentu yang dijelaskan nanti dalam panduan ini.

Sebelum memulai

Sebelum memulai, lakukan hal berikut:

  1. Instal Bazel jika Anda belum melakukannya.

  2. Jika Anda belum familier dengan Bazel dan konsepnya, selesaikan tutorial aplikasi iOS). Anda harus memahami ruang kerja Bazel, termasuk file MODULE.bazel dan BUILD, serta konsep target, aturan build, dan paket Bazel.

  3. Menganalisis dan memahami dependensi project.

Menganalisis dependensi project

Tidak seperti Xcode, Bazel mengharuskan Anda mendeklarasikan semua dependensi secara eksplisit untuk setiap target dalam file BUILD.

Untuk mengetahui informasi selengkapnya tentang dependensi eksternal, lihat Bekerja dengan dependensi eksternal.

Membangun atau menguji project Xcode dengan Bazel

Untuk membuat atau menguji project Xcode dengan Bazel, lakukan hal berikut:

  1. Buat file MODULE.bazel

  2. (Eksperimental) Mengintegrasikan dependensi SwiftPM

  3. Buat file BUILD:

    a. Tambahkan target aplikasi

    b. (Opsional) Tambahkan target pengujian

    c. Tambahkan target library

  4. (Opsional) Membagi-bagi build

  5. Jalankan build

  6. Buat project Xcode dengan rules_xcodeproj

Langkah 1: Buat file MODULE.bazel

Buat file MODULE.bazel di direktori baru. Direktori ini akan menjadi root ruang kerja Bazel. Jika project tidak menggunakan dependensi eksternal, file ini dapat kosong. Jika project bergantung pada file atau paket yang tidak ada di salah satu direktori project, tentukan dependensi eksternal ini dalam file MODULE.bazel.

Langkah 2: (Eksperimental) Mengintegrasikan dependensi SwiftPM

Untuk mengintegrasikan dependensi SwiftPM ke ruang kerja Bazel dengan swift_bazel, Anda harus mengonversinya menjadi paket Bazel seperti yang dijelaskan dalam tutorial berikut .

Langkah 3: Buat file BUILD

Setelah menentukan ruang kerja dan dependensi eksternal, Anda perlu membuat file BUILD yang memberi tahu Bazel cara project disusun. Buat file BUILD di root ruang kerja Bazel dan konfigurasikan untuk melakukan build awal project sebagai berikut:

Tips: Untuk mempelajari lebih lanjut paket dan konsep Bazel lainnya, lihat Ruang kerja, paket, dan target.

Langkah 3a: Tambahkan target aplikasi

Tambahkan target aturan macos_application atau ios_application. Target ini masing-masing membangun paket aplikasi macOS atau iOS. Di target, tentukan minimal hal berikut:

  • bundle_id - ID paket (jalur DNS terbalik diikuti dengan nama aplikasi) dari biner.

  • provisioning_profile - profil penyediaan dari akun Apple Developer Anda (jika membangun untuk perangkat iOS).

  • families (khusus iOS) - apakah akan membangun aplikasi untuk iPhone, iPad, atau keduanya.

  • infoplists - daftar file .plist yang akan digabungkan ke dalam file Info.plist akhir.

  • minimum_os_version - versi minimum macOS atau iOS yang didukung aplikasi. Tindakan ini memastikan Bazel mem-build aplikasi dengan level API yang benar.

Langkah 3b: (Opsional) Tambahkan target pengujian

Aturan build Apple Bazel mendukung pengujian unit dan UI di semua platform Apple. Tambahkan target pengujian sebagai berikut:

  • macos_unit_test untuk menjalankan pengujian unit berbasis library dan berbasis aplikasi di macOS.

  • ios_unit_test untuk membuat dan menjalankan pengujian unit berbasis library di iOS.

  • ios_ui_test untuk membuat dan menjalankan pengujian antarmuka pengguna di simulator iOS.

  • Aturan pengujian serupa ada untuk tvOS, watchOS dan visionOS.

Minimal, tentukan nilai untuk atribut minimum_os_version. Meskipun atribut kemasan lainnya, seperti bundle_identifier dan infoplists, secara default menggunakan nilai yang paling umum digunakan, pastikan nilai default tersebut kompatibel dengan project dan sesuaikan jika perlu. Untuk pengujian yang memerlukan simulator iOS, tentukan juga nama target ios_application sebagai nilai atribut test_host.

Langkah 3c: Tambahkan target pustaka

Tambahkan target objc_library untuk setiap library Objective-C dan target swift_library untuk setiap library Swift yang menjadi dependensi aplikasi dan/atau pengujian.

Tambahkan target library sebagai berikut:

  • Tambahkan target library aplikasi sebagai dependensi ke target aplikasi.

  • Tambahkan target library pengujian sebagai dependensi ke target pengujian.

  • Mencantumkan sumber penerapan dalam atribut srcs.

  • Cantumkan header dalam atribut hdrs.

Anda dapat menjelajahi contoh yang ada untuk berbagai jenis aplikasi langsung di direktori rules_apple examples. Contoh:

Untuk mengetahui informasi selengkapnya tentang aturan build, lihat Aturan Apple untuk Bazel.

Pada tahap ini, sebaiknya uji build:

bazel build //:<application_target>

Langkah 4: (Opsional) Buat build lebih terperinci

Jika project besar, atau saat project berkembang, pertimbangkan untuk membaginya menjadi beberapa paket Bazel. Perincian yang lebih tinggi ini memberikan:

  • Peningkatan inkrementalitas build,

  • Peningkatan paralelisasi tugas build,

  • Pemeliharaan yang lebih baik untuk pengguna di masa mendatang,

  • Kontrol yang lebih baik atas visibilitas kode sumber di seluruh target dan paket. Hal ini mencegah masalah seperti library yang berisi detail implementasi bocor ke API publik.

Tips untuk membagi project menjadi bagian-bagian kecil:

  • Letakkan setiap library dalam paket Bazel-nya sendiri. Mulailah dengan yang memerlukan paling sedikit dependensi dan lanjutkan ke atas pohon dependensi.

  • Saat Anda menambahkan file BUILD dan menentukan target, tambahkan target baru ini ke atribut deps target yang bergantung padanya.

  • Fungsi glob() tidak melintasi batas paket, sehingga seiring bertambahnya jumlah paket, file yang cocok dengan glob() akan berkurang.

  • Saat menambahkan file BUILD ke direktori main, tambahkan juga file BUILD ke direktori test yang sesuai.

  • Menerapkan batas visibilitas yang sehat di seluruh paket.

  • Bangun project setelah setiap perubahan besar pada file BUILD dan perbaiki error build saat Anda menemuinya.

Langkah 5: Jalankan build

Jalankan build yang telah dimigrasikan sepenuhnya untuk memastikan build selesai tanpa error atau peringatan. Jalankan setiap aplikasi dan target pengujian satu per satu untuk lebih mudah menemukan sumber dari setiap error yang terjadi.

Contoh:

bazel build //:my-target

Langkah 6: Buat project Xcode dengan rules_xcodeproj

Saat membangun dengan Bazel, file MODULE.bazel dan BUILD menjadi sumber kebenaran tentang build. Agar Xcode mengetahui hal ini, Anda harus membuat project Xcode yang kompatibel dengan Bazel menggunakan rules_xcodeproj.

Pemecahan masalah

Error Bazel dapat muncul saat tidak sinkron dengan versi Xcode yang dipilih, seperti saat Anda menerapkan update. Berikut beberapa hal yang dapat dicoba jika Anda mengalami error dengan Xcode, misalnya "Xcode version must be specified to use an Apple CROSSTOOL".

  • Jalankan Xcode secara manual dan setujui persyaratan dan ketentuan apa pun.

  • Gunakan Xcode select untuk menunjukkan versi yang benar, menyetujui lisensi, dan menghapus status Bazel.

  sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
  sudo xcodebuild -license
  bazel sync --configure
  • Jika tidak berhasil, Anda juga dapat mencoba menjalankan bazel clean --expunge.