Menulis Aturan di Windows

Laporkan masalah Lihat sumber Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Halaman ini berfokus pada penulisan aturan yang kompatibel dengan Windows, masalah umum dalam penulisan aturan portabel, dan beberapa solusi.

Jalur

Masalah:

  • Batas panjang: panjang jalur maksimum adalah 259 karakter.

    Meskipun Windows juga mendukung jalur yang lebih panjang (hingga 32.767 karakter), banyak program dibuat dengan batas yang lebih rendah.

    Perhatikan hal ini tentang program yang Anda jalankan dalam tindakan.

  • Direktori kerja: juga dibatasi hingga 259 karakter.

    Proses tidak dapat cd ke direktori yang panjangnya lebih dari 259 karakter.

  • Kepekaan huruf besar/kecil: Jalur Windows tidak peka huruf besar/kecil, jalur Unix peka huruf besar/kecil.

    Perhatikan hal ini saat membuat command line untuk tindakan.

  • Pemisah jalur: adalah garis miring terbalik (\`), not forward slash (/`).

    Bazel menyimpan jalur gaya Unix dengan pemisah /. Meskipun beberapa program Windows mendukung jalur gaya Unix, program lainnya tidak. Beberapa perintah bawaan di cmd.exe mendukungnya, beberapa tidak.

    Sebaiknya selalu gunakan \` separators on Windows: replace/with` saat Anda membuat command line dan variabel lingkungan untuk tindakan.

  • Jalur absolut: tidak dimulai dengan garis miring (/).

    Jalur absolut di Windows dimulai dengan huruf drive, seperti C:\foo\bar.txt. Tidak ada root sistem file tunggal.

    Perhatikan hal ini jika aturan Anda memeriksa apakah jalur bersifat absolut. Jalur absolut harus dihindari karena sering kali tidak portabel.

