Bu sayfada, makroların kullanımıyla ilgili temel bilgiler ve tipik kullanım örnekleri, öğreneceğiz.
Makro, BUILD
dosyasından çağrılan ve kuralları örneklendirebilen bir işlevdir.
Makrolar genellikle mevcut kuralları kapsüllemek ve kodu yeniden kullanmak için kullanılır
ve diğer makrolar için geçerlidir.
yükleme aşamasında, makrolar artık mevcut değilse
ve Bazel yalnızca örneklendirilmiş kuralların somut kümesini görür.
Kullanım
Bir makronun tipik kullanım alanı, kuralı yeniden kullanmak istediğiniz durumlardır.
Örneğin, bir BUILD
dosyasındaki genrule,
Komuta sabit kodlu bir some_arg
bağımsız değişkeniyle //:generator
:
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
çıkarın. file_generator
makrosuna
name
ve arg
parametrelerine sahip. Genrule'ı şununla 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, aynı konumda bulunan bir .bzl
dosyasından file_generator
simgesini yüklersiniz
(//path
paketinde) Makro işlev tanımlarını ayrı bir
.bzl
dosyası, BUILD
dosyanızı temiz ve bildirim amaçlı tutarsınız, .bzl
dosyası, çalışma alanındaki herhangi bir paketten yüklenebilir.
Son olarak, path/generator.bzl
dilinde, makronun tanımını
orijinal genrule tanımını kapsülleyin ve parametreleştirin:
def file_generator(name, arg, visibility=None):
native.genrule(
name = name,
outs = [name + ".txt"],
cmd = "$(location //:generator) %s > $@" % arg,
tools = ["//:generator"],
visibility = visibility,
)
Makroları, kuralları birbirine bağlamak için de kullanabilirsiniz. Bu örnekte zincir mağaza genrules, bu örnekte bir genrule önceki bir genrule'ın çıkışlarını giriş olarak kullanır:
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 nesile bir görünürlük değeri atar. Bu da makro yazarlarının, ara kuralların çıktılarını bu çıktılara bağımlı kalmalarını önler diğer hedefler tarafından kontrol edilir.
Genişletme makroları
Bir makronun ne yaptığını incelemek istediğinizde query
komutunu
Genişletilmiş formu görmek için --output=build
:
$ 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)
native modülünden örnekler:
def my_macro(name, visibility=None):
native.cc_library(
name = name,
srcs = ["main.cc"],
visibility = visibility,
)
Paket adını bilmeniz gerekiyorsa (örneğin, BUILD
makrosuyla birlikte) native.package_name() işlevini kullanın.
native
öğesinin yalnızca .bzl
dosyalarında kullanılabildiğini, BUILD
dosyalarında kullanılamayacağını unutmayın.
Makrolarda etiket çözünürlüğü
Makrolar yükleme aşamasında değerlendirildiğinden
bir makroda yer alan "//foo:bar"
gibi etiket dizeleri yorumlanır
ile göreli olarak değil, makronun kullanıldığı BUILD
dosyasına göre
içinde tanımlandığı .bzl
dosyası. Bu, genellikle istenmeyen bir davranış
diğer depolarda kullanılması amaçlanan makrolara yönelik (ör.
yayınlanmış bir Starlark kural setinin parçasıdır.
Starlark kurallarıyla aynı davranışı elde etmek için etiket dizelerini
Label
oluşturucu:
# @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
,BUILD
dosyasının nasıl yapılacağını gösterecek. değerlendirmeden geçer. Tüm makrolar, glob'lar, döngüler genişletilir. Bilinen sınırlama:select
ifadeleri şu anda çıkışta gösterilmiyor.Çıkışı,
generator_function
işlevine göre filtreleyebilirsiniz. tarafından oluşturulmuşsa) veyagenerator_name
(makronun ad özelliği):bash $ bazel query --output=build 'attr(generator_function, my_macro, //my/path:all)'
foo
kuralınınBUILD
dosyasında tam olarak nerede oluşturulduğunu öğrenmek için aşağıdaki numarayı deneyebilirsiniz. Bu satırıBUILD
öğesinin üst kısmına yakın bir yere ekleyin dosya:cc_library(name = "foo")
. Bazel'i çalıştırın. Aşağıdaki durumlarda istisna yapılır:foo
kuralı oluşturulur (ad çakışması nedeniyle). Bu kural, size tam yığın izleme (stack trace) hakkında bilgi edinin.Hata ayıklama için yazdırma yöntemini de kullanabilirsiniz. Gösterilen bu mesajı, yükleme aşamasında
DEBUG
günlük satırı olarak kaydedebilirsiniz. Nadir olanlar hariç yaprint
çağrıları kaldırın ya da birdebugging
parametresi için kodu göndermeden önce varsayılan olarakFalse
sağlar.
Hatalar
Hata vermek istiyorsanız fail işlevini kullanın.
Kullanıcıya sorunun ne olduğunu ve BUILD
dosyasının nasıl düzeltileceğini net bir şekilde açıklayın.
Hata yakalanamaz.
def my_macro(name, deps, visibility=None):
if len(deps) < 2:
fail("Expected at least two values in deps")
# ...
Kongreler
Tüm herkese açık işlevler (alt çizgiyle başlamayan işlevler) örneklendirme kurallarının bir
name
bağımsız değişkeni olmalıdır. Bu bağımsız değişken isteğe bağlı (varsayılan değer vermeyin).Herkese açık işlevler, Python'dan sonra bir docstring kullanmalıdır inceleyin.
BUILD
dosyalarında, makrolarınname
bağımsız değişkeni bir anahtar kelime olmalıdır bağımsız değişkenine (konumsal bağımsız değişken değil) girin.Bir makro tarafından oluşturulan kuralların
name
özelliği, bağımsız değişkenini önek olarak ayarlar. Örneğin,macro(name = "foo")
şunları oluşturabilir:cc_library
foo
ve bir genelfoo_gen
.Çoğu durumda, isteğe bağlı parametreler için varsayılan değer
None
olmalıdır.None
doğrudan yerel kurallara iletilebilir. Bu kurallar, yerel kurallara tartışmayı geçemediniz. Dolayısıyla, bu e-posta adresinin Bu amaçla0
,False
veya[]
ile kullanın. Bunun yerine makro, varsayılanları karmaşık olabileceğinden veya zaman içinde değişebileceğinden, gerekir. Ayrıca, varsayılan değerine açık bir şekilde ayarlanmış bir parametre erişildiğinde hiçbir zaman ayarlanmayan (veyaNone
olarak ayarlanmış) olandan farklı görünüyor test dili veya derleme sistemi dahili ayarlarını kullanabilirsiniz.Makroların isteğe bağlı bir
visibility
bağımsız değişkeni olmalıdır.