Yapılandırmalar

Sorun bildir Kaynağı görüntüleyin Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bu sayfada, projenizin derleme şeklini özelleştirmek için Bazel'in API'si olan Starlark yapılandırmalarının avantajları ve temel kullanımı ele alınmaktadır. Derleme ayarlarının nasıl tanımlanacağını içerir ve örnekler sağlar.

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
  • Kurallara daha iyi varsayılan değerler ekleme (ör. belirli bir SDK ile //my:android_app otomatik olarak derleme)

ve daha fazlası, tamamen .bzl dosyalarından alınır (Bzel 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ı bir anahtar/değer eşlemesi olarak düşünün. --cpu=ppc ve --copt="-DFoo" ayarlandığında {cpu: ppc, copt: "-DFoo"} gibi görünen bir yapılandırma oluşturulur. 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 korunan diğer API'ler aracılığıyla okuyup yazabilir. Yerel işaretleri ve bunları açığa çıkaran 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 kaydetmek için bazel sürümüne ihtiyacınız yoktur). Ayrıca, komut satırı üzerinden de ayarlanabilir (flags olarak atanmışsa aşağıda daha fazla bilgi bulabilirsiniz) ancak 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 gibi temel Starlark türleriyle sınırlıdır. 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, varsayılan olarak yanlış değerine ayarlanmış isteğe bağlı bir boole parametresini (flag) alır. flag doğru değerine ayarlanırsa derleme ayarı, varsayılan değerler ve geçişler aracılığıyla kural yazarları tarafından dahili olarak veya kullanıcılar tarafından komut satırında ayarlanabilir. Tüm ayarlar kullanıcılar tarafından ayarlanamaz. Ö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 değerini kullanma

Tüm kurallar gibi derleme ayarı kuralları da uygulama işlevlerine sahiptir. Derleme ayarlarının temel Starlark türündeki değerine ctx.build_setting_value yöntemi aracılığıyla erişilebilir. Bu yöntem yalnızca derleme ayarı kurallarının ctx nesneleri tarafından kullanılabilir. Bu uygulama yöntemleri, derleme ayarları değerini doğrudan iletebilir veya üzerinde ek işlemler (ör. tür kontrolü veya daha karmaşık yapı oluşturma) yapabilir. enum türünde bir derleme ayarını şu şekilde uygularsınız:

# 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 ayar dizesi işaretlerini tanımlama

Dize ayarlarında, işaretin komut satırında veya bazelrcs'de birden çok kez ayarlanmasına olanak tanıyan ek bir allow_multiple parametresi bulunur. Bunların varsayılan değeri hâlâ dize türünde 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 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ı örneklendirme

build_setting parametresiyle tanımlanan kurallarda, zorunlu build_setting_default özelliği varsayılan olarak bulunur. Bu özellik, build_setting parametresi tarafından belirtilenle aynı türdedir.

# 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 örnek

Skylib kitaplığı, özel Starlark yazmanıza gerek kalmadan örneklendirebileceğiniz önceden tanımlanmış bir ayar grubu içerir.

Örneğin, sınırlı sayıda dize değeri 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 bilgilerini 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, tüm kuralların bağlı olduğu standart bir derleme ayarları grubu oluşturmak isteyebilir. fragments doğal kavramı artık Starlark yapılandırma dünyasında kodlanmış bir nesne olarak mevcut olmasa da bu kavramı çevirmenin bir yolu, ortak gizli özellik kümeleri 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, işaret olarak işaretlenmiş derleme ayarlarını ayarlamak 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 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.

.bazelrc alanına --flag_alias=ALIAS_NAME=TARGET_PATH ekleyerek bir takma ad belirleyin . Ö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 örnek

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ımlanamayacaklarıdır.

Etiket türünde ayarlar, sonuçta geç sınırlanan varsayılanların işlevinin yerini alacaktı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'nin yerini alır.

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

Build settings 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ı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 yapılan dönüşümü eşler.

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ırmasına yapılan bir işlevdir. Çoğu geçiş 1:1'dir. Örneğin, "giriş yapılandırmasını --cpu=ppc ile geçersiz kıl". 1:2 ve üstü geçişler de olabilir ancak bazı özel kısıtlamalar vardır.

Starlark'ta geçişler, tanımlayan bir transition() işlevi ve uygulama işlevi ile kurallara 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şlevini, okunacak bir dizi derleme ayarını(inputs) ve yazılacak bir dizi derleme ayarını (outputs) alır. Uygulama işlevinin settings ve attr adlı iki parametresi vardır. 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. Giden kenar geçişi olarak eklendiğinde bu özelliklerin tümünün değerleri, select() çözümlemesi sonrasında yapılandırılır. Gelen kenar geçişi olarak eklendiğinde attr, değerini çözmek için seçici kullanan özellikleri içermez. --foo üzerindeki bir gelen kenar geçişi bar özelliğini okuyup bar özelliğini ayarlamak için --foo'te seçim yaparsa gelen kenar geçişinin geçişte bar özelliğinin yanlış değerini okuması olasıdır.

Uygulama işlevi, uygulanacak yeni derleme ayarı değerlerinin sözlüğünü (veya birden fazla çıkış yapılandırması olan 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, tam olarak geçiş işlevinin outputs parametresine iletilen derleme ayarları grubunu içermelidir. Bu durum, bir derleme ayarı geçiş sırasında gerçekten değiştirilmemiş olsa bile geçerlidir. Orijinal değeri, döndürülen sözlüğe açıkça iletilmelidir.

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

Uçtan uca örnek

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 yararlıdır.

1:2 ve daha fazla geçiş, 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ş ekleme

Uçtan uca örnek

Geçişler iki yere eklenebilir: gelen kenarlar ve giden kenarlar. Bu, kuralların kendi yapılandırmalarını (gelen uç geçiş) ve bağımlılıklarının yapılandırmalarını (giden uç geçişi) geçirebileceği anlamına gelir.

NOT: Starlark geçişlerini yerel kurallara eklemenin şu anda bir yolu yoktur. Bunu yapmanız gerekiyorsa geçici çözümler bulma konusunda yardım almak için bazel-discuss@googlegroups.com adresiyle iletişime geçin.

Gelen kenar geçişleri

Gelen kenar geçişleri, rule() cfg parametresine bir transition nesnesi (transition() tarafından oluşturulmuş) 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şler olmalıdır.

Giden kenar geçişleri

Giden uç geçişleri, özelliğin cfg parametresine bir 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şlerle özelliklere erişme başlıklı makaleyi inceleyin.

Yerel seçeneklerde geçişler

Uçtan uca örnek

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'te "//command_line_option:define" ile geçişi desteklemez. Bunun yerine, özel bir derleme ayarı kullanın. Genel olarak, yeni --define kullanımlarının yerine derleme ayarları kullanılması önerilmez.

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şaretler (ör. --spawn_strategy) içerebilmesidir. Bazel, tasarım gereği bu tür işaretleri tek tek hedeflere bağlayamaz. Bu, bunların geçişlerde uygulanmasının tutarlı bir yolu olmadığı anlamına gelir.

Geçişinizde yapılandırma kapsamında bulunan işaretleri açıkça listeleyebilirsiniz. Bunun için --config'nin genişletmesini iki yerde korumanız gerekir. Bu, bilinen bir kullanıcı arayüzü kusurudur.

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

Birden fazla değere izin veren derleme ayarları yapılırken, 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ı orijinal değerlerinde tutmanın kısa yoludur. 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şlerle özelliklere erişme

Uçtan uca örnek

Giden bir kenara geçiş eklenirken (geçişin 1:1 veya 1:2+ geçiş olması fark etmez) ctx.attr, hâlihazırda 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 oluşturuyorsa ctx.split_attr, her bir anahtar için bağımsız sunumları okumak amacıyla 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

--cpu ve --crosstool_top gibi birçok yerel işaret, günümüzde araç zinciri çözümüyle ilgilidir. Gelecekte bu tür işaretlerde açık geçişler büyük olasılıkla hedef platformda geçişle değiştirilecektir.

Bellek ve performansla ilgili dikkat edilmesi gereken noktalar

Derlemenize geçişler ve dolayısıyla yeni yapılandırmalar eklemek bazı maliyetlere neden olur: daha büyük derleme grafikleri, daha az 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 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: bir örnek olay

Ölçeklenebilirlik grafiği

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

Bu grafikte, //pkg:1_0 ve //pkg:1_1 adlı iki hedefe bağlı olan üst düzey bir hedef (//pkg:app) 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 adlı iki hedefe bağlıdır. Bu durum //pkg:n_0 ve //pkg:n_1 tarihine kadar devam eder. Bunların her ikisi de //pkg:dep hedefine bağlıdır.

//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çerli olur

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\)".

Bu, derleme grafiğini hedef grafikten kat kat daha büyük hale getirir ve buna karşılık gelen bellek ve performans sorunlarına yol açar.

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 makaleleri inceleyin: