Membuat aplikasi dengan Platform

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.
Laporkan masalah Lihat sumber

Bazel memiliki dukungan canggih untuk pemodelan platform dan Toolchain. Integrasi dengan project sungguhan memerlukan kerja sama yang cermat antara pemilik kode, pengelola aturan, dan developer Bazel inti.

Halaman ini merangkum tujuan platform dan menunjukkan cara mem-build dengan platform tersebut.

tl;dr: Platform dan API toolchain Bazel tersedia, tetapi tidak akan berfungsi di mana pun hingga semua aturan bahasa, select(), dan referensi lama lainnya diperbarui. Hal ini akan terus dilakukan. Pada akhirnya, semua build akan berbasis platform. Baca di bawah ini untuk melihat kecocokan build Anda.

Untuk dokumentasi yang lebih formal, lihat:

Latar belakang

Platform dan Toolchain diperkenalkan untuk membuat standardisasi cara project software menargetkan berbagai mesin dan mem-build dengan alat bahasa yang tepat.

Ini adalah tambahan yang relatif baru untuk Bazel. Contoh ini diinspirasi oleh pengamatan bahwa pengelola bahasa sudah melakukan hal ini dengan cara yang tidak kompatibel dan bersifat ad hoc. Misalnya, aturan C++ menggunakan --cpu dan --crosstool_top untuk menetapkan toolchain CPU dan C++ target build. Tidak satu pun dari model ini yang memodelkan "platform" dengan benar. Upaya historis untuk melakukannya menyebabkan build yang canggung dan tidak akurat. Tanda ini juga tidak mengontrol kompilasi Java, yang mengembangkan antarmuka independennya dengan --java_toolchain.

Bazel ditujukan untuk project besar multi-bahasa dan multi-platform. Hal ini memerlukan dukungan yang lebih prinsip untuk konsep ini, termasuk API yang jelas yang mendorong bahasa dan interoperabilitas project. Inilah kegunaan API baru ini.

Migrasi

Platform dan API toolchain hanya berfungsi jika project benar-benar menggunakannya. Hal ini tidaklah mudah karena logika aturan, toolchain, dependensi, dan select() project harus mendukungnya. Hal ini memerlukan urutan migrasi yang cermat agar semua project dan dependensinya tetap berfungsi dengan benar.

Misalnya, Dukungan Aturan C++ Bazel. Namun, Aturan Apple tidak. Project C++ Anda mungkin tidak peduli dengan Apple. Namun, ada kemungkinan untuk melakukannya. Oleh karena itu, mengaktifkan platform untuk semua build C++ secara global belum aman.

Bagian selanjutnya dari halaman ini menjelaskan urutan migrasi ini serta bagaimana dan kapan project Anda cocok.

Sasaran

Migrasi platform Bazel selesai jika semua project di-build dengan formulir:

bazel build //:myproject --platforms=//:myplatform

Ini menyiratkan:

  1. Aturan yang digunakan project Anda dapat menyimpulkan toolchain yang benar dari //:myplatform.
  2. Aturan yang digunakan dependensi project Anda dapat menyimpulkan toolchain yang benar dari //:myplatform.
  3. Baik project bergantung pada dukungan Anda //:myplatform atau project Anda mendukung API lama (seperti --crosstool_top).
  4. //:myplatform mereferensikan deklarasi umum CPU, OS, dan konsep umum lainnya yang mendukung kompatibilitas lintas project otomatis.
  5. Semua select() project yang relevan memahami properti mesin yang tersirat oleh //:myplatform.
  6. //:myplatform ditentukan di tempat yang jelas dan dapat digunakan kembali: di replika project Anda jika platform bersifat unik untuk project Anda, jika tidak, semua project yang mungkin menggunakan platform ini dapat ditemukan.

API lama akan dihapus segera setelah sasaran ini tercapai. Maka, hal ini akan menjadi cara standar project memilih platform dan toolchain.

Haruskah saya menggunakan platform?

