Fungsi

Daftar Isi

paket

package(default_deprecation, default_testonly, default_visibility, features)

Fungsi ini mendeklarasikan metadata yang berlaku untuk setiap aturan berikutnya dalam paket. Ini digunakan paling banyak sekali dalam sebuah paket (file BUILD).

Fungsi package() harus dipanggil tepat setelah semua pernyataan load() di bagian atas file, sebelum aturan apa pun.

Argumen

Atribut Deskripsi
default_visibility

List of labels; optional

Visibilitas default aturan dalam paket ini.

Setiap aturan dalam paket ini memiliki visibilitas yang ditentukan dalam atribut ini, kecuali jika ditentukan lain dalam atribut visibility aturan. Untuk informasi selengkapnya tentang sintaksis atribut ini, lihat dokumentasi visibilitas. Visibilitas default paket tidak berlaku untuk exports_files, yang bersifat publik secara default.

default_deprecation

String; optional

Menetapkan pesan deprecation default untuk semua aturan dalam paket ini.

default_testonly

Boolean; optional; default is False except as noted

Menetapkan properti testonly default untuk semua aturan dalam paket ini.

Dalam paket dengan javatests, nilai defaultnya adalah 1.

features

List strings; optional

Menetapkan berbagai tanda yang memengaruhi semantik file BUILD ini.

Fitur ini terutama digunakan oleh orang-orang yang mengerjakan sistem build untuk memberi tag pada paket yang memerlukan penanganan khusus. Jangan gunakan ini kecuali jika diminta secara eksplisit oleh seseorang yang menangani sistem build.

Contoh

Deklarasi di bawah mendeklarasikan bahwa aturan dalam paket ini hanya dapat dilihat oleh anggota grup paket //foo:target. Deklarasi visibilitas individual pada aturan, jika ada, akan menggantikan spesifikasi ini.
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

Fungsi ini menentukan kumpulan paket dan mengaitkan label dengan kumpulan. Label dapat direferensikan di atribut visibility.

Grup paket terutama digunakan untuk kontrol visibilitas. Target yang terlihat secara publik dapat direferensikan dari setiap paket dalam hierarki sumber. Target yang terlihat secara pribadi hanya dapat direferensikan dalam paketnya sendiri (bukan sub-paket). Di antara kondisi ekstrem ini, target dapat mengizinkan akses ke paketnya sendiri ditambah paket apa pun yang dijelaskan oleh satu atau beberapa grup paket. Untuk penjelasan yang lebih mendetail tentang sistem visibilitas, lihat atribut visibilitas.

Paket tertentu dianggap berada dalam grup jika cocok dengan atribut packages, atau sudah dimuat dalam salah satu grup paket lain yang disebutkan dalam atribut includes.

Grup paket secara teknis merupakan target teknis, tetapi tidak dibuat oleh aturan, dan tidak memiliki perlindungan visibilitas apa pun.

Argumen

Atribut Deskripsi
name

Name; required

Nama unik untuk target ini.

packages

List of strings; optional

Daftar yang berisi nol atau beberapa spesifikasi paket.

Setiap string spesifikasi paket dapat memiliki salah satu bentuk berikut:

  1. Nama lengkap paket, tanpa repositorinya, dimulai dengan garis miring ganda. Misalnya, //foo/bar menentukan paket yang memiliki nama tersebut dan yang berada di repositori yang sama dengan grup paket.
  2. Seperti di atas, tetapi dengan /... di akhir. Misalnya, //foo/... menentukan kumpulan //foo dan semua sub-paketnya. //... menentukan semua paket dalam repositori saat ini.
  3. String public atau private, yang masing-masing menentukan setiap paket atau tidak ada paket. (Formulir ini memerlukan penetapan flag --incompatible_package_group_has_public_syntax.)

Selain itu, dua jenis spesifikasi paket pertama juga dapat diawali dengan - untuk menunjukkan bahwa spesifikasi tersebut diabaikan.

Grup paket berisi paket yang cocok dengan setidaknya salah satu spesifikasi positifnya dan tidak ada spesifikasi negatifnya Misalnya, nilai [//foo/..., -//foo/tests/...] mencakup semua sub-paket //foo yang juga bukan sub-paket dari //foo/tests. (//foo sendiri disertakan, sedangkan //foo/tests tidak disertakan.)

Selain visibilitas publik, tidak ada cara untuk menentukan paket secara langsung di luar repositori saat ini.

Jika atribut ini tidak ada, sama dengan menyetelnya ke daftar kosong, yang juga sama dengan menyetelnya ke daftar yang hanya berisi private.

Catatan: Sebelum Bazel 6.0, spesifikasi //... memiliki perilaku lama yang sama dengan public. Perilaku ini diperbaiki saat --incompatible_fix_package_group_reporoot_syntax diaktifkan, yang merupakan setelan default setelah Bazel 6.0.

Catatan: Sebelum Bazel 6.0, jika atribut ini diserialisasi sebagai bagian dari bazel query --output=proto (atau --output=xml), garis miring di awal akan dihilangkan. Misalnya, //pkg/foo/... akan menghasilkan output sebagai \"pkg/foo/...\". Perilaku ini diperbaiki saat --incompatible_package_group_includes_double_slash diaktifkan, yang merupakan setelan default setelah Bazel 6.0.

includes

List of labels; optional

Grup paket lain yang disertakan dalam paket ini.

Label dalam atribut ini harus merujuk ke grup paket lainnya. Paket dalam grup paket yang direferensikan dianggap sebagai bagian dari grup paket ini. Ini bersifat transitif — jika grup paket a menyertakan grup paket b, dan b menyertakan grup paket c, setiap paket dalam c juga akan menjadi anggota a.

Saat digunakan bersama dengan spesifikasi paket yang diabaikan, perhatikan bahwa kumpulan paket untuk setiap grup terlebih dahulu dikomputasi secara independen, lalu hasilnya kemudian digabungkan. Ini berarti spesifikasi yang diabaikan di satu grup tidak memengaruhi spesifikasi di grup lain.

Contoh

Deklarasi package_group berikut menentukan grup paket yang disebut "tropis" yang berisi buah tropis.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

Deklarasi berikut menentukan grup paket aplikasi fiktif:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

exports_files

exports_files([label, ...], visibility, licenses)

exports_files() menentukan daftar file yang termasuk dalam paket ini yang diekspor ke paket lain.

File BUILD untuk sebuah paket hanya dapat merujuk langsung ke file sumber yang termasuk dalam paket lain jika file tersebut diekspor secara eksplisit dengan pernyataan exports_files(). Baca selengkapnya tentang visibilitas file.

Sebagai perilaku lama, file yang disebutkan sebagai input ke aturan juga diekspor dengan visibilitas default hingga flag --incompatible_no_implicit_file_export dibalik. Namun, perilaku ini tidak boleh diandalkan dan secara aktif dimigrasikan.

Argumen

Argumennya adalah daftar nama file dalam paket saat ini. Deklarasi visibilitas juga dapat ditentukan; dalam hal ini, file akan terlihat oleh target yang ditentukan. Jika tidak ada visibilitas yang ditentukan, file akan terlihat oleh setiap paket, meskipun visibilitas default paket telah ditentukan dalam fungsi package. Lisensi juga dapat ditentukan.

Contoh

Contoh berikut mengekspor golden.txt, file teks dari paket test_data, sehingga paket lain dapat menggunakannya, misalnya, dalam atribut data pengujian.

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob adalah fungsi bantuan yang menemukan semua file yang cocok dengan pola jalur tertentu, dan menampilkan daftar jalur yang baru, dapat diubah, dan diurutkan. Glob hanya menelusuri file dalam paketnya sendiri, dan hanya mencari file sumber (bukan file yang dihasilkan maupun target lainnya).

Label file sumber disertakan dalam hasil jika jalur relatif paket file tersebut cocok dengan pola include mana pun dan tidak dengan pola exclude.

Daftar include dan exclude berisi pola jalur yang relatif terhadap paket saat ini. Setiap pola dapat terdiri dari satu atau beberapa segmen jalur. Seperti biasa dengan jalur Unix, segmen ini dipisahkan oleh /. Segmen dapat berisi karakter pengganti *: karakter ini cocok dengan substring apa pun di segmen jalur (bahkan substring kosong), kecuali pemisah direktori /. Karakter pengganti ini dapat digunakan beberapa kali dalam satu segmen jalur. Selain itu, karakter pengganti ** dapat cocok dengan nol atau beberapa segmen jalur lengkap, tetapi harus dideklarasikan sebagai segmen jalur mandiri.

Contoh:
  • foo/bar.txt sama persis dengan file foo/bar.txt dalam paket ini
  • foo/*.txt cocok dengan setiap file dalam direktori foo/ jika file diakhiri dengan .txt (kecuali jika foo/ adalah sub-paket)
  • foo/a*.htm* mencocokkan setiap file dalam direktori foo/ yang dimulai dengan a, lalu memiliki string arbitrer (bisa kosong), kemudian memiliki .htm, dan diakhiri dengan string arbitrer lainnya; seperti foo/axx.htm dan foo/a.html atau foo/axxx.html
  • **/a.txt cocok dengan setiap file a.txt di setiap subdirektori paket ini
  • **/bar/**/*.txt cocok dengan setiap file .txt di setiap subdirektori paket ini, jika setidaknya satu direktori pada jalur yang dihasilkan disebut bar, seperti xxx/bar/yyy/zzz/a.txt atau bar/a.txt (ingat bahwa ** juga cocok dengan nol segmen) atau bar/zzz/a.txt
  • ** cocok dengan setiap file di setiap subdirektori paket ini
  • foo**/a.txt adalah pola yang tidak valid, karena ** harus berdiri sendiri sebagai segmen

Jika argumen exclude_directories diaktifkan (ditetapkan ke 1), file direktori jenis akan dihilangkan dari hasil (default 1).

Jika argumen allow_empty ditetapkan ke False, fungsi glob akan mengalami error jika hasilnya berupa daftar kosong.

Ada beberapa batasan dan peringatan penting:

  1. Karena glob() berjalan selama evaluasi file BUILD, glob() hanya mencocokkan file dalam hierarki sumber, bukan file yang dihasilkan. Jika Anda membuat target yang memerlukan file sumber maupun file yang dihasilkan, Anda harus menambahkan daftar eksplisit file yang dihasilkan ke glob tersebut. Lihat contoh di bawah dengan :mylib dan :gen_java_srcs.

  2. Jika aturan memiliki nama yang sama dengan file sumber yang cocok, aturan akan "bayangi" file tersebut.

    Untuk memahami hal ini, ingat bahwa glob() menampilkan daftar jalur, sehingga penggunaan glob() dalam atribut aturan lain (misalnya srcs = glob(["*.cc"])) memiliki efek yang sama dengan mencantumkan jalur yang cocok secara eksplisit. Jika misalnya glob() menghasilkan ["Foo.java", "bar/Baz.java"], tetapi ada juga aturan dalam paket bernama "Foo.java" (yang diizinkan, meskipun Bazel memperingatkan tentang hal itu), konsumen glob() akan menggunakan aturan "Foo.java" (outputnya) bukan file "Foo.java". Lihat Masalah GitHub #10395 untuk detail selengkapnya.

  3. Globs mungkin cocok dengan file di subdirektori. Selain itu, nama subdirektori mungkin memiliki karakter pengganti. Namun...
  4. Label tidak diizinkan melewati batas paket dan glob tidak cocok dengan file dalam sub-paket.

    Misalnya, ekspresi glob **/*.cc dalam paket x tidak menyertakan x/y/z.cc jika x/y ada sebagai paket (sebagai x/y/BUILD, atau di tempat lain di jalur-paket). Artinya, hasil ekspresi glob tersebut sebenarnya bergantung pada keberadaan file BUILD — yaitu, ekspresi glob yang sama akan menyertakan x/y/z.cc jika tidak ada paket yang disebut x/y atau ditandai sebagai dihapus menggunakan flag --deleted_packages.

  5. Pembatasan di atas berlaku untuk semua ekspresi glob, apa pun karakter pengganti yang digunakan.
  6. File tersembunyi dengan nama file yang diawali dengan . sepenuhnya dicocokkan dengan karakter pengganti ** dan *. Jika ingin mencocokkan file tersembunyi dengan pola gabungan, Anda harus memulai dengan .. Misalnya, * dan .*.txt akan cocok dengan .foo.txt, tetapi *.txt tidak. Direktori tersembunyi juga dicocokkan dengan cara yang sama. Direktori tersembunyi dapat mencakup file yang tidak diperlukan sebagai input, dan dapat meningkatkan jumlah file dengan glob yang tidak perlu serta pemakaian memori. Untuk mengecualikan direktori tersembunyi, tambahkan direktori tersebut ke argumen daftar "exclude".
  7. Karakter pengganti "**" memiliki satu kasus sudut: pola "**" tidak cocok dengan jalur direktori paket. Dengan kata lain, glob(["**"], exclude_directories = 0) cocok dengan semua file dan direktori secara transitif secara transitif dalam direktori paket saat ini (tetapi tentu saja tidak masuk ke direktori sub-paket - lihat catatan sebelumnya tentang hal itu).

Secara umum, Anda harus mencoba menyediakan ekstensi yang sesuai (mis. *.html), bukan menggunakan '*' kosong untuk pola glob. Nama yang lebih eksplisit adalah mendokumentasikan sendiri dan memastikan bahwa Anda tidak secara tidak sengaja mencocokkan file cadangan, atau file emacs/vi/... menyimpan otomatis.

Saat menulis aturan build, Anda dapat menghitung elemen glob. Hal ini memungkinkan pembuatan aturan individual untuk setiap input, misalnya. Lihat bagian contoh glob yang diperluas di bawah.

Contoh Glob

Buat library Java yang dibuat dari semua file java dalam direktori ini, dan semua file yang dihasilkan oleh aturan :gen_java_srcs.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

Sertakan semua file txt dalam direktori testdata, kecuali experiment.txt. Perhatikan bahwa file dalam subdirektori pengujian data tidak akan disertakan. Jika Anda ingin file tersebut disertakan, gunakan glob rekursif (**).

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

Contoh Glob Rekursif

Buat pengujian bergantung pada semua file txt dalam direktori testdata dan setiap subdirektorinya (beserta subdirektorinya, dan seterusnya). Subdirektori yang berisi file BUILD akan diabaikan. (Lihat batasan dan peringatan di atas.)

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

Buat library yang dibuat dari semua file java dalam direktori ini dan semua subdirektori kecuali yang jalurnya menyertakan direktori bernama pengujian. Pola ini harus dihindari jika memungkinkan, karena dapat mengurangi inkrementalitas build sehingga meningkatkan waktu build.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Contoh Glob yang Diperluas

Buat genrule individual untuk *_test.cc di direktori saat ini yang menghitung jumlah baris dalam file.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

Jika file BUILD di atas berada dalam paket //foo dan paket tersebut berisi tiga file yang cocok, a_test.cc, b_test.cc, dan c_test.cc, menjalankan bazel query '//foo:all' akan mencantumkan semua aturan yang dihasilkan:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

pilih

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() adalah fungsi helper yang membuat atribut aturan dapat dikonfigurasi. Atribut ini dapat menggantikan sisi kanan hampir semua penetapan atribut sehingga nilainya bergantung pada flag Bazel command line. Anda dapat menggunakannya, misalnya, untuk menentukan dependensi khusus platform atau menyematkan resource yang berbeda, bergantung pada apakah aturan dibuat dalam mode "developer" atau "rilis".

Penggunaan dasarnya adalah sebagai berikut:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

Hal ini membuat atribut srcs dari sh_binary dapat dikonfigurasi dengan mengganti penetapan daftar label normalnya dengan panggilan select yang memetakan kondisi konfigurasi ke nilai yang cocok. Setiap kondisi adalah referensi label ke config_setting atau constraint_value, yang "cocok" jika konfigurasi target cocok dengan kumpulan nilai yang diharapkan. Nilai mytarget#srcs kemudian menjadi daftar label mana pun yang cocok dengan pemanggilan saat ini.

Catatan:

  • Hanya satu kondisi yang dipilih pada pemanggilan apa pun.
  • Jika beberapa kondisi cocok dan salah satunya adalah spesialisasi dari yang lainnya, spesialisasi akan lebih diutamakan. Kondisi B dianggap sebagai spesialisasi kondisi A jika B memiliki semua tanda dan nilai batasan yang sama dengan A, ditambah beberapa tanda tambahan atau nilai batasan. Hal ini juga berarti bahwa penyelesaian spesialisasi tidak dirancang untuk membuat pengurutan seperti yang ditunjukkan dalam Contoh 2 di bawah.
  • Jika beberapa kondisi cocok dan satu kondisi bukan merupakan spesialisasi dari semua kondisi lainnya, Bazel akan gagal dengan menampilkan error.
  • //conditions:default label semu khusus dianggap cocok jika tidak ada kondisi lain yang cocok. Jika kondisi ini tidak disertakan, beberapa aturan lain harus cocok untuk menghindari error.
  • select dapat disematkan di dalam penetapan atribut yang lebih besar. Jadi, srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) dan srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) adalah ekspresi yang valid.
  • select berfungsi dengan sebagian besar atribut, tetapi tidak semua. Atribut yang tidak kompatibel ditandai sebagai nonconfigurable dalam dokumentasinya.

    sub-paket

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() adalah fungsi helper, mirip dengan glob() yang mencantumkan sub-paket, bukan file dan direktori. Class ini menggunakan pola jalur yang sama dengan glob() dan dapat cocok dengan subpaket apa pun yang merupakan turunan langsung dari file BUILD yang sedang dimuat. Lihat glob untuk penjelasan mendetail dan contoh pola sertakan dan pengecualian.

    Daftar sub-paket yang dihasilkan ditampilkan dalam urutan yang diurutkan dan berisi jalur yang relatif terhadap paket pemuatan saat ini yang cocok dengan pola yang diberikan di include dan bukan yang ada dalam exclude.

    Contoh

    Contoh berikut mencantumkan semua subpaket langsung untuk paket foo/BUILD

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

    Secara umum, sebaiknya pengguna menggunakan modul 'sub-paket' skylib, bukan memanggil fungsi ini secara langsung.