Solusi:

  • Buat jalur yang pendek.

    Hindari nama direktori yang panjang, struktur direktori bertingkat yang dalam, nama file yang panjang, nama ruang kerja yang panjang, nama target yang panjang.

    Semua ini dapat menjadi komponen jalur file input tindakan, dan dapat melebihi batas panjang jalur.

  • Gunakan root output singkat.

    Gunakan flag --output_user_root=<path> untuk menentukan jalur singkat untuk output Bazel. Sebaiknya siapkan drive (atau drive virtual) khusus untuk output Bazel (seperti file D:\`), and adding this line to your.bazelrc`:

    build --output_user_root=D:/
    

    atau

    build --output_user_root=C:/_bzl
    
  • Gunakan persimpangan.

    Secara umum, persimpangan adalah link simbolis direktori[1]. Gabungan mudah dibuat dan dapat mengarah ke direktori (di komputer yang sama) dengan jalur panjang. Jika tindakan build membuat persimpangan yang jalurnya pendek tetapi targetnya panjang, maka alat dengan batas jalur pendek dapat mengakses file di direktori yang digabungkan.

    Di file .bat atau di cmd.exe, Anda dapat membuat sambungan seperti berikut:

    mklink /J c:\path\to\junction c:\path\to\very\long\target\path
    

    [1]: Secara teknis Gabungan bukan Link Simbolis, tetapi demi tindakan build, Anda dapat menganggap Gabungan sebagai Link Simbolis Direktori.

  • Ganti / dengan `` di jalur dalam tindakan / envvar.

    Saat Anda membuat command line atau variabel lingkungan untuk suatu tindakan, buat jalur gaya Windows. Contoh:

    def as_path(p, is_windows):
        if is_windows:
            return p.replace("/", "\\")
        else:
            return p
    

Variabel lingkungan

Masalah:

  • Kepekaan huruf besar/kecil: Nama variabel lingkungan Windows tidak peka huruf besar/kecil.

    Misalnya, di Java, System.getenv("SystemRoot") dan System.getenv("SYSTEMROOT") menghasilkan hasil yang sama. (Hal ini juga berlaku untuk bahasa lain.)

  • Hermeticity: tindakan harus menggunakan sesedikit mungkin variabel lingkungan kustom.

    Variabel lingkungan adalah bagian dari kunci cache tindakan. Jika tindakan menggunakan variabel lingkungan yang sering berubah, atau bersifat khusus untuk pengguna, hal itu membuat aturan kurang dapat di-cache.

Solusi:

  • Hanya gunakan nama variabel lingkungan huruf besar.

    Fitur ini berfungsi di Windows, macOS, dan Linux.

  • Minimalkan lingkungan tindakan.

    Saat menggunakan ctx.actions.run, tetapkan lingkungan ke ctx.configuration.default_shell_env. Jika tindakan memerlukan lebih banyak variabel lingkungan, masukkan semuanya ke dalam kamus dan teruskan ke tindakan. Contoh:

    load("@bazel_skylib//lib:dicts.bzl", "dicts")
    
    def _make_env(ctx, output_file, is_windows):
        out_path = output_file.path
        if is_windows:
            out_path = out_path.replace("/", "\\")
        return dicts.add(ctx.configuration.default_shell_env, {"MY_OUTPUT": out_path})
    

Tindakan

Masalah:

  • Output yang dapat dieksekusi: Setiap file yang dapat dieksekusi harus memiliki ekstensi yang dapat dieksekusi.

    Ekstensi yang paling umum adalah .exe (file biner) dan .bat (skrip Batch).

    Perhatikan bahwa skrip shell (.sh) TIDAK dapat dieksekusi di Windows; Anda tidak dapat menentukannya sebagai ctx.actions.run executable. Tidak ada juga izin +x yang dapat dimiliki file, sehingga Anda tidak dapat mengeksekusi file arbitrer seperti di Linux.

  • Perintah Bash: Demi portabilitas, hindari menjalankan perintah Bash secara langsung dalam tindakan.

    Bash banyak digunakan pada sistem mirip Unix, tetapi sering kali tidak tersedia di Windows. Bazel sendiri semakin sedikit mengandalkan Bash (MSYS2), sehingga pada masa mendatang, pengguna cenderung tidak menginstal MSYS2 bersama dengan Bazel. Agar aturan lebih mudah digunakan di Windows, hindari menjalankan perintah Bash dalam tindakan.

  • Akhir baris: Windows menggunakan CRLF (\r\n), sistem mirip Unix menggunakan LF (\n).

    Perhatikan hal ini saat membandingkan file teks. Perhatikan setelan Git Anda, terutama akhir baris saat melakukan checkout atau commit. (Lihat setelan core.autocrlf Git.)

Solusi:

  • Gunakan aturan khusus tanpa Bash.

    native.genrule() adalah wrapper untuk perintah Bash, dan sering digunakan untuk memecahkan masalah sederhana seperti menyalin file atau menulis file teks. Anda dapat menghindari penggunaan Bash (dan menciptakan kembali roda): lihat apakah bazel-skylib memiliki aturan khusus untuk kebutuhan Anda. Tidak ada yang bergantung pada Bash saat dibangun/diuji di Windows.

    Contoh aturan build:

    • copy_file() (source, documentation): menyalin file ke tempat lain, dengan opsi menjadikannya dapat dieksekusi

    • write_file() (source, documentation): menulis file teks, dengan akhir baris yang diinginkan (auto, unix, atau windows), dan secara opsional menjadikannya dapat dieksekusi (jika berupa skrip)

    • run_binary() (source, documentation): menjalankan biner (atau aturan *_binary) dengan input dan output yang diharapkan sebagai tindakan build (ini adalah wrapper aturan build untuk ctx.actions.run)

    • native_binary() (sumber, dokumentasi): membungkus biner native dalam aturan *_binary, yang dapat Anda bazel run atau gunakan dalam atribut tool run_binary() atau atribut tools native.genrule()

    Contoh aturan pengujian:

    • diff_test() (source, documentation): menguji yang membandingkan konten dua file

    • native_test() (source, documentation): membungkus biner native dalam aturan *_test, yang dapat Anda bazel test

  • Di Windows, pertimbangkan untuk menggunakan skrip .bat untuk hal-hal sepele.

    Alih-alih menggunakan skrip .sh, Anda dapat menyelesaikan tugas sederhana dengan skrip .bat.

    Misalnya, jika Anda memerlukan skrip yang tidak melakukan apa pun, atau mencetak pesan, atau keluar dengan kode error tetap, maka file .bat sederhana sudah cukup. Jika aturan Anda menampilkan penyedia DefaultInfo(), kolom executable dapat merujuk ke file .bat tersebut di Windows.

    Karena ekstensi file tidak penting di macOS dan Linux, Anda selalu dapat menggunakan .bat sebagai ekstensi, bahkan untuk skrip shell.

    Perlu diketahui bahwa file .bat yang kosong tidak dapat dieksekusi. Jika Anda memerlukan skrip kosong, tulis satu spasi di dalamnya.

  • Gunakan Bash secara terarah.

    Dalam aturan build dan pengujian Starlark, gunakan ctx.actions.run_shell untuk menjalankan skrip Bash dan perintah Bash sebagai tindakan.

    Dalam makro Starlark, bungkus skrip dan perintah Bash dalam native.sh_binary() atau native.genrule(). Bazel akan memeriksa apakah Bash tersedia dan menjalankan skrip atau perintah melalui Bash.

    Dalam aturan repositori Starlark, coba hindari Bash sepenuhnya. Saat ini, Bazel tidak menawarkan cara untuk menjalankan perintah Bash secara teratur dalam aturan repositori.

Menghapus file

Masalah:

  • File tidak dapat dihapus saat terbuka.

    File yang terbuka tidak dapat dihapus (secara default), upaya penghapusan akan menghasilkan error "Akses Ditolak". Jika Anda tidak dapat menghapus file, mungkin proses yang sedang berjalan masih membukanya.

  • Direktori kerja dari proses yang sedang berjalan tidak dapat dihapus.

    Proses memiliki handle terbuka ke direktori kerjanya, dan direktori tidak dapat dihapus hingga proses berakhir.

Solusi:

  • Dalam kode Anda, coba tutup file dengan segera.

    Di Java, gunakan try-with-resources. Di Python, gunakan with open(...) as f:. Pada prinsipnya, coba tutup handle sesegera mungkin.