Jika hanya ingin mem-build atau mengompilasi silang project, Anda harus mengikuti dokumentasi resmi project.

Jika Anda adalah project, bahasa, atau pengelola toolchain, Anda sebaiknya mendukung API baru. Apakah Anda menunggu hingga migrasi global selesai atau memilih ikut serta lebih awal, bergantung pada kebutuhan nilai / biaya tertentu Anda:

Nilai

  • Anda dapat select() atau memilih toolchain pada properti persis yang Anda minati, bukan flag hard code seperti --cpu. Misalnya, beberapa CPU dapat mendukung set petunjuk yang sama.
  • Build yang lebih benar. Jika Anda select() dengan --cpu dalam contoh di atas, lalu menambahkan CPU baru yang mendukung set petunjuk yang sama, select() akan gagal untuk mengenali CPU baru. Namun, select() di platform tetap akurat.
  • Pengalaman pengguna yang lebih sederhana. Semua project memahami: --platforms=//:myplatform. Tidak perlu beberapa flag khusus bahasa pada command line.
  • Desain bahasa yang lebih sederhana. Semua bahasa memiliki API yang sama untuk menentukan toolchain, menggunakan toolchain, dan memilih toolchain yang tepat untuk platform.
  • Target dapat dilewati dalam fase build dan pengujian jika tidak kompatibel dengan platform target.

Biaya

  • Project dependen yang belum mendukung platform mungkin tidak otomatis berfungsi dengan project Anda.
  • Untuk membuatnya berfungsi, Anda mungkin memerlukan pemeliharaan sementara tambahan.
  • Koeksistensi API baru dan lama memerlukan panduan pengguna yang lebih saksama untuk menghindari kebingungan.
  • Definisi kanonis untuk properti umum seperti OS dan CPU masih berkembang dan mungkin memerlukan kontribusi awal tambahan.
  • Definisi kanonis untuk toolchain khusus bahasa masih berkembang dan mungkin memerlukan kontribusi awal tambahan.

Peninjauan API

platform adalah kumpulan constraint_value target:

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value adalah properti mesin. Nilai "jenis" yang sama dikelompokkan dalam constraint_setting umum:

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

toolchain adalah aturan Starlark. Atribut ini mendeklarasikan alat bahasa (seperti compiler = "//mytoolchain:custom_gcc"). Penyedianya meneruskan informasi ini ke aturan yang perlu dibuat dengan alat ini.

Toolchain mendeklarasikan constraint_value mesin yang dapat ditargetkan (target_compatible_with = ["@platforms//os:linux"]) dan mesin yang dapat dijalankan (exec_compatible_with = ["@platforms//os:mac"]) oleh alat mereka.

Saat mem-build $ bazel build //:myproject --platforms=//:myplatform, Bazel akan otomatis memilih toolchain yang dapat berjalan di mesin build dan membuat biner untuk //:myplatform. Ini dikenal sebagai resolusi toolchain.

Kumpulan toolchain yang tersedia dapat didaftarkan di WORKSPACE dengan register_toolchains atau di command line dengan --extra_toolchains.

Lihat di sini untuk penjelasan lebih lanjut.

Status

Dukungan platform saat ini bervariasi antarbahasa. Semua aturan utama Bazel dipindahkan ke platform. Namun, proses ini akan memerlukan waktu yang lama. Hal ini disebabkan oleh tiga alasan utama:

  1. Logika aturan harus diperbarui untuk mendapatkan info alat dari API toolchain (ctx.toolchains) yang baru dan berhenti membaca setelan lama seperti --cpu dan --crosstool_top. Hal ini relatif mudah.

  2. Pengelola toolchain harus menentukan toolchain dan membuatnya dapat diakses oleh pengguna (di repositori GitHub dan entri WORKSPACE). Secara teknis hal ini cukup mudah, tetapi harus diatur dengan cerdas untuk mempertahankan pengalaman pengguna yang mudah.

    Definisi platform juga diperlukan (kecuali jika Anda mem-build untuk mesin yang sama yang dijalankan Bazel). Umumnya, project harus menentukan platformnya sendiri.

  3. Project yang ada harus dimigrasikan. select() dan transisi juga harus dimigrasikan. Ini adalah tantangan terbesar. Hal ini sangat menantang untuk project multibahasa (yang mungkin gagal jika semua bahasa tidak dapat membaca --platforms).

Jika mendesain kumpulan aturan baru, Anda harus mendukung platform dari awal. Hal ini otomatis membuat aturan Anda kompatibel dengan aturan dan project lain, dengan peningkatan nilai saat API platform menjadi lebih umum.

Properti platform umum

Properti platform seperti OS dan CPU yang umum di seluruh project harus dideklarasikan di tempat standar yang terpusat. Hal ini mendorong kompatibilitas lintas project dan lintas bahasa.

Misalnya, jika MyApp memiliki select() pada constraint_value @myapp//cpus:arm dan SomeCommonLib memiliki select() pada @commonlib//constraints:arm, ini akan memicu mode "arm" dengan kriteria yang tidak kompatibel.

Properti umum secara global dideklarasikan dalam repo @platforms (sehingga label kanonis untuk contoh di atas adalah @platforms//cpu:arm). Properti umum bahasa harus dideklarasikan dalam repo bahasanya masing-masing.

Platform default

Umumnya, pemilik project harus menentukan platform eksplisit untuk mendeskripsikan jenis mesin yang ingin mereka buat. Ini kemudian dipicu dengan --platforms.

Jika --platforms tidak ditetapkan, Bazel akan ditetapkan secara default ke platform yang mewakili mesin build lokal. Ini dibuat secara otomatis di @local_config_platform//:host sehingga Anda tidak perlu menentukannya secara eksplisit. Ini memetakan OS mesin lokal dan CPU dengan constraint_value yang dideklarasikan di @platforms.

C++

Aturan C++ Bazel menggunakan platform untuk memilih toolchain saat Anda menetapkan --incompatible_enable_cc_toolchain_resolution (#7260).

Ini berarti Anda dapat mengonfigurasi project C++ dengan:

bazel build //:my_cpp_project --platforms=//:myplatform

bukan yang lama:

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

Jika project Anda adalah C++ murni dan tidak bergantung pada project non-C++, Anda dapat menggunakan platform dengan aman selama select dan transisi kompatibel. Lihat #7260 dan Mengonfigurasi toolchain C++ untuk panduan selengkapnya.

Mode ini tidak diaktifkan secara default. Ini karena project Apple masih mengonfigurasi dependensi C++ dengan --cpu dan --crosstool_top (contoh). Jadi, hal ini bergantung pada aturan Apple yang dimigrasikan ke platform.

Java

Aturan Java Bazel menggunakan platform.

Ini menggantikan flag lama --java_toolchain, --host_java_toolchain, --javabase, dan --host_javabase.

Untuk mempelajari cara menggunakan flag konfigurasi, lihat manual Bazel dan Java. Untuk informasi tambahan, lihat Dokumen desain.

Jika Anda masih menggunakan flag lama, ikuti proses migrasi di Masalah #7849.

Android

Aturan Android Bazel menggunakan platform untuk memilih toolchain saat Anda menetapkan --incompatible_enable_android_toolchain_resolution.

Opsi ini tidak diaktifkan secara default. Namun, migrasi sedang dalam proses.

Apel

Aturan Apple Bazel belum mendukung platform untuk memilih toolchain Apple.

Rangkaian ini juga tidak mendukung dependensi C++ yang mendukung platform karena menggunakan --crosstool_top lama untuk menetapkan toolchain C++. Hingga proses migrasi ini, Anda dapat menggabungkan project Apple dengan C++ yang kompatibel dengan platorm menggunakan pemetaan platform (contoh).

Bahasa lain

Jika Anda mendesain aturan untuk bahasa baru, gunakan platform untuk memilih toolchain bahasa Anda. Lihat dokumentasi toolchain untuk mengetahui panduan yang baik.

select()

Project dapat select() pada target constraint_value, tetapi tidak dapat menyelesaikan platform. Hal ini dimaksudkan agar select() mendukung sebanyak mungkin mesin. Library dengan sumber khusus ARM harus mendukung semua mesin yang didukung ARM kecuali jika ada alasan yang lebih spesifik.

Untuk memilih di satu atau beberapa constraint_value, gunakan:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

Hal ini sama dengan memilih secara tradisional di --cpu:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

Lihat detail selengkapnya di sini.

select di --cpu, --crosstool_top, dll. tidak memahami --platforms. Saat memigrasikan project ke platform, Anda harus mengonversinya menjadi constraint_values atau menggunakan pemetaan platform untuk mendukung kedua gaya melalui jendela migrasi.

Transisi

Transisi Starlark mengubah flag bawah pada bagian grafik build Anda. Jika project Anda menggunakan transisi yang menetapkan --cpu, --crossstool_top, atau flag lama lainnya, aturan yang membaca --platforms tidak akan melihat perubahan ini.

Saat memigrasikan project ke platform, Anda harus mengonversi perubahan seperti return { "//command_line_option:cpu": "arm" } ke return { "//command_line_option:platforms": "//:my_arm_platform" } atau menggunakan pemetaan platform untuk mendukung kedua gaya melalui jendela migrasi.

Cara menggunakan platform saat ini

Jika hanya ingin mem-build atau mengompilasi silang project, Anda harus mengikuti dokumentasi resmi project. Penentuan bahasa dan waktu untuk menentukan cara dan waktu integrasi dengan platform, serta nilai yang ditawarkannya bergantung pada pengelola bahasa dan project.

Jika Anda adalah project, bahasa, atau pengelola toolchain, dan build Anda tidak menggunakan platform secara default, Anda memiliki tiga opsi (selain menunggu migrasi global):

  1. Aktifkan flag "use platform" untuk bahasa project Anda (jika ada) dan lakukan pengujian apa pun yang diperlukan untuk melihat apakah project yang Anda sukai bekerja.

  2. Jika project yang penting bagi Anda masih bergantung pada flag lama seperti --cpu dan --crosstool_top, gunakan project tersebut bersama dengan --platforms:

    bazel build //:my_mixed_project --platforms==//:myplatform --cpu=... --crosstool_top=...
    

    Hal ini memerlukan biaya pemeliharaan (Anda harus memastikan bahwa setelannya cocok). Namun, hal ini akan berfungsi tanpa adanya transisi yang dapat ditolak.

  3. Tulis pemetaan platform untuk mendukung kedua gaya dengan memetakan setelan gaya --cpu ke platform yang sesuai, dan sebaliknya.

Pemetaan platform

Pemetaan platform adalah API sementara yang memungkinkan logika yang didukung platform dan yang didukung lama berdampingan dalam build yang sama melalui jendela penghentian yang terakhir.

Pemetaan platform adalah peta platform() ke kumpulan tanda lama yang sesuai atau kebalikannya. Contoh:

platforms:
  # Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
  //platforms:ios
    --cpu=ios_x86_64
    --apple_platform_type=ios

flags:
  # Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --cpu=ios_x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin
  --apple_platform_type=macos
    //platforms:macos

Bazel menggunakannya untuk menjamin semua setelan, baik yang berbasis platform maupun yang lama, diterapkan secara konsisten di seluruh build, termasuk melalui transisi.

Secara default, Bazel membaca pemetaan dari file platform_mappings di root ruang kerja Anda. Anda juga dapat menetapkan --platform_mappings=//:my_custom_mapping.

Lihat di sini untuk mengetahui detail selengkapnya.

Pertanyaan

Untuk dukungan umum dan pertanyaan tentang linimasa migrasi, hubungi bazel-discuss@googlegroups.com atau pemilik aturan yang sesuai.

Untuk diskusi tentang desain dan evolusi API platform/Toolchain, hubungi bazel-dev@googlegroups.com.

Lihat juga