Yapılandırmalar

Sorun bildir Kaynağı göster

Bu sayfada Starlark yapılandırmalarının avantajları ve temel kullanımı, Bazel'in projenizin derleme biçimini özelleştirmeye yönelik API ele alınmaktadır. Videoda, oluşturma ayarlarının nasıl tanımlanacağı ve örnekler verilir.

Bu, aşağıdakileri mümkün kılar:

  • projeniz için özel işaretler tanımlayarak --define ihtiyacını ortadan kaldırır.
  • üst öğelerinden farklı yapılandırmalardaki (--compilation_mode=opt veya --cpu=arm gibi) depoları yapılandırmak için geçişler yazma
  • varsayılanları kurallara göre daha iyi hale getirme (ör. belirli bir SDK ile //my:android_app öğesini otomatik olarak derleme)

ve daha fazlası, tamamen .bzl dosyalarından yapılıyor (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 bilgisi parçasıdır. Yapılandırmayı bir anahtar/değer eşlemesi olarak düşünebilirsiniz. --cpu=ppc ve --copt="-DFoo" ayarlamaları, {cpu: ppc, copt: "-DFoo"} gibi bir yapılandırma oluşturur. Her giriş bir derleme ayarıdır.

cpu ve copt gibi geleneksel işaretler, yerel ayarlardır. Bunların anahtarları tanımlanır ve değerleri yerel Bazel java kodunda belirlenir. Bazel kullanıcıları, bunları yalnızca komut satırı ve yerel olarak yönetilen diğer API'ler aracılığıyla okuyup yazabilir. Yerel işaretlerin ve bunları açığa çıkaran API'lerin değiştirilmesi için yeni bir temel sürüm gereklidir. Kullanıcı tanımlı derleme ayarları .bzl dosyalarında tanımlanır (dolayısıyla, değişiklikleri kaydetmek için temel sürüm gerekmez). Ayrıca, komut satırı üzerinden de ayarlanabilirler (flags olarak tanımlanmışlarsa aşağıda daha fazla bilgi edinin) veya kullanıcı tanımlı geçişler aracılığıyla da ayarlanabilir.

Derleme ayarlarını tanımlama

Uçtan uca örneği

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. Bu 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ü dokümanları'na bakın. Kuralın uygulama işlevi, daha karmaşık bir yazma işlemi gerçekleştirilebilir. Bu konuda daha fazla bilgiyi aşağıda bulabilirsiniz.

config modülünün işlevleri, varsayılan olarak yanlış değerine ayarlanan isteğe bağlı flag boole parametresini alır. flag doğru değerine ayarlanırsa derleme ayarı, kullanıcılar tarafından komut satırından veya varsayılan değerler ve geçişler aracılığıyla kural yazarları tarafından dahili olarak ayarlanabilir. Tüm ayarlar kullanıcılar tarafından değiştirilemez. Örneğin, kural yazarı olarak test kurallarının içinde açmak istediğiniz bir hata ayıklama modu kullanıyorsanız, kullanıcılara bu özelliği diğer test dışı kurallarda ayrım yapmadan açma olanağı vermek istemezsiniz.

ctx.build_setting_value değerini kullanma

Tüm kurallar gibi oluşturma kurallarının uygulama işlevleri vardır. Derleme ayarlarının temel Starlark türü değerine ctx.build_setting_value yöntemi aracılığıyla erişilebilir. Bu yöntem yalnızca derleme ayarı kurallarının ctx nesnelerinde kullanılabilir. Bu uygulama yöntemleri, derleme ayarları değerini doğrudan yönlendirebilir veya üzerinde tür kontrolü ya da daha karmaşık yapı oluşturma gibi ek işler yapabilir. enum türünde bir derleme ayarını şu şekilde uygulayabilirsiniz:

# 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 setli dize işaretlerini tanımlama

Dize ayarlarında, işaretin komut satırında veya Bazelrcs'ta birden fazla kez ayarlanmasına olanak tanıyan ek bir allow_multiple parametresi bulunur. Varsayılan değerleri hâlâ dize türünde bir öznitelikle ayarlanmıştı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 dosya {"//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 kurallar, dolaylı bir zorunlu build_setting_default özelliğine sahiptir. Bu özellik, build_setting parametresinde belirtilenle 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/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

Skylib kitaplığı, özel Starlark yazmak zorunda kalmadan örnekleyebileceğiniz önceden tanımlanmış bir dizi ayar içerir.

Ö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 Yaygın derleme ayarı kuralları bölümüne bakın.

Derleme ayarlarını kullanma

Derleme ayarlarına bağlı olarak

Bir hedef, yapılandırma bilgilerini okumak isterse 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, söz konusu dil için tüm kuralların bağlı olduğu standart bir derleme ayarları grubu oluşturmak isteyebilir. fragments yerel kavramı artık Starlark yapılandırma dünyasında sabit kodlu bir nesne olarak mevcut olmasa da, bu kavramı çevirmenin bir yolu, yaygın örtülü özellik gruplarını 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şarete benzer şekilde, bayrak olarak işaretlenmiş derleme ayarlarını belirlemek için komut satırını kullanabilirsiniz. Derleme ayarını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 okumayı kolaylaştırmak amacıyla derleme ayarı hedef yolunuz için takma ad belirleyebilirsiniz. Takma adlar, yerel işaretlere benzer şekilde çalışır ve ayrıca çift kısa çizgili seçenek söz diziminden yararlanır.

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

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

En İyi Uygulama: Bir takma adın birden çok kez ayarlanması, en son takma adın öncelikli hale gelmesine neden olur. Sonuçların istenmeyen şekilde ayrıştırılmasını önlemek için benzersiz takma ad adları kullanın.

Takma addan yararlanmak için derleme ayarı hedef yolunun yerine takma adı yazın. Yukarıdaki coffee örneği kullanıcının .bazelrc öğesinde ayarlanmışsa:

$ 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 belirlemek mümkün olsa da bunları .bazelrc içinde bırakmak komut satırı karmaşasını azaltır.

Etiketle belirtilen derleme ayarları

Uçtan uca örneği

Diğer derleme ayarlarının aksine, etiketle ilgili ayarlar build_setting kural parametresi kullanılarak tanımlanamaz. Bunun yerine, Bazel'ın 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 şekilde tanımlanamamalarıdır.

Etiketle türetilen ayarlar sonuçta, geç sınırlamalı varsayılanların işlevselliğinin yerini alacaktır. Geç sınırlanmış varsayılan özellikler, nihai değerleri yapılandırmadan etkilenebilen Etiket türünde özelliklerdir. Bu sürüm, 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şturun ve select()

Uçtan uca örneği

Kullanıcılar, select() kullanarak derleme ayarlarındaki özellikleri yapılandırabilir. Derleme ayarı hedefleri, config_setting öğesinin flag_values özelliğine iletilebilir. Yapılandırmayla eşleştirilecek değer String olarak iletilir ve ardından eşleştirme için derleme ayarı 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, dönüşümü oluşturma grafiği içinde yapılandırılmış bir hedeften diğerine eşler.

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 derleyin" gibi bir istek bir geçiş tarafından işlenir.

Resmî olarak geçiş, giriş yapılandırmasından bir veya daha fazla çıkış yapılandırmasına geçiş işlevidir. Çoğu geçiş 1'e 1'dir (ör. "--cpu=ppc ile giriş yapılandırmasını geçersiz kıl" gibi). 1:2 ve üzeri geçişler de olabilir ancak özel kısıtlamalar olabilir.

Starlark'ta geçişler, tanımlayıcı bir transition() işlev ve bir uygulama işleviyle kurallara çok benzer şekilde tanımlanı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 derleme ayarları(inputs) ve yazmak için bir dizi derleme ayarı (outputs) alır. Uygulama işlevinin iki parametresi vardır: settings ve attr. settings, inputs parametresinde transition() için tanımlanan tüm ayarların {String:Object} sözlüğüdür.

attr, geçişin eklendiği kuralın özellikleri ve değerlerinin bir sözlüğüdür. Giden uç geçişi olarak eklendiğinde, bu özelliklerin tüm değerleri post-select() çözünürlüğünde yapılandırılır. Gelen uç geçişi olarak eklendiğinde attr, değerini çözümlemek için seçici kullanan hiçbir özellik içermez. --foo üzerinde gelen bir uç geçişi bar özelliğini okur ve ardından --foo üzerinde bar özelliğini ayarlamak için seçim yaparsa gelen uç geçişinin geçişte yanlış bar değerini okuma ihtimali vardır.

Uygulama işlevi, uygulanacak yeni derleme ayarları değerlerinin bir sözlüğü (veya birden fazla çıkış yapılandırması olan geçişlerde, sözlük listesi) döndürmelidir. Döndürülen sözlük anahtar kümeleri, tam olarak geçiş işlevinin outputs parametresine iletilen derleme ayarları grubunu içermelidir. Bir derleme ayarı geçiş sırasında gerçekten değiştirilmese bile bu geçerlidir; orijinal değeri döndürülen sözlükte açıkça geçirilmelidir.

1:2+ geçişleri tanımlama

Uçtan uca örneği

Giden uç 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 bir araya getiren kuralları tanımlamak için yararlıdır.

1:2+ geçişler, geçiş uygulama işlevinde bir 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 bağımsız 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şler ekleniyor

Uçtan uca örneği

Geçişler iki yere eklenebilir: gelen kenarlar ve giden kenarlar. Bu sayede kurallar kendi yapılandırmalarını (gelen uç geçişi) ve bağımlılık yapılandırmalarını (giden uç geçişi) geçirebilir.

NOT: Şu anda Starlark geçişlerini yerel kurallara eklemenin bir yolu yoktur. Bunu yapmanız gerekirse geçici çözümleri bulmak için yardım almak için bazel-talk@googlegroups.com ile iletişime geçin.

Gelen kenar geçişleri

Gelen kenar geçişleri, rule() cfg parametresine bir transition nesnesi (transition() tarafından oluşturulan) 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şturulan) 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ı öğrenmek için Geçiş içeren özelliklere erişme bölümüne bakın.

Yerel seçeneklerdeki geçişler

Uçtan uca örneği

Ayrıca Starlark geçişleri, seçenek adına özel bir ön ek 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ş yapılmasını desteklemiyor. Bunun yerine, özel bir oluşturma ayarı kullanın. Genel olarak, derleme ayarlarının yerine --define uygulamasının yeni kullanımları önerilmez.

Bazel, --config üzerinde geçiş yapmayı desteklemiyor. Bunun nedeni, --config değerinin diğer flag'lere genişleyen bir "genişletme" işareti olmasıdır.

En önemlisi de --config, derleme yapılandırmasını etkilemeyen --spawn_strategy gibi işaretler içerebilir. Bazel, tasarımı gereği bu tür işaretleri ayrı hedeflere bağlayamaz. Bu, bunları geçişlere uygulamanın tutarlı bir yolu olmadığı anlamına gelir.

Geçici bir çözüm olarak, geçişinizdeki yapılandırmanın bir parçası olan işaretleri açıkça öğe haline getirebilirsiniz. Bu, --config'ın genişletme özelliğinin iki yerde sürdürülmesini gerektirir. Bu, bilinen bir kullanıcı arayüzü arızasıdır.

Birden fazla derleme ayarına izin verme açık olduğunda yapılan geçişler

Birden çok değere izin veren derleme ayarları yapılırken 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 döndürürse bu, tüm ayarları orijinal değerlerinde tutmanın kısaltmasıdır. Bu, her çıktıyı açıkça belirtmekten daha kullanışlı 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şli ö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) henüz eklenmemişse ctx.attr adlı kullanıcının liste olması zorunlu kılınır. Bu listedeki öğelerin sırası belirtilmemiştir.

