Yapılandırmalar

Sorun bildir Kaynağı göster Nightly · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bu sayfada Starlark yapılandırmalarının avantajları ve temel kullanımı, Projenizin derleme şeklini özelleştirmek için Bazel API'si. Projenin vizyonu ve hedefleri ve örnekler sunduk.

Bu sayede:

  • Projeniz için özel işaretler tanımlayabilirsiniz. Böylece --define
  • Bağımlılıkları, üst öğelerinden farklı yapılandırmalarda (--compilation_mode=opt veya --cpu=arm gibi) yapılandırmak için geçişler yazma
  • daha iyi varsayılanlar oluşturma (ör. //my:android_app belirtilen bir SDK ile)

ve daha fazlası, tamamen .bzl dosyalarından alınır (Bzel sürümü gerekmez). Bkz. Şunun için bazelbuild/examples deposu örnekler.

Kullanıcı tanımlı derleme ayarları

Derleme ayarı, tek bir yapılandırma bilgisidir. Yapılandırmayı bir anahtar/değer eşlemesi olarak düşünebilirsiniz. --cpu=ppc ayarlanıyor --copt="-DFoo" ise şöyle bir yapılandırma üretir: {cpu: ppc, copt: "-DFoo"}. 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 kodunda ayarlanır. Bazel kullanıcıları, bunları yalnızca komut satırından okuyup yazabilir ve diğer API'ler yerel olarak korunur. Yerel işaretleri ve bunları gösteren API'leri değiştirmek için bazel sürümü gerekir. Kullanıcı tanımlı derleme ayarları .bzl dosyalarında tanımlanır (bu nedenle, (değişiklikleri kaydedin). Bu değerler komut satırı üzerinden de ayarlanabilir (flags olarak belirlenmişse daha fazla bilgi için aşağıya bakın). Ayrıca kullanıcı tanımlı geçişler aracılığıyla da ayarlanabilir.

Derleme ayarlarını tanımlama

Uçtan uca örnek

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. Ayrıntılar için config modülü dokümanlarına bakın. Kuralın uygulama işlevinde daha karmaşık yazım işlemleri yapılabilir. Bu konu hakkında daha fazla bilgiyi aşağıda bulabilirsiniz.

config modülünün işlevleri isteğe bağlı şu boole parametresini alır: flag Bu değer varsayılan olarak yanlış değerine ayarlanır. flag doğru değerine ayarlanırsa derleme ayarı kullanıcılar tarafından komut satırından aynı zamanda kural yazarları tarafından dahili olarak ayarlanabilir varsayılan değerler ve geçişler aracılığıyla yükleyebilirsiniz. Tüm ayarlar kullanıcılar tarafından değiştirilemez. Örneğin, kural yazarı olarak test kurallarında etkinleştirmek istediğiniz bir hata ayıklama modunuz varsa kullanıcılara bu özelliği test dışı diğer kurallarda da etkinleştirme olanağı vermek istemezsiniz.

ctx.build_setting_value kullanılması

Tüm kurallar gibi derleme ayarı kuralları da uygulama işlevlerine sahiptir. Derleme ayarlarının temel Starlark türü değerine şuradan erişilebilir: ctx.build_setting_value yöntemini çağırın. Bu yöntem yalnızca derleme ayarı kurallarının ctx nesneleri tarafından kullanılabilir. Bu uygulama yöntemleri, derleme ayarlarının değerini doğrudan yönlendirebilir veya gibi araçları daha kolay şekilde yapılandırabilirsiniz. Bunu şu şekilde yapabilirsiniz: enum türü bir derleme ayarı uygulayın:

# 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)
)

Çok kümeli dize işaretlerini tanımlama

Dize ayarlarında ek bir allow_multiple parametresi bulunur. Bu parametre, işaretinin komut satırında veya bazelrc'lerde birden çok kez ayarlanmasını gerektirir. Varsayılan değerleri, dize türüne sahip bir özellikle ayarlanır:

# example/buildsettings/build_settings.bzl
allow_multiple_flag = rule(
    implementation = _impl,
    build_setting = config.string(flag = True, allow_multiple = True)
)
# example/BUILD
load("//example/buildsettings:build_settings.bzl", "allow_multiple_flag")
allow_multiple_flag(
    name = "roasts",
    build_setting_default = "medium"
)

İşaretin her ayarı tek bir değer olarak ele alınır:

$ bazel build //my/target --//example:roasts=blonde \
    --//example:roasts=medium,dark

Yukarıdaki değer {"//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ı örneklendirme

build_setting parametresiyle tanımlanan kurallarda örtülü bir zorunluluk vardır build_setting_default özelliği için de geçerlidir. Bu özellik şununla aynı türü alır: build_setting parametresiyle tanımlanı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/BUILD
load("//example/buildsettings:build_settings.bzl", "flavor")
flavor(
    name = "favorite_flavor",
    build_setting_default = "APPLE"
)

Önceden tanımlanmış ayarlar

Uçtan uca örneği

İlgili içeriği oluşturmak için kullanılan Skylib kitaplıktaki bir grup önceden tanımlı bir ayar içerir. Bu ayarlar, bir yıldız gibi tasarladık.

Örneğin, sınırlı bir dize değerleri grubunu 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 bkz. Ortak derleme ayarı kuralları.

Derleme ayarlarını kullanma

Derleme ayarlarına bağlı olarak

Bir hedef, bir yapılandırma bilgisini okumak isterse kullanımı, normal bir özellik bağımlılığı aracılığıyla doğrudan derleme ayarına bağlıdır.

# 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, tüm kuralların geçerli olduğu standart bir derleme ayarları kümesi oluşturmak isteyebilir. bu dile göre değişir. Ancak fragments yerel kavramı artık kullanılmıyor Starlark yapılandırma dünyasında sabit kodlu bir nesne olarak bulunur. ortak örtülü öznitelik kümeleri kullanmak anlamına gelir. Ö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şarete benzer şekilde, işaret olarak işaretlenmiş derleme ayarlarını ayarlamak için komut satırını kullanabilirsiniz. Derleme ayarın adı, name=value söz dizimini kullanan 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

Komut satırında daha kolay okunması için derleme ayarı hedef yolunuz için bir takma ad belirleyebilirsiniz. Takma adlar, yerel işaretlere benzer şekilde çalışır ve çift kısa çizgili seçenek söz dizimini de kullanır.

--flag_alias=ALIAS_NAME=TARGET_PATH ekleyerek bir takma ad belirleyin .bazelrc cihazınıza . Örneğin, coffee olarak bir takma ad ayarlamak için:

# .bazelrc
build --flag_alias=coffee=//experimental/user/starlark_configurations/basic_build_setting:coffee-temp

En iyi uygulama: Bir takma adı birden çok kez ayarlamak, en son takma adın öncelik kazanması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 bu adı yazın. Kullanıcının .bazelrc ayarlarında yukarıdaki coffee örneğini kullanarak:

$ bazel build //my/target --coffee=ICED

yerine

$ bazel build //my/target --//experimental/user/starlark_configurations/basic_build_setting:coffee-temp=ICED

En iyi uygulama: Komut satırında takma ad ayarlamak mümkün olsa da bunları .bazelrc içinde bırakmak komut satırındaki dağınıklığı azaltır.

Etiketle yazılmış derleme ayarları

Uçtan uca örneği

Diğer derleme ayarlarından farklı olarak, etiket türünde ayarlar build_setting kural parametresi. Bunun yerine, bazel'in 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. Aralarındaki tek fark, şekilde tanımlanamaz.

Etiketle yazılmış ayarlar, nihayetinde geç sınırlanan işlevlerin yerini alacaktır. varsayılan olarak ayarlanır. Geç bağlanan varsayılan özellikler, nihai değerleri yapılandırmadan etkilenebilen etiket türündeki özelliklerdir. Starlark'ta bu, configuration_field API'ye gidin.

# 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"
)

Derleme ayarları ve select()

Uçtan uca örneği

Kullanıcılar, aşağıdakileri kullanarak derleme ayarlarındaki özellikleri yapılandırabilir: select(). Derleme ayarı hedefleri, config_setting öğesinin flag_values özelliğine iletilebilir. Yapılandırmayla eşleştirilecek değer String daha sonra eşleştirme için derleme ayarının türüne göre 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ş bir yapılandırılmış hedeften diğerine dönüşümü eşler. anlamına gelir.

Bu değerleri ayarlayan kurallar özel bir özellik içermelidir:

  "_allowlist_function_transition": attr.label(
      default = "@bazel_tools//tools/allowlists/function_transition_allowlist"
  )

Geçişler ekleyerek derleme grafiğinizin boyutunu oldukça kolay bir şekilde artırabilirsiniz. Bu işlem, istediğiniz pakette bir izin verilenler listesi bu kuralın hedeflerini oluştur. Yukarıdaki kod bloğundaki varsayılan değer her şeyi izin verilenler listesine ekler. Ancak kuralınızı kimlerin kullanabileceğini kısıtlamak istiyorsanız bu özelliği kendi özel izin verilenler listenizi işaret edecek şekilde ayarlayabilirsiniz. Tavsiye veya yardım almak isterseniz bazel-survey@googlegroups.com adresine e-posta gönderebilirsiniz. nasıl etkileyebileceğini daha iyi kavrayacaksınız.

Tanımlama

Geçişler, kurallar arasındaki yapılandırma değişikliklerini tanımlar. Örneğin, "Bağımlılıklarımı üst öğesinden farklı bir CPU için derle" gibi bir istek, bir geçiş tarafından ele alınır.

Resmî olarak geçiş, bir giriş yapılandırmasından bir veya daha fazla çıkış yapılandırmalarını kullanın. Çoğu geçiş 1:1'dir (ör. "--cpu=ppc ile giriş yapılandırmasını geçersiz kıl"). 1:2 veya daha fazla geçiş de olabilir ancak bunlar özel kısıtlamalara tabidir.

Starlark'ta geçişler kurallara çok benzer şekilde tanımlanır ve transition() işlev ve uygulama işlevi.

# 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, bir dizi okunacak derleme ayarları(inputs) ve yazılacak bir dizi derleme ayarı (outputs). Uygulama fonksiyonunun iki parametresi vardır: settings ve attr. settings, inputs parametresinde transition() için tanımlanan tüm ayarların {String:Object} bir sözlüğüdür.

attr, geçişin eklendiği kuralın özelliklerini ve değerlerini içeren bir sözlüktür. Bir yolculuğunun ucu geçişi gibi bir sürüm kullanıyorsanız özelliklerinin tümü yapılandırılmış post-select() çözünürlüğüdür. Şu şekilde eklendiğinde: gelen uç geçişi durumunda, attr değerini çözümlemek için seçici kullanan tüm özellikleri ekleyin. Bir --foo cihazda gelen uç geçişi bar özelliğini okuyor ve ardından bar özelliğini ayarlamak için --foo tarihinde seçer, geçişte yanlış bar değerini okumak için gelen uç geçişini kullanın.

Uygulama işlevi, uygulanacak yeni derleme ayarları değerlerinin bir sözlüğünü (veya birden fazla çıkış yapılandırması içeren geçişler söz konusu olduğunda sözlük listesi) döndürmelidir. Döndürülen sözlük anahtar kümeleri, outputs öğesine aktarılan derleme ayarları grubunu tam olarak içermelidir parametresinin değeri. Derleme ayarı gerçekten değişmemiş olana işarettir. Orijinal değeri, döndürülen sözlüğe açık bir şekilde iletilmelidir.

1:2 veya daha fazla geçiş tanımlama

Uçtan uca örneği

Giden kenar geçişi tek bir girişi eşleyebilir iki veya daha fazla çıkış yapılandırmasına uyarlayabilirsiniz. Bu, çok mimarili kodu bir araya getiren kuralları tanımlamak için yararlıdır.

1:2+ geçişleri, bir sözlük listesi döndürerek işlevini kullanın.

# 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 bağımlılıkları tek tek okuyabilirsiniz:

# 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

Uçtan uca örnek

Geçişler iki yere eklenebilir: gelen kenarlar ve giden kenarlar. Bu, kuralların kendi yapılandırmalarını (gelecekte uç geçişi) ve bağımlılıklarını yapılandırmalar (giden kenar geçişi) olduğundan emin olun.

NOT: Şu anda Starlark geçişlerini yerel kurallara eklemek mümkün değildir. Bunu yapmanız gerekiyorsa bazel-discuss@googlegroups.com adresine göz atın.

Gelen kenar geçişleri

Gelen kenar geçişleri, bir transition nesnesi eklenerek etkinleştirilir rule() kullanıcısının cfg parametresine (transition() tarafından oluşturuldu):

# 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şler 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.

Geçişlerle özelliklere erişme başlıklı makaleyi inceleyin. öğrenebilirsiniz.

Yerel seçeneklerde geçişler

Uçtan uca örneği

Starlark geçişleri, seçenek adının önüne özel bir ön ek ekleyerek yerel derleme yapılandırma seçeneklerinde okuma ve yazma işlemlerini de belirtebilir.

# 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 uygulamasında "//command_line_option:define". Bunun yerine özel bir derleme ayarı kullanın. Genel olarak, --define'ün yeni kullanımlarının derleme ayarları lehine bırakılması önerilir.

Bazel, --config tarihinde geçiş işlemini desteklemiyor. Bunun nedeni, --config'ün diğer işaretlere genişleyen bir "genişleme" işareti olmasıdır.

Önemli bir nokta, --config'ün, derleme yapılandırmasını etkilemeyen işaretçiler içerebilmesidir (ör. --spawn_strategy). Bazel, tasarım gereği bu tür işaretleri tek tek hedeflere bağlayamaz. Bu, geçişlerde bunları tutarlı bir şekilde uygulamanın mümkün olmadığı anlamına gelir.

Geçici bir çözüm olarak, öğesinin parçası olan işaretleri yapılandırdığınızdan emin olun. Bu, --config öğesinin korunmasını gerektirir ve bu da bilinen bir kullanıcı arayüzü sorunudur.

Birden fazla derleme ayarına izin veren geçişler

Birden fazla değere izin veren derleme ayarları belirlenirken ayarın değeri bir listeyle 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 döndürürse bu, tüm ayarların orijinal değerlerinde tutulması için kısayoldur. Bu, her çıkışı açıkça kendi kendisine ayarlamaktan daha uygun 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ş içeren özelliklere erişme

Uçtan uca örneği

Giden bir kenara geçiş eklerken (geçişin 1:1 veya 1:2+ geçişlerinden bağımsız olarak) ctx.attr listesi zorunlu kılınır. uygun bir yöntem de yoktur. 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 ayarlanmışsa ctx.split_attr kullanılabilir her anahtar için ayrı bölümleri okumak:

# 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 inceleyin burayı tıklayın.

Platformlar ve araç zincirleriyle entegrasyon

Günümüzde --cpu ve --crosstool_top gibi birçok yerel işaret birbiriyle alakalıdır araç zinciri çözünürlüğüne sahip. Gelecekte bu tür belgelerde açıkça bayrakların yerini büyük olasılıkla hedef platforma bağlı olarak değişebilir.

Bellek ve performansla ilgili dikkat edilmesi gereken noktalar

Yapınıza geçişler ve dolayısıyla yeni yapılandırmalar eklemek maliyet: daha büyük yapı grafikleri, daha az anlaşılır yapı grafikleri ve daha yavaş inşa eder. 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ğinizin nasıl katlanarak büyüyebileceğine dair bir örnek verilmiştir.

Kötü davranışlı derlemeler: örnek olay

Ölçeklenebilirlik grafiği

Şekil 1. Üst düzey bir hedefi ve bağımlılıklarını gösteren ölçeklenebilirlik grafiği.

Bu grafikte, iki hedefe bağlı olan üst düzey bir hedef (//pkg:app) gösterilmektedir. //pkg:1_0 ve //pkg:1_1. Bu hedeflerin ikisi de //pkg:2_0 ve //pkg:2_1 adlı 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 (//pkg:dep) bağlı olan //pkg:n_0 ve //pkg:n_1'e kadar devam eder.

//pkg:app oluşturmak için \(2n+2\) aşağıdaki hedefler gerekir:

  • //pkg:app
  • //pkg:dep
  • \(i\) adlı kuruluş biriminde \([1..n]\)için //pkg:i_0 ve //pkg:i_1

Bir işaret uyguladığınızı düşünün --//foo:owner=<STRING> ve //pkg:i_b geçerlidir

depConfig = myConfig + depConfig.owner="$(myConfig.owner)$(b)"

Diğer bir deyişle, //pkg:i_b tüm bağımlılıkları için b değerini --owner değerinin eski değerine 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ış hedefler oluşturur: config.owner= \(\{0,1\}\)içindeki tüm \(b_i\) için "\(b_0b_1...b_n\)".

Böylece, derleme grafiği hedef grafikten katlanarak daha büyük hale gelir. sonuçlar doğurabilir.

YAPILACAKLAR: Bu sorunların ölçümü ve azaltılması için stratejiler ekleyin.

Daha fazla bilgi

Derleme yapılandırmalarını değiştirme hakkında daha fazla bilgi için aşağıdaki konulara bakın: