Fungsi

Laporkan masalah Lihat sumber Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Daftar Isi

paket

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

Fungsi ini mendeklarasikan metadata yang berlaku untuk setiap aturan dalam paket. Ini digunakan maksimal sekali dalam paket (file BUILD).

Untuk pasangan yang mendeklarasikan metadata yang berlaku untuk setiap aturan di seluruh repositori, gunakan fungsi repo() dalam file REPO.bazel di root repo Anda. Fungsi repo() menggunakan argumen yang sama persis dengan package().

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

Argumen

Atribut Deskripsi
default_applicable_licenses

Alias untuk default_package_metadata.

default_visibility

Daftar label; default-nya adalah []

Visibilitas default target aturan level teratas dan makro simbolis dalam paket ini — yaitu, target dan makro simbolis yang tidak dideklarasikan di dalam makro simbolis. Atribut ini diabaikan jika target atau makro menentukan nilai visibility.

Untuk mengetahui informasi mendetail tentang sintaksis atribut ini, lihat dokumentasi visibilitas. Visibilitas default paket tidak berlaku untuk exports_files, yang bersifat publik secara default.

default_deprecation

String; default-nya adalah ""

Menetapkan pesan deprecation default untuk semua aturan dalam paket ini.

default_package_metadata

Daftar label; default-nya adalah []

Menetapkan daftar default target metadata yang berlaku untuk semua target lainnya dalam paket. Ini biasanya adalah target yang terkait dengan paket OSS dan deklarasi lisensi. Lihat rules_license untuk mengetahui contohnya.

default_testonly

Boolean; defaultnya adalah False kecuali seperti yang tercantum

Menetapkan properti testonly default untuk semua aturan dalam paket ini.

Dalam paket di bagian javatests, nilai defaultnya adalah True.

features

Mencantumkan string; default-nya adalah []

Menetapkan berbagai flag yang memengaruhi semantik file BUILD ini.

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

Contoh

Deklarasi di bawah menyatakan bahwa aturan dalam paket ini hanya terlihat oleh anggota grup paket //foo:target. Setiap deklarasi visibilitas pada aturan, jika ada, akan mengganti spesifikasi ini.
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

Fungsi ini menentukan sekumpulan paket dan mengaitkan label dengan kumpulan tersebut. Label dapat direferensikan dalam atribut visibility.

Grup paket terutama digunakan untuk kontrol visibilitas. Target yang terlihat secara publik dapat dirujuk dari setiap paket dalam hierarki sumber. Target yang terlihat secara pribadi hanya dapat direferensikan dalam paketnya sendiri (bukan subpaket). Di antara ekstrem ini, target dapat mengizinkan akses ke paketnya sendiri beserta 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 ada dalam salah satu grup paket lain yang disebutkan dalam atribut includes.

Grup paket secara teknis adalah target, tetapi tidak dibuat oleh aturan, dan sendiri tidak memiliki perlindungan visibilitas.

Argumen

Atribut Deskripsi
name

Nama; wajib

Nama unik untuk target ini.

packages

Daftar string; default-nya adalah []

Daftar 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 berada di repositori yang sama dengan grup paket.
  2. Seperti di atas, tetapi dengan /... di akhir. Misalnya, //foo/... menentukan kumpulan //foo dan semua subpaketnya. //... 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 flag --incompatible_package_group_has_public_syntax untuk ditetapkan.)

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

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

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

Jika atribut ini tidak ada, hasilnya sama dengan menetapkannya ke daftar kosong, yang juga sama dengan menetapkannya 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, saat 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

Daftar label; default-nya adalah []

Grup paket lain yang disertakan dalam grup ini.

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

Jika digunakan bersama dengan spesifikasi paket yang dinegasikan, perhatikan bahwa kumpulan paket untuk setiap grup dihitung secara independen terlebih dahulu dan hasilnya kemudian digabungkan. Ini berarti bahwa spesifikasi yang dinegasikan di satu grup tidak berpengaruh pada spesifikasi di grup lain.

Contoh

Deklarasi package_group berikut menentukan grup paket yang disebut "tropis" yang berisi buah-buahan 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 milik paket ini yang diekspor ke paket lain.

File BUILD untuk paket hanya dapat merujuk langsung ke file sumber yang merupakan milik paket lain jika 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 tanda --incompatible_no_implicit_file_export dibalik. Namun, perilaku ini tidak boleh diandalkan dan dimigrasikan secara aktif.

Argumen

