Bu sayfa, makro kullanımıyla ilgili temel bilgileri ve genel kullanım alanlarını, hata ayıklama kurallarını ve kuralları ele almaktadır.
Makro, BUILD
dosyasından çağrılan ve kuralları örneklendirebilen bir işlevdir.
Makrolar, genellikle mevcut kuralların ve diğer makroların kapsüllenmesi ve kodların yeniden kullanılması için kullanılır. Yükleme aşamasının sonunda makrolar artık kalmaz ve Bazel yalnızca somut kurallar kümesini görür.
Kullanım
Bir makronun tipik kullanım alanı, bir kuralı yeniden kullanmak istemenizdir.
Örneğin, bir BUILD
dosyasındaki genrule, //:generator
kullanan ve komutun koduna gömülü bir some_arg
bağımsız değişkeniyle birlikte bir dosya oluşturur:
genrule(
name = "file",
outs = ["file.txt"],
cmd = "$(location //:generator) some_arg > $@",
tools = ["//:generator"],
)
Farklı bağımsız değişkenlere sahip daha fazla dosya oluşturmak istiyorsanız bu kodu bir makro işlevine ayıklamayı düşünebilirsiniz. name
ve arg
parametrelerine sahip
file_generator
makrosunu adlandıralım. Genrule ifadesini aşağıdakiyle değiştirin:
load("//path:generator.bzl", "file_generator")
file_generator(
name = "file",
arg = "some_arg",
)
file_generator(
name = "file-two",
arg = "some_arg_two",
)
file_generator(
name = "file-three",
arg = "some_arg_three",
)
Burada, //path
paketinde bulunan .bzl
dosyasından file_generator
simgesini yüklersiniz. Makro işlevi tanımlarını ayrı bir .bzl
dosyasına koyarak BUILD
dosyalarınızı temiz ve bildirim temelli tutabilirsiniz. .bzl
dosyası, çalışma alanındaki herhangi bir paketten yüklenebilir.
Son olarak, path/generator.bzl
içinde orijinal tür tanımını kapsamak ve parametreleştirmek için makronun tanımını yazın:
def file_generator(name, arg, visibility=None):
native.genrule(
name = name,
outs = [name + ".txt"],
cmd = "$(location //:generator) %s > $@" % arg,
tools = ["//:generator"],
visibility = visibility,
)
Kuralları birbirine bağlamak için makroları da kullanabilirsiniz. Bu örnekte, bir genrule türünün giriş olarak önceki bir genrule çıkışının çıkışları kullandığı zincirleme türler gösterilmektedir:
def chained_genrules(name, visibility=None):
native.genrule(
name = name + "-one",
outs = [name + ".one"],
cmd = "$(location :tool-one) $@",
tools = [":tool-one"],
visibility = ["//visibility:private"],
)
native.genrule(
name = name + "-two",
srcs = [name + ".one"],
outs = [name + ".two"],
cmd = "$(location :tool-two) $< $@",
tools = [":tool-two"],
visibility = visibility,
)
Örnek, yalnızca ikinci türe bir görünürlük değeri atar. Böylece, makro yazarları ara kuralların çıkışlarının, çalışma alanındaki diğer hedefler tarafından kullanılmalarını engelleyebilir.
Genişletilen makrolar
Bir makronun ne işe yaradığını incelemek istediğinizde query
komutunu --output=build
ile birlikte kullanarak genişletilmiş formu görebilirsiniz:
$ bazel query --output=build :file
# /absolute/path/test/ext.bzl:42:3
genrule(
name = "file",
tools = ["//:generator"],
outs = ["//test:file.txt"],
cmd = "$(location //:generator) some_arg > $@",
)
Yerel kuralları örneklendirme
Yerel kurallar (load()
ifadesi gerektirmeyen kurallar) yerel modülünden örneklenebilir:
def my_macro(name, visibility=None):
native.cc_library(
name = name,
srcs = ["main.cc"],
visibility = visibility,
)
Paket adını (örneğin, makroyu hangi BUILD
dosyasının çağırdığını) bilmeniz gerekiyorsa native.package_name() işlevini kullanın. native
öğesinin yalnızca .bzl
dosyalarında kullanılabileceğini, BUILD
dosyalarında kullanılamayacağını unutmayın.
Makrolarda etiket çözümlemesi
Makrolar yükleme aşamasında değerlendirildiğinden, bir makroda meydana gelen "//foo:bar"
gibi etiket dizeleri, tanımlandığı .bzl
dosyasına göre değil, makronun kullanıldığı BUILD
dosyasına göre yorumlanır. Bu davranış, yayınlanan bir Starlark kural kümesinin parçası olmaları gibi diğer depolarda kullanılması amaçlanan makrolar için genellikle istenmeyen bir davranıştır.
Starlark kurallarıyla aynı davranışı elde etmek için etiket dizelerini Label
oluşturucuyla sarmalayın:
# @my_ruleset//rules:defs.bzl
def my_cc_wrapper(name, deps = [], **kwargs):
native.cc_library(
name = name,
deps = deps + select({
# Due to the use of Label, this label is resolved within @my_ruleset,
# regardless of its site of use.
Label("//config:needs_foo"): [
# Due to the use of Label, this label will resolve to the correct target
# even if the canonical name of @dep_of_my_ruleset should be different
# in the main repo, such as due to repo mappings.
Label("@dep_of_my_ruleset//tools:foo"),
],
"//conditions:default": [],
}),
**kwargs,
)
Hata ayıklama
bazel query --output=build //my/path:all
, değerlendirmeden sonraBUILD
dosyasının nasıl göründüğünü gösterir. Tüm makrolar, glob'lar, döngüler genişletilir. Bilinen sınırlama:select
ifadeleri şu anda çıkışta gösterilmemektedir.Çıkışı,
generator_function
(kuralları oluşturan işlev) veyagenerator_name
(makronun ad özelliği) ölçütlerine göre filtreleyebilirsiniz:bash $ bazel query --output=build 'attr(generator_function, my_macro, //my/path:all)'
Bir
BUILD
dosyasındafoo
kuralının tam olarak nerede oluşturulduğunu öğrenmek için aşağıdaki yolu deneyebilirsiniz. Şu satırıBUILD
dosyasının üst kısmına yakın bir yere ekleyin:cc_library(name = "foo")
. Bazel'ı çalıştır.foo
kuralı oluşturulduğunda (ad çakışması nedeniyle) bir istisna alırsınız. Bu kural, tam yığın izlemeyi (stack trace) gösterir.Hata ayıklama için yazdır aracını da kullanabilirsiniz. Yükleme aşamasında mesajı
DEBUG
günlük satırı olarak gösterir. Nadir durumlar haricinde,print
çağrılarını kaldırın veya kodu depoya göndermeden önce varsayılan olarakFalse
olan birdebugging
parametresiyle koşullu hâle getirin.
Hatalar
Hata bildirmek istiyorsanız fail işlevini kullanın.
Kullanıcıya sorunun ne olduğunu ve BUILD
dosyasının nasıl düzeltileceğini açıkça açıklayın.
Hata yakalamak mümkün değildir.
def my_macro(name, deps, visibility=None):
if len(deps) < 2:
fail("Expected at least two values in deps")
# ...
Kongreler
Kuralları örnekleyen tüm ortak işlevlerin (alt çizgi ile başlamayan işlevler) bir
name
bağımsız değişkenine sahip olması gerekir. Bu bağımsız değişken isteğe bağlı olmamalıdır (varsayılan değer vermeyin).Genel işlevler, Python kurallarına uygun bir docstring kullanmalıdır.
BUILD
dosyalarında, makrolarınname
bağımsız değişkeni bir anahtar kelime bağımsız değişkeni olmalıdır (konumsal bağımsız değişken değil).Bir makro tarafından oluşturulan kuralların
name
özelliği, ad bağımsız değişkenini ön ek olarak içermelidir. Örneğinmacro(name = "foo")
,cc_library
foo
ve genrulefoo_gen
oluşturabilir.Çoğu durumda, isteğe bağlı parametrelerin varsayılan değeri
None
olmalıdır.None
, doğrudan yerel kurallara geçirilebilir. Bu kurallar, herhangi bir bağımsız değişkende iletilmemiş gibi davranır. Dolayısıyla, bu amaçla bunu0
,False
veya[]
ile değiştirmenize gerek yoktur. Bunun yerine, varsayılan değerleri karmaşık olabileceği veya zaman içinde değişebileceği için makro, oluşturduğu kurallara bağlı kalmalıdır. Ayrıca, açıkça varsayılan değerine ayarlanan bir parametre, sorgu dili veya derleme sisteminin dahili bileşenleri üzerinden erişildiğinde hiçbir zaman ayarlanmayan (veyaNone
olarak ayarlanmayan) bir parametreden farklı görünür.Makrolar, isteğe bağlı
visibility
bağımsız değişkenlerine sahip olmalıdır.