# 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ıysa ctx.split_attr, her anahtarın bağlantılarını ayrı ayrı okumak için 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 bulabilirsiniz.

Platformlar ve araç zincirleriyle entegrasyon

Günümüzde --cpu ve --crosstool_top gibi birçok yerel işaret, araç zinciri çözünürlüğüyle ilgilidir. Gelecekte, bu tür işaretlemelerdeki açık geçişlerin yerini muhtemelen hedef platformdaki geçişler alacaktır.

Bellek ve performans konusunda dikkat edilmesi gereken noktalar

Derlemenize geçişler, dolayısıyla yeni yapılandırmalar eklemenin bir maliyeti vardır: daha büyük derleme grafikleri, daha anlaşılır derleme grafikleri ve daha yavaş derlemeler. Derleme kurallarınızda geçişleri kullanmayı düşünürken bu maliyetleri göz önünde bulundurmanızı öneririz. Aşağıda, bir geçişin yapı grafiğinizde nasıl üstel büyüme oluşturabileceğine dair bir örnek verilmiştir.

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

Ölçeklenebilirlik grafiği

Şekil 1. Ü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 bir üst düzey hedef (//pkg:app) gösterilmektedir. Bu hedeflerin her ikisi de iki hedefe bağlıdır: //pkg:2_0 ve //pkg:2_1. Bu hedeflerin her ikisi de iki hedefe bağlıdır: //pkg:3_0 ve //pkg:3_1. Bu, her ikisi de tek bir hedefe (//pkg:dep) bağlı olan //pkg:n_0 ve //pkg:n_1 tarihine kadar devam eder.

//pkg:app oluşturulması için hedefler \(2n+2\) gerekir:

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

Bir işaret implement düşünün --//foo:owner=<STRING> ve //pkg:i_b

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

Diğer bir deyişle, //pkg:i_b, tüm atamaları için eski --owner değerine b ekler.

Bu, 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= \(b_i\) in \(\{0,1\}\)içindeki herkes için "\(b_0b_1...b_n\)".

Bu durum, derleme grafiğini hedef grafikten katlanarak daha büyük hale getirir ve buna karşılık gelen bellek ve performans sonuçları olur.

YAPILACAKLAR: Bu sorunları ölçmek ve azaltmak için stratejiler ekleyin.

Daha fazla bilgi

Derleme yapılandırmalarını değiştirme hakkında daha fazla bilgi için bkz.