Argumennya adalah daftar nama file dalam paket saat ini. Pernyataan 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 baru yang dapat diubah dan diurutkan. Glob hanya menelusuri file dalam paketnya sendiri, dan hanya mencari file sumber (bukan file yang dihasilkan atau target lainnya).

Label file sumber disertakan dalam hasil jika jalur paket relatif file cocok dengan salah satu pola include dan tidak ada 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 dalam pola dicocokkan dengan segmen jalur. Segmen dapat berisi karakter pengganti *: karakter ini cocok dengan substring apa pun di segmen jalur (bahkan substring kosong), tidak termasuk 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 (kecuali jika foo/ adalah subpaket)
  • foo/*.txt cocok dengan setiap file di direktori foo/ jika file berakhir dengan .txt (kecuali jika foo/ adalah subpaket)
  • foo/a*.htm* cocok dengan setiap file di direktori foo/ yang dimulai dengan a, lalu memiliki string arbitrer (dapat kosong), lalu memiliki .htm, dan diakhiri dengan string arbitrer lain (kecuali jika foo/ adalah subpaket); seperti foo/axx.htm dan foo/a.html atau foo/axxx.html
  • foo/* cocok dengan setiap file di direktori foo/, (kecuali jika foo/ adalah subpaket); tidak cocok dengan direktori foo itu sendiri meskipun exclude_directories ditetapkan ke 0
  • foo/** cocok dengan setiap file di setiap subdirektori non-subpaket di subdirektori tingkat pertama paket foo/; jika exclude_directories ditetapkan ke 0, direktori foo itu sendiri juga cocok dengan pola; dalam hal ini, ** dianggap cocok dengan segmen jalur nol
  • **/a.txt cocok dengan file a.txt dalam direktori paket ini ditambah subdirektori non-subpaket.
  • **/bar/**/*.txt cocok dengan setiap file .txt di setiap subdirektori non-subpaket dari paket ini, jika setidaknya satu direktori di jalur yang dihasilkan disebut bar, seperti xxx/bar/yyy/zzz/a.txt atau bar/a.txt (ingat bahwa ** juga cocok dengan segmen nol) atau bar/zzz/a.txt
  • ** cocok dengan setiap file di setiap subdirektori non-subpaket paket ini
  • foo**/a.txt adalah pola yang tidak valid, karena ** harus berdiri sendiri sebagai segmen
  • foo/ adalah pola yang tidak valid, karena segmen kedua yang ditentukan setelah / adalah string kosong

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 adalah daftar kosong.

