Bu sayfada, makroların kullanımıyla ilgili temel bilgiler, tipik kullanım alanları, hata ayıklama ve kurallar ele alınmaktadır.
Makro, BUILD
dosyasından çağrılan ve kuralları örnekleyebilen bir işlevdir.
Makrolar, temel olarak mevcut kuralların ve diğer makroların sarmalanması ve kodlarının yeniden kullanılması için kullanılır.
Makrolar iki şekilde sunulur: Bu sayfada açıklanan sembolik makrolar ve eski makrolar. Mümkün olduğunda kod netliği için sembolik makrolar kullanmanızı öneririz.
Sembolik makrolar, yazılmış bağımsız değişkenler (makronun çağrıldığı yere göre dize etiketi dönüşümü) ve oluşturulan hedeflerin görünürlüğünü kısıtlama ve belirtme olanağı sunar. Bunlar, tembel değerlendirmeye uygun olacak şekilde tasarlanmıştır (gelecekteki bir Bazel sürümünde eklenecektir). Sembolik makrolar, Bazel 8'de varsayılan olarak kullanılabilir. Bu belgede macros
ifadesi, sembolik makrolar anlamına gelir.
Kullanım
Makrolar, macro()
işlevi iki parametreyle (attrs
ve implementation
) çağrılarak .bzl
dosyalarında tanımlanır.
Özellikler
attrs
, makronun bağımsız değişkenlerini temsil eden özellik adı ile özellik türleri arasındaki bir sözlük kabul eder. İki ortak özellik (ad ve görünürlük), tüm makrolara dolaylı olarak eklenir ve katılımcılara iletilen sözlüğe dahil edilmez.
# macro/macro.bzl
my_macro = macro(
attrs = {
"deps": attr.label_list(mandatory = True, doc = "The dependencies passed to the inner cc_binary and cc_test targets"),
"create_test": attr.bool(default = False, configurable = False, doc = "If true, creates a test target"),
},
implementation = _my_macro_impl,
)
Özellik türü bildirimleri mandatory
, default
ve doc
parametrelerini kabul eder. Çoğu özellik türü, özelliğin select
kabul edip etmediğini belirleyen configurable
parametresini de kabul eder. Bir özellik configurable
ise select
olmayan değerler, yapılandırılabilir olmayan bir select
olarak ayrıştırılır. "foo"
, select({"//conditions:default": "foo"})
olur. Daha fazla bilgiyi seçimler bölümünde bulabilirsiniz.
Uygulama
implementation
, makronun mantığını içeren bir işlevi kabul eder.
Uygulama işlevleri genellikle bir veya daha fazla kuralı çağırarak hedef oluşturur ve genellikle özeldir (başında alt çizgiyle adlandırılır). Geleneksel olarak, makrolarıyla aynı ada sahiptirler ancak önlerine _
, sonlarına ise _impl
eklenir.
Özelliklere başvuru içeren tek bir bağımsız değişken (ctx
) alan kural uygulama işlevlerinin aksine, makro uygulama işlevleri her bağımsız değişken için bir parametreyi kabul eder.
# macro/macro.bzl
def _my_macro_impl(name, deps, create_test):
cc_library(
name = name + "_cc_lib",
deps = deps,
)
if create_test:
cc_test(
name = name + "_test",
srcs = ["my_test.cc"],
deps = deps,
)
Bildirim
Makrolar, tanımları bir BUILD
dosyasına yükleyerek ve çağırarak bildirilir.
# pkg/BUILD
my_macro(
name = "macro_instance",
deps = ["src.cc"] + select(
{
"//config_setting:special": ["special_source.cc"],
"//conditions:default": [],
},
),
create_tests = True,
)
Bu işlem, //pkg:macro_instance_cc_lib
ve//pkg:macro_instance_test
hedeflerini oluşturur.
Ayrıntılar
Oluşturulan hedefler için adlandırma kuralları
Sembolik bir makro tarafından oluşturulan hedeflerin veya alt makroların adları, makronun name
parametresiyle eşleşmeli ya da name
ile başlamalı ve ardından _
(tercih edilen), .
veya -
gelmelidir. Örneğin, my_macro(name = "foo")
yalnızca foo
adlı veya foo_
, foo-
ya da foo.
ön ekiyle başlayan dosyalar veya hedefler (ör. foo_bar
) oluşturabilir.
Makro adlandırma kuralını ihlal eden hedefler veya dosyalar tanımlanabilir ancak derlenemez ve bağımlılık olarak kullanılamaz.
Makro örneğiyle aynı paketteki makro dışı dosya ve hedeflerin adları, olası makro hedef adlarıyla çakışmamalıdır ancak bu münhasırlık zorunlu kılınmaz. Sembolik makrolar için performans iyileştirmesi olarak tembel değerlendirme özelliğini uygulama sürecindeyiz. Bu özellik, adlandırma şemasını ihlal eden paketlerde bozulacaktır.
kısıtlamalar
Sembolik makrolar, eski makrolara kıyasla bazı ek kısıtlamalara sahiptir.
Sembolik makrolar
- bir
name
bağımsız değişkeni ve birvisibility
bağımsız değişkeni almalıdır implementation
işlevi olmalıdır- değer döndürmeyebilir
args
- özel
finalizer
makroları değilsenative.existing_rules()
işlevini çağıramazlar native.package()
araması yapılamazglob()
'yi arayamaznative.environment_group()
'yi arayamaz- Adları adlandırma şemasına uygun olan hedefler oluşturmalıdır.
- Tanımlanmamış veya bağımsız değişken olarak iletilmemiş giriş dosyalarına referans veremez (daha fazla bilgi için görünürlük bölümüne bakın).
Görünürlük
TODO: Bu bölümü genişletin
Hedef görünürlük
Varsayılan olarak, sembolik makrolar tarafından oluşturulan hedefler oluşturuldukları paket tarafından görülebilir. Ayrıca, bu görünürlüğü makroyu çağıran kullanıcıya (visibility
özelliğini doğrudan makro çağrısından oluşturulan hedefe ileterek) ve diğer paketlere (hedefin görünürlüğünde açıkça belirterek) genişletebilecek bir visibility
özelliği de kabul ederler.
Bağımlılık görünürlüğü
Makrolar, ifade ettikleri dosyaları ve hedefleri kolayca görebilmelidir. Bunu aşağıdaki yöntemlerden biriyle yapabilir:
- Açıkça makroya
attr
değeri olarak aktarıldı
# pkg/BUILD
my_macro(... deps = ["//other_package:my_tool"] )
attr
değerinin dolaylı varsayılan değeri
# my_macro:macro.bzl
my_macro = macro(
attrs = {"deps" : attr.label_list(default = ["//other_package:my_tool"])} )
- Makro tanımında zaten görünür
# other_package/BUILD
cc_binary(
name = "my_tool",
visibility = "//my_macro:\\__pkg__",
)
Seçimler
Özellik configurable
ise makro uygulama işlevi özellik değerini her zaman select
değerli olarak görür. Örneğin, aşağıdaki makroyu inceleyin:
my_macro = macro(
attrs = {"deps": attr.label_list()}, # configurable unless specified otherwise
implementation = _my_macro_impl,
)
my_macro
, deps = ["//a"]
ile çağrılırsa _my_macro_impl
, deps
parametresi select({"//conditions:default":
["//a"]})
olarak ayarlanmış şekilde çağrılır.
Kural hedefleri bu dönüşümü tersine çevirir ve önemsiz select
'leri koşulsuz değerleri olarak depolar. Bu örnekte, _my_macro_impl
bir kural hedefi my_rule(..., deps = deps)
tanımlarsa bu kural hedefinin deps
değeri ["//a"]
olarak depolanır.
Sonlandırıcılar
Kural sonlandırıcı, özel bir sembolik makrodur. BUILD dosyasındaki sözlük konumu ne olursa olsun, sonlandırıcı olmayan tüm hedefler tanımlandıktan sonra paket yüklemenin son aşamasında değerlendirilir. Sıradan sembolik makrolardan farklı olarak, sonlandırıcı native.existing_rules()
öğesini çağırabilir. Burada, eski makrolardan biraz farklı davranır: Yalnızca nihai olmayan kural hedefleri grubunu döndürür. Sonlandırıcı, bu kümenin durumu hakkında iddiada bulunabilir veya yeni hedefler tanımlayabilir.
Bir sonlandırıcıyı beyan etmek için finalizer = True
ile macro()
'ü çağırın:
def _my_finalizer_impl(name, visibility, tags_filter):
for r in native.existing_rules().values():
for tag in r.get("tags", []):
if tag in tags_filter:
my_test(
name = name + "_" + r["name"] + "_finalizer_test",
deps = [r["name"]],
data = r["srcs"],
...
)
continue
my_finalizer = macro(
attrs = {"tags_filter": attr.string_list(configurable = False)},
implementation = _impl,
finalizer = True,
)
Tembellik
ÖNEMLİ: Tembel makro genişletmeyi ve değerlendirmeyi uygulama sürecindeyiz. Bu özellik henüz kullanıma sunulmadı.
Şu anda tüm makrolar, BUILD dosyası yüklendikten hemen sonra değerlendirilir. Bu durum, maliyetli ve alakasız makroların da bulunduğu paketlerdeki hedeflerin performansını olumsuz yönde etkileyebilir. Gelecekte, nihaileştirici olmayan sembolik makrolar yalnızca derleme için gerekliyse değerlendirilecektir. Önek adlandırma şeması, istenen bir hedef verildiğinde Basel'in hangi makronun genişletileceğini belirlemesine yardımcı olur.
Taşımayla ilgili sorunları giderme
Taşımayla ilgili bazı yaygın sorunlar ve bunların nasıl düzeltileceği aşağıda açıklanmıştır.
- Eski makro çağrıları
glob()
glob()
çağrısını BUILD dosyanıza (veya BUILD dosyasından çağrılan eski bir makroya) taşıyın ve glob()
değerini bir etiket listesi özelliği kullanarak sembolik makroya iletin:
# BUILD file
my_macro(
...,
deps = glob(...),
)
- Eski makroda, geçerli bir starlark
attr
türü olmayan bir parametre var.
İç içe yerleştirilmiş sembolik bir makroya mümkün olduğunca fazla mantık çekin ancak üst düzey makroyu eski bir makroda tutun.
- Eski makro, adlandırma şemasını ihlal eden bir hedef oluşturan bir kural çağırıyor
Sorun değil, "rahatsız edici" hedefe güvenmeyin. Adlandırma denetimi sessizce yoksayılır.