Bu sayfada, projenizin nasıl oluşturulacağını özelleştirmek için Bazel'in API'si olan Starlark yapılandırmalarının avantajları ve temel kullanımı açıklanmaktadır. Derleme ayarlarının nasıl tanımlanacağı ve örnekler yer alır.
Bu sayede:
- projeniz için özel işaretler tanımlayarak
--define
ihtiyacını ortadan kaldırın - Üst öğelerinden farklı yapılandırmalarda (ör.
--compilation_mode=opt
veya--cpu=arm
) bağımlılıkları yapılandırmak için geçişler yazma - Kurallara daha iyi varsayılan değerler ekleyin (ör. belirtilen bir SDK ile otomatik olarak
//my:android_app
oluşturma)
ve daha fazlası, tamamen .bzl dosyalarından (Bazel sürümü gerekmez). Örnekler için
bazelbuild/examples
deposuna bakın.
Kullanıcı tanımlı derleme ayarları
Derleme ayarı, tek bir yapılandırma bilgisidir. Yapılandırmayı anahtar/değer eşlemesi olarak düşünebilirsiniz. --cpu=ppc
ayarı ve --copt="-DFoo"
, {cpu: ppc, copt: "-DFoo"}
gibi görünen bir yapılandırma oluşturur. Her giriş bir derleme ayarıdır.
cpu
ve copt
gibi geleneksel işaretler yerel ayarlardır. Anahtarları tanımlanır ve değerleri yerel Bazel Java kodu içinde ayarlanır.
Bazel kullanıcıları bunları yalnızca komut satırı ve yerel olarak desteklenen diğer API'ler üzerinden okuyup yazabilir. Yerel işaretlerin ve bunları gösteren API'lerin değiştirilmesi için bazel sürümü gerekir. Kullanıcı tanımlı derleme ayarları .bzl
dosyalarında tanımlanır (bu nedenle, değişikliklerin kaydedilmesi için Bazel sürümü gerekmez). Bu geçişler komut satırı üzerinden de ayarlanabilir (flags
olarak belirlenmişse, daha fazla bilgiyi aşağıda bulabilirsiniz). Ayrıca kullanıcı tanımlı geçişler üzerinden de ayarlanabilir.
Derleme ayarlarını tanımlama
build_setting
rule()
parametresi
Derleme ayarları, diğer kurallar gibi kurallardır ve Starlark rule()
işlevinin build_setting
özelliği kullanılarak ayırt edilir.
# example/buildsettings/build_settings.bzl
string_flag = rule(
implementation = _impl,
build_setting = config.string(flag = True)
)
build_setting
özelliği, derleme ayarının türünü belirten bir işlev alır. Tür, bool
ve string
gibi bir dizi temel Starlark türüyle sınırlıdır. Ayrıntılar için config
modülü
belgelerini inceleyin. Daha karmaşık yazma işlemleri, kuralın uygulama işlevinde yapılabilir. Bu konuyla ilgili daha fazla bilgiyi aşağıda bulabilirsiniz.
config
modülünün işlevleri, varsayılan olarak false değerine ayarlanmış isteğe bağlı bir boolean parametresi olan flag
alır. flag
true olarak ayarlanırsa derleme ayarı, komut satırında kullanıcılar tarafından ve kural yazanlar tarafından varsayılan değerler ve geçişler aracılığıyla dahili olarak da ayarlanabilir.
Tüm ayarlar kullanıcılar tarafından belirlenememelidir. Örneğin, kural yazarı olarak test kurallarında etkinleştirmek istediğiniz bir hata ayıklama modunuz varsa kullanıcıların bu özelliği diğer test dışı kurallarda rastgele etkinleştirmesine izin vermek istemezsiniz.
ctx.build_setting_value kullanma
Tüm kurallar gibi, derleme ayarı kurallarının da uygulama işlevleri vardır.
Derleme ayarlarının temel Starlark türü değerine ctx.build_setting_value
yöntemiyle erişilebilir. Bu yöntem yalnızca derleme ayarı kurallarının ctx
nesneleri için kullanılabilir. Bu uygulama yöntemleri, derleme ayarları değerini doğrudan iletebilir veya üzerinde ek işlemler (ör. tür kontrolü ya da daha karmaşık yapı oluşturma) yapabilir. enum
türünde bir derleme ayarını nasıl uygulayacağınız aşağıda açıklanmıştır:
# example/buildsettings/build_settings.bzl
TemperatureProvider = provider(fields = ['type'])
temperatures = ["HOT", "LUKEWARM", "ICED"]
def _impl(ctx):
raw_temperature = ctx.build_setting_value
if raw_temperature not in temperatures:
fail(str(ctx.label) + " build setting allowed to take values {"
+ ", ".join(temperatures) + "} but was set to unallowed value "
+ raw_temperature)
return TemperatureProvider(type = raw_temperature)
temperature = rule(
implementation = _impl,
build_setting = config.string(flag = True)
)
Çoklu küme dize işaretlerini tanımlama
Dize ayarlarında, komut satırında veya bazelrc'lerde işaretin birden çok kez ayarlanmasına olanak tanıyan ek bir allow_multiple
parametresi bulunur. Varsayılan değerleri, dize türünde bir özellikle ayarlanmaya devam eder:
# example/buildsettings/build_settings.bzl
allow_multiple_flag = rule(
implementation = _impl,
build_setting = config.string(flag = True, allow_multiple = True)
)
# example/buildsettings/BUILD
load("//example/buildsettings:build_settings.bzl", "allow_multiple_flag")
allow_multiple_flag(
name = "roasts",
build_setting_default = "medium"
)
Her işaret ayarı tek bir değer olarak kabul edilir:
$ bazel build //my/target --//example:roasts=blonde \
--//example:roasts=medium,dark
Yukarıdaki ifade {"//example:roasts": ["blonde", "medium,dark"]}
olarak ayrıştırılır ve ctx.build_setting_value
, ["blonde", "medium,dark"]
listesini döndürür.
Derleme ayarlarını başlatma
build_setting
parametresiyle tanımlanan kurallar, örtülü bir zorunlu build_setting_default
özelliğine sahiptir. Bu özellik, build_setting
parametresi tarafından bildirilen türle aynı türü alır.
# example/buildsettings/build_settings.bzl
FlavorProvider = provider(fields = ['type'])
def _impl(ctx):
return FlavorProvider(type = ctx.build_setting_value)
flavor = rule(
implementation = _impl,
build_setting = config.string(flag = True)
)
# example/buildsettings/BUILD
load("//example/buildsettings:build_settings.bzl", "flavor")
flavor(
name = "favorite_flavor",
build_setting_default = "APPLE"
)
Önceden tanımlanmış ayarlar
Skylib kitaplığı, özel Starlark yazmanıza gerek kalmadan oluşturabileceğiniz bir dizi önceden tanımlanmış ayar içerir.
Örneğin, sınırlı bir dize değerleri kümesini kabul eden bir ayar tanımlamak için:
# example/BUILD
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
string_flag(
name = "myflag",
values = ["a", "b", "c"],
build_setting_default = "a",
)
Tam liste için Ortak derleme ayarı kuralları başlıklı makaleyi inceleyin.
Derleme ayarlarını kullanma
Derleme ayarlarına bağlı olarak
Bir hedef, yapılandırma bilgisini okumak istiyorsa normal bir özellik bağımlılığı aracılığıyla doğrudan derleme ayarına bağlı olabilir.
# example/rules.bzl
load("//example/buildsettings:build_settings.bzl", "FlavorProvider")
def _rule_impl(ctx):
if ctx.attr.flavor[FlavorProvider].type == "ORANGE":
...
drink_rule = rule(
implementation = _rule_impl,
attrs = {
"flavor": attr.label()
}
)
# example/BUILD
load("//example:rules.bzl", "drink_rule")
load("//example/buildsettings:build_settings.bzl", "flavor")
flavor(
name = "favorite_flavor",
build_setting_default = "APPLE"
)
drink_rule(
name = "my_drink",
flavor = ":favorite_flavor",
)
Diller, o dille ilgili tüm kuralların bağlı olduğu standart bir derleme ayarları grubu oluşturmak isteyebilir. fragments
kavramı artık Starlark yapılandırma dünyasında sabit kodlanmış bir nesne olarak bulunmasa da bu kavramı çevirmenin bir yolu, ortak örtülü özellik kümelerini kullanmaktır. Örneğin:
# kotlin/rules.bzl
_KOTLIN_CONFIG = {
"_compiler": attr.label(default = "//kotlin/config:compiler-flag"),
"_mode": attr.label(default = "//kotlin/config:mode-flag"),
...
}
...
kotlin_library = rule(
implementation = _rule_impl,
attrs = dicts.add({
"library-attr": attr.string()
}, _KOTLIN_CONFIG)
)
kotlin_binary = rule(
implementation = _binary_impl,
attrs = dicts.add({
"binary-attr": attr.label()
}, _KOTLIN_CONFIG)
Komut satırında derleme ayarlarını kullanma
Çoğu yerel işaret gibi, işaret olarak işaretlenen derleme ayarlarını belirlemek için komut satırını kullanabilirsiniz. Derleme ayarının adı, name=value
söz dizimi kullanılarak oluşturulan tam hedef yoludur:
$ bazel build //my/target --//example:string_flag=some-value # allowed
$ bazel build //my/target --//example:string_flag some-value # not allowed
Özel Boole söz dizimi desteklenir:
$ bazel build //my/target --//example:boolean_flag
$ bazel build //my/target --no//example:boolean_flag
Derleme ayarı takma adlarını kullanma
Derleme ayarı hedef yolunuz için komut satırında daha kolay okunmasını sağlamak amacıyla bir takma ad belirleyebilirsiniz. Diğer adlar, yerel işaretlere benzer şekilde çalışır ve çift tireli seçenek söz dizimini kullanır.
--flag_alias=ALIAS_NAME=TARGET_PATH
ekleyerek .bazelrc
için takma ad belirleyin . Örneğin, coffee
için takma ad ayarlamak istiyorsanız:
# .bazelrc
build --flag_alias=coffee=//experimental/user/starlark_configurations/basic_build_setting:coffee-temp
En iyi uygulama: Bir takma adın birden çok kez ayarlanması, en son ayarlanan takma adın öncelikli olmasına neden olur. İstenmeyen ayrıştırma sonuçlarını önlemek için benzersiz takma adlar kullanın.
Takma adı kullanmak için derleme ayarı hedef yolu yerine takma adı yazın.
Kullanıcının .bazelrc
ayarlarında coffee
olarak ayarlanmış yukarıdaki örnekte:
$ bazel build //my/target --coffee=ICED
yerine
$ bazel build //my/target --//experimental/user/starlark_configurations/basic_build_setting:coffee-temp=ICED
En İyi Uygulama: Komut satırında takma ad ayarlamak mümkün olsa da bunları .bazelrc
içinde bırakmak komut satırındaki karışıklığı azaltır.
Etiket türünde derleme ayarları
Diğer derleme ayarlarının aksine, etiket türündeki ayarlar build_setting
kural parametresi kullanılarak tanımlanamaz. Bunun yerine Bazel'de iki yerleşik kural vardır: label_flag
ve label_setting
. Bu kurallar, derleme ayarının ayarlandığı gerçek hedefin sağlayıcılarını yönlendirir. label_flag
ve
label_setting
geçişler tarafından okunabilir/yazılabilir ve label_flag
diğer build_setting
kuralları gibi kullanıcı tarafından ayarlanabilir. Tek farkları, özel olarak tanımlanamamalarıdır.
Etiket türündeki ayarlar, sonunda geç bağlanan varsayılanların işlevinin yerini alacak. Geç bağlanan varsayılan özellikler, son değerleri yapılandırmadan etkilenebilen Etiket türünde özelliklerdir. Bu, Starlark'ta configuration_field
API'nin yerini alacak.
# example/rules.bzl
MyProvider = provider(fields = ["my_field"])
def _dep_impl(ctx):
return MyProvider(my_field = "yeehaw")
dep_rule = rule(
implementation = _dep_impl
)
def _parent_impl(ctx):
if ctx.attr.my_field_provider[MyProvider].my_field == "cowabunga":
...
parent_rule = rule(
implementation = _parent_impl,
attrs = { "my_field_provider": attr.label() }
)
# example/BUILD
load("//example:rules.bzl", "dep_rule", "parent_rule")
dep_rule(name = "dep")
parent_rule(name = "parent", my_field_provider = ":my_field_provider")
label_flag(
name = "my_field_provider",
build_setting_default = ":dep"
)
Ayarları oluşturma ve select() işlevini kullanma
Kullanıcılar, select()
kullanarak derleme ayarlarında özellikleri yapılandırabilir. Derleme ayarı hedefleri, flag_values
özelliğine aktarılabilir.
config_setting
. Yapılandırmayla eşleştirilecek değer, String
olarak iletilir ve ardından eşleştirme için derleme ayarının türüne ayrıştırılır.
config_setting(
name = "my_config",
flag_values = {
"//example:favorite_flavor": "MANGO"
}
)
Kullanıcı tanımlı geçişler
Yapılandırma geçişi, derleme grafiğinde bir yapılandırılmış hedeften diğerine dönüşümü eşler.
Bu kuralları belirleyen kurallar özel bir özellik içermelidir:
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist"
)
Geçiş ekleyerek derleme grafiğinizin boyutunu kolayca artırabilirsiniz. Bu işlem, bu kuralın hedeflerini oluşturabileceğiniz paketlerde bir izin verilenler listesi oluşturur. Yukarıdaki kod bloğunda varsayılan değer, her şeye izin verir. Ancak kuralınızı kimlerin kullanabileceğini kısıtlamak istiyorsanız bu özelliği kendi özel izin verilenler listenize yönlendirecek şekilde ayarlayabilirsiniz. Geçişlerin derleme performansınızı nasıl etkileyebileceğini anlamak için tavsiye veya yardım almak isterseniz bazel-discuss@googlegroups.com ile iletişime geçin.
Tanımlama
Geçişler, kurallar arasındaki yapılandırma değişikliklerini tanımlar. Örneğin, "bağımlılığımı üst öğesinden farklı bir CPU için derle" gibi bir istek geçişle işlenir.
Resmi olarak geçiş, bir giriş yapılandırmasından bir veya daha fazla çıkış yapılandırmasına yönelik bir işlevdir. Çoğu geçiş 1:1'dir (ör. "giriş yapılandırmasını --cpu=ppc
ile geçersiz kıl"). 1:2'den fazla geçiş de olabilir ancak özel kısıtlamalarla birlikte gelir.
Starlark'ta geçişler, kurallara benzer şekilde tanımlanır. Tanımlayan bir transition()
işlev
ve bir uygulama işlevi vardır.
# example/transitions/transitions.bzl
def _impl(settings, attr):
_ignore = (settings, attr)
return {"//example:favorite_flavor" : "MINT"}
hot_chocolate_transition = transition(
implementation = _impl,
inputs = [],
outputs = ["//example:favorite_flavor"]
)
transition()
işlevi bir uygulama işlevi, okunacak bir dizi derleme ayarı(inputs
) ve yazılacak bir dizi derleme ayarı (outputs
) alır. Uygulama işlevinin iki parametresi vardır: settings
ve attr
. settings
, inputs
parametresinde transition()
için belirtilen tüm ayarların sözlüğüdür {String
:Object
}.
attr
, geçişin eklendiği kuralın özellik ve değer sözlüğüdür. Giden kenar geçişi olarak eklendiğinde bu özelliklerin değerleri, select() çözümlendirmesinden sonra yapılandırılır. Gelen kenar geçişi olarak eklendiğinde attr
, değerini çözmek için seçici kullanan hiçbir özellik içermez. --foo
üzerinde gelen bir kenar geçişi, bar
özelliğini okuyup ardından bar
özelliğini ayarlamak için --foo
üzerinde seçim yaparsa gelen kenar geçişinin, geçişte bar
özelliğinin yanlış değerini okuma ihtimali vardır.
Uygulama işlevi, uygulanacak yeni derleme ayarları değerlerinin sözlüğünü (veya birden fazla çıkış yapılandırması içeren geçişler söz konusu olduğunda sözlük listesini) döndürmelidir. Döndürülen sözlük anahtar kümeleri, geçiş işlevinin outputs
parametresine iletilen derleme ayarları kümesini içermelidir. Bu durum, geçiş sırasında bir derleme ayarı gerçekten değiştirilmemiş olsa bile geçerlidir. Orijinal değeri, döndürülen sözlükte açıkça iletilmelidir.
1:2'den fazla geçiş tanımlama
Giden kenar geçişi, tek bir giriş yapılandırmasını iki veya daha fazla çıkış yapılandırmasıyla eşleyebilir. Bu, çok mimarili kodu paketleyen kuralları tanımlamak için kullanışlıdır.
1:2'den fazla geçiş, geçiş uygulama işlevinde sözlük listesi döndürülerek tanımlanır.
# example/transitions/transitions.bzl
def _impl(settings, attr):
_ignore = (settings, attr)
return [
{"//example:favorite_flavor" : "LATTE"},
{"//example:favorite_flavor" : "MOCHA"},
]
coffee_transition = transition(
implementation = _impl,
inputs = [],
outputs = ["//example:favorite_flavor"]
)
Ayrıca, kural uygulama işlevinin tek tek bağımlılıkları okumak için kullanabileceği özel anahtarlar da ayarlayabilirler:
# example/transitions/transitions.bzl
def _impl(settings, attr):
_ignore = (settings, attr)
return {
"Apple deps": {"//command_line_option:cpu": "ppc"},
"Linux deps": {"//command_line_option:cpu": "x86"},
}
multi_arch_transition = transition(
implementation = _impl,
inputs = [],
outputs = ["//command_line_option:cpu"]
)
Geçiş ekleme
Geçişler iki yere eklenebilir: gelen kenarlar ve giden kenarlar. Bu, kuralların kendi yapılandırmalarını (gelen kenar geçişi) ve bağımlılıklarının yapılandırmalarını (giden kenar geçişi) geçirebileceği anlamına gelir.
NOT: Şu anda Starlark geçişlerini yerel kurallara eklemenin bir yolu yoktur. Bunu yapmanız gerekiyorsa geçici çözümler bulma konusunda yardım almak için bazel-discuss@googlegroups.com ile iletişime geçin.
Gelen kenar geçişleri
Gelen kenar geçişleri, transition
nesnesi (transition()
tarafından oluşturulur) rule()
'nin cfg
parametresine eklenerek etkinleştirilir:
# example/rules.bzl
load("example/transitions:transitions.bzl", "hot_chocolate_transition")
drink_rule = rule(
implementation = _impl,
cfg = hot_chocolate_transition,
...
Gelen kenar geçişleri 1:1 geçiş olmalıdır.
Giden kenar geçişleri
Giden kenar geçişleri, bir özelliğin cfg
parametresine transition
nesnesi (transition()
tarafından oluşturulur) eklenerek etkinleştirilir:
# example/rules.bzl
load("example/transitions:transitions.bzl", "coffee_transition")
drink_rule = rule(
implementation = _impl,
attrs = { "dep": attr.label(cfg = coffee_transition)}
...
Giden kenar geçişleri 1:1 veya 1:2+ olabilir.
Bu anahtarları nasıl okuyacağınız hakkında bilgi edinmek için Geçişlerle özelliklere erişme başlıklı makaleyi inceleyin.
Yerel seçeneklerdeki geçişler
Starlark geçişleri, seçenek adının başına özel bir önek ekleyerek yerel derleme yapılandırma seçeneklerinde okuma ve yazma işlemleri de bildirebilir.
# example/transitions/transitions.bzl
def _impl(settings, attr):
_ignore = (settings, attr)
return {"//command_line_option:cpu": "k8"}
cpu_transition = transition(
implementation = _impl,
inputs = [],
outputs = ["//command_line_option:cpu"]
Desteklenmeyen yerel seçenekler
Bazel, --define
üzerinde "//command_line_option:define"
ile geçişi desteklemez. Bunun yerine özel bir derleme ayarı kullanın. Genel olarak, derleme ayarları yerine --define
'nın yeni kullanımları önerilmez.
Bazel, --config
üzerinde geçişi desteklemez. Bunun nedeni, --config
'nın diğer flag'lere genişleyen bir "genişletme" flag'i olmasıdır.
En önemlisi, --config
, derleme yapılandırmasını etkilemeyen işaretler (ör. --spawn_strategy
) içerebilir. Bazel, tasarım gereği bu tür işaretleri tek tek hedeflere bağlayamaz. Bu nedenle, geçişlerde tutarlı bir şekilde uygulanamazlar.
Geçici çözüm olarak, geçişinizde yapılandırmanın bir parçası olan işaretleri açıkça listeleyebilirsiniz. Bu, --config
'nın iki yerde genişletilmesini gerektirir. Bu da bilinen bir kullanıcı arayüzü kusurudur.
Geçişler birden fazla derleme ayarına izin verir
Birden fazla değere izin veren derleme ayarları belirlenirken ayarın değeri bir liste ile ayarlanmalıdır.
# example/buildsettings/build_settings.bzl
string_flag = rule(
implementation = _impl,
build_setting = config.string(flag = True, allow_multiple = True)
)
# example/BUILD
load("//example/buildsettings:build_settings.bzl", "string_flag")
string_flag(name = "roasts", build_setting_default = "medium")
# example/transitions/rules.bzl
def _transition_impl(settings, attr):
# Using a value of just "dark" here will throw an error
return {"//example:roasts" : ["dark"]},
coffee_transition = transition(
implementation = _transition_impl,
inputs = [],
outputs = ["//example:roasts"]
)
İşlemsiz geçişler
Bir geçiş {}
, []
veya None
değerini döndürürse bu, tüm ayarların orijinal değerlerinde tutulması için kullanılan kısa bir yöntemdir. Bu, her çıkışı açıkça kendisine ayarlamaktan daha kolay olabilir.
# example/transitions/transitions.bzl
def _impl(settings, attr):
_ignore = (attr)
if settings["//example:already_chosen"] is True:
return {}
return {
"//example:favorite_flavor": "dark chocolate",
"//example:include_marshmallows": "yes",
"//example:desired_temperature": "38C",
}
hot_chocolate_transition = transition(
implementation = _impl,
inputs = ["//example:already_chosen"],
outputs = [
"//example:favorite_flavor",
"//example:include_marshmallows",
"//example:desired_temperature",
]
)
Geçişlerle özelliklere erişme
Giden bir kenara geçiş eklenirken (geçişin 1:1 veya 1:2+ geçişi olup olmadığına bakılmaksızın) ctx.attr
, zaten bir liste değilse liste olmaya zorlanır. Bu listedeki öğelerin sırası belirtilmemiş.
# example/transitions/rules.bzl
def _transition_impl(settings, attr):
return {"//example:favorite_flavor" : "LATTE"},
coffee_transition = transition(
implementation = _transition_impl,
inputs = [],
outputs = ["//example:favorite_flavor"]
)
def _rule_impl(ctx):
# Note: List access even though "dep" is not declared as list
transitioned_dep = ctx.attr.dep[0]
# Note: Access doesn't change, other_deps was already a list
for other dep in ctx.attr.other_deps:
# ...
coffee_rule = rule(
implementation = _rule_impl,
attrs = {
"dep": attr.label(cfg = coffee_transition)
"other_deps": attr.label_list(cfg = coffee_transition)
})
Geçiş 1:2+
ise ve özel anahtarlar ayarlıyorsa her anahtar için bağımsız bağımlılıkları okumak üzere ctx.split_attr
kullanılabilir:
# example/transitions/rules.bzl
def _impl(settings, attr):
_ignore = (settings, attr)
return {
"Apple deps": {"//command_line_option:cpu": "ppc"},
"Linux deps": {"//command_line_option:cpu": "x86"},
}
multi_arch_transition = transition(
implementation = _impl,
inputs = [],
outputs = ["//command_line_option:cpu"]
)
def _rule_impl(ctx):
apple_dep = ctx.split_attr.dep["Apple deps"]
linux_dep = ctx.split_attr.dep["Linux deps"]
# ctx.attr has a list of all deps for all keys. Order is not guaranteed.
all_deps = ctx.attr.dep
multi_arch_rule = rule(
implementation = _rule_impl,
attrs = {
"dep": attr.label(cfg = multi_arch_transition)
})
Tam örneği burada görebilirsiniz.
Platformlar ve araç zincirleriyle entegrasyon
Günümüzde --cpu
ve --crosstool_top
gibi birçok yerel işaret, araç zinciri çözümüyle ilgilidir. Gelecekte, bu tür işaretlerdeki açık geçişlerin yerini hedef platformda geçiş alma olasılığı yüksektir.
Bellek ve performansla ilgili dikkat edilmesi gereken noktalar
Derlemenize geçişler ve dolayısıyla yeni yapılandırmalar eklemek; daha büyük derleme grafikleri, daha az anlaşılır derleme grafikleri ve daha yavaş derlemeler gibi maliyetlere yol açar. Derleme kurallarınızda geçişleri kullanmayı düşünürken bu maliyetleri göz önünde bulundurmanız gerekir. Aşağıda, bir geçişin derleme grafiğinizde nasıl katlanarak büyüme oluşturabileceğine dair bir örnek verilmiştir.
Kötü davranışlı derlemeler: bir örnek olay
1.şekil En üst düzey hedefi ve bağımlılıklarını gösteren ölçeklenebilirlik grafiği.
Bu grafikte, //pkg:1_0 ve //pkg:1_1 olmak üzere iki hedefe bağlı olan //pkg:app üst düzey hedefi gösterilmektedir. Bu hedeflerin her ikisi de //pkg:2_0 ve //pkg:2_1 olmak üzere iki hedefe bağlıdır. Bu hedeflerin her ikisi de //pkg:3_0 ve //pkg:3_1 olmak üzere iki hedefe bağlıdır. Bu işlem, her ikisi de tek bir hedefe bağlı olan //pkg:n_0 ve //pkg:n_1'e kadar devam eder: //pkg:dep.
//pkg:app
oluşturmak için \(2n+2\) hedefler gerekir:
//pkg:app
//pkg:dep
- \([1..n]\)konumundaki \(i\) için
//pkg:i_0
ve//pkg:i_1
Bir işaret uyguladığınızı (--//foo:owner=<STRING>
) ve //pkg:i_b
'ün geçerli olduğunu düşünün.
depConfig = myConfig + depConfig.owner="$(myConfig.owner)$(b)"
Diğer bir deyişle, //pkg:i_b
, tüm bağımlılıkları için --owner
'nin eski değerine b
ekler.
Bu işlem, aşağıdaki yapılandırılmış hedefleri oluşturur:
//pkg:app //foo:owner=""
//pkg:1_0 //foo:owner=""
//pkg:1_1 //foo:owner=""
//pkg:2_0 (via //pkg:1_0) //foo:owner="0"
//pkg:2_0 (via //pkg:1_1) //foo:owner="1"
//pkg:2_1 (via //pkg:1_0) //foo:owner="0"
//pkg:2_1 (via //pkg:1_1) //foo:owner="1"
//pkg:3_0 (via //pkg:1_0 → //pkg:2_0) //foo:owner="00"
//pkg:3_0 (via //pkg:1_0 → //pkg:2_1) //foo:owner="01"
//pkg:3_0 (via //pkg:1_1 → //pkg:2_0) //foo:owner="10"
//pkg:3_0 (via //pkg:1_1 → //pkg:2_1) //foo:owner="11"
...
//pkg:dep
, \(2^n\) yapılandırılmış hedef oluşturur: config.owner=
\(\{0,1\}\)içindeki tüm \(b_i\) için "\(b_0b_1...b_n\)".
Bu durum, derleme grafiğini hedef grafikten katlanarak daha büyük hale getirir ve buna bağlı olarak bellek ve performansla ilgili sonuçlar ortaya çıkar.
YAPILACAKLAR: Bu sorunların ölçülmesi ve azaltılmasına yönelik stratejiler ekleyin.
Daha fazla bilgi
Derleme yapılandırmalarını değiştirme hakkında daha fazla bilgi için aşağıdaki makaleleri inceleyin:
- Starlark Derleme Yapılandırması
- Bazel Yapılandırılabilirliği Yol Haritası
- Uçtan uca örneklerin tam seti