Ada beberapa batasan dan peringatan penting:

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

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

    Untuk memahami hal ini, ingat bahwa glob() menampilkan daftar jalur, sehingga menggunakan glob() dalam atribut aturan lain (misalnya, srcs = glob(["*.cc"])) memiliki efek yang sama dengan mencantumkan jalur yang cocok secara eksplisit. Misalnya, jika glob() menghasilkan ["Foo.java", "bar/Baz.java"], tetapi ada juga aturan dalam paket yang disebut "Foo.java" (yang diizinkan, meskipun Bazel memperingatkannya), maka konsumen glob() akan menggunakan aturan "Foo.java" (output-nya), bukan file "Foo.java". Lihat masalah GitHub #10395 untuk mengetahui detail selengkapnya.

  3. Glob dapat mencocokkan file di subdirektori. Selain itu, nama subdirektori dapat berisi karakter pengganti. Namun...
  4. Label tidak diizinkan untuk melintasi batas paket dan glob tidak cocok dengan file dalam subpaket.

    Misalnya, ekspresi glob **/*.cc dalam paket x tidak menyertakan x/y/z.cc jika x/y ada sebagai paket (baik sebagai x/y/BUILD, atau di tempat lain di jalur paket). Hal ini berarti bahwa hasil ekspresi glob 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. Batasan di atas berlaku untuk semua ekspresi glob, terlepas dari karakter pengganti yang digunakan.
  6. File tersembunyi dengan nama file yang diawali dengan . sepenuhnya cocok dengan karakter pengganti ** dan *. Jika Anda ingin mencocokkan file tersembunyi dengan pola gabungan, pola Anda harus diawali dengan .. Misalnya, * dan .*.txt akan cocok dengan .foo.txt, tetapi *.txt tidak akan cocok. Direktori tersembunyi juga dicocokkan dengan cara yang sama. Direktori tersembunyi dapat menyertakan file yang tidak diperlukan sebagai input, dan dapat meningkatkan jumlah file yang tidak perlu di-glob dan konsumsi memori. Untuk mengecualikan direktori tersembunyi, tambahkan direktori tersebut ke argumen daftar "exclude".
  7. Karakter pengganti "**" memiliki satu kasus ekstrem: pola "**" tidak cocok dengan jalur direktori paket. Artinya, glob(["**"], exclude_directories = 0) mencocokkan semua file dan direktori secara transitif secara ketat di bawah direktori paket saat ini (tetapi tentu saja tidak masuk ke direktori subpaket - lihat catatan sebelumnya tentang hal itu).

Secara umum, Anda harus mencoba memberikan ekstensi yang sesuai (misalnya, *.html) bukan menggunakan '*' kosong untuk pola glob. Nama yang lebih eksplisit merupakan dokumentasi mandiri dan memastikan bahwa Anda tidak sengaja mencocokkan file pencadangan, atau file simpan otomatis emacs/vi/...

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 di 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 experimental.txt. Perhatikan bahwa file dalam subdirektori testdata 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 di direktori testdata dan semua subdirektorinya (dan subdirektorinya, dan seterusnya). Subdirektori yang berisi file BUILD akan diabaikan. (Lihat batasan dan catatan di atas.)

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

Buat library yang dibuat dari semua file java di 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 berisi tiga file yang cocok, a_test.cc, b_test.cc, dan c_test.cc, maka 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 bantuan yang membuat atribut aturan dapat dikonfigurasi. Flag ini dapat menggantikan sisi kanan hampir penetapan atribut apa pun sehingga nilainya bergantung pada flag Bazel command line. Anda dapat menggunakannya, misalnya, untuk menentukan dependensi khusus platform atau untuk menyematkan resource yang berbeda, bergantung pada apakah aturan dibuat dalam mode "developer" vs. "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 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 kondisi lainnya, spesialisasi akan diutamakan. Kondisi B dianggap sebagai spesialisasi kondisi A jika B memiliki semua flag dan nilai batasan yang sama dengan A ditambah beberapa flag atau nilai batasan tambahan. Hal ini juga berarti bahwa resolusi spesialisasi tidak dirancang untuk membuat pengurutan seperti yang ditunjukkan dalam Contoh 2 di bawah.
  • Jika beberapa kondisi cocok dan salah satunya bukan spesialisasi dari semua kondisi lainnya, Bazel akan gagal dengan error, kecuali jika semua kondisi di-resolve ke nilai yang sama.
  • Label pseudo khusus //conditions:default dianggap cocok jika tidak ada kondisi lain yang cocok. Jika kondisi ini dihilangkan, 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, tetapi tidak semua, atribut. Atribut yang tidak kompatibel ditandai nonconfigurable dalam dokumentasinya.

    sub-paket

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

    subpackages() adalah fungsi bantuan, mirip dengan glob() yang mencantumkan subpaket, bukan file dan direktori. Class ini menggunakan pola jalur yang sama dengan glob() dan dapat mencocokkan subpaket apa pun yang merupakan turunan langsung dari file BUILD yang sedang dimuat. Lihat glob untuk mengetahui penjelasan mendetail dan contoh pola sertakan dan kecualikan.

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

    Contoh

    Contoh berikut mencantumkan semua subpaket langsung untuk paket foo/BUILD

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/bar/but/bad/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs1 = subpackages(include = ["**"])
    
    # results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    
    subs2 = subpackages(include = ["bar/*"])
    # results in subs2 = ["bar/baz"]
    #
    # Since 'bar' is not a subpackage itself, this looks for any subpackages under
    # all first level subdirectories of 'bar'.
    
    subs3 = subpackages(include = ["bar/**"])
    # results in subs3 = ["bar/baz", "bar/but/bad"]
    #
    # Since bar is not a subpackage itself, this looks for any subpackages which are
    # (1) under all subdirectories of 'bar' which can be at any level, (2) not a
    # subpackage of another subpackages.
    
    subs4 = subpackages(include = ["sub"])
    subs5 = subpackages(include = ["sub/*"])
    subs6 = subpackages(include = ["sub/**"])
    # results in subs4 and subs6 being ["sub"]
    # results in subs5 = [].
    #
    # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
    # subpackage of 'foo').
    # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
    # 'foo/sub' is already a subpackage itself, the subdirectories will not be
    # traversed anymore.
    # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
    # is returned. But the subdirectories of 'foo/sub' will not be traversed
    # anymore.
    

    Secara umum, sebaiknya pengguna menggunakan modul 'subpackages' dari skylib, bukan memanggil fungsi ini secara langsung.