Yapılandırmalar

Sorun bildirin Kaynağı göster

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

Bu sayede:

  • projeniz için özel flag'ler tanımlayarak --define ihtiyacını ortadan kaldırın
  • sunumları üst öğelerinden farklı yapılandırmalarda (--compilation_mode=opt veya --cpu=arm gibi) yapılandırmak için geçişler yazın
  • daha iyi varsayılan uygulamalar oluşturma (ör. belirtilen bir SDK ile //my:android_app uygulamasını 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 bilgisi parçasıdır. Yapılandırmayı bir anahtar/değer eşlemesi olarak düşünebilirsiniz. --cpu=ppc ve --copt="-DFoo" ayarlandığında {cpu: ppc, copt: "-DFoo"} gibi bir yapılandırma oluşturulur. Her giriş bir derleme ayarıdır.

cpu ve copt gibi geleneksel flag'ler yerel ayarlardır. Bunların anahtarları tanımlanır ve değerleri yerel bazel Java kodunun 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ından da 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 örneği

build_setting rule() parametresi

Derleme ayarları, diğer kurallar gibidir 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 temel Starlark türleri grubuyla sınırlıdır. Ayrıntılar için config modülü belgelerine bakın. Kuralın uygulama işlevinde daha karmaşık yazma işlemleri yapılabilir. Aşağıda bu konuyla ilgili daha fazla bilgi 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 değiştirilemez. Örneğin, kural yazarı olarak test kuralları içinde etkinleştirmek istediğiniz bir hata ayıklama modu varsa kullanıcılara test dışı diğer kurallarda bu özelliği ayrım yapmadan açma olanağı vermek istemezsiniz.

ctx.build_setting_value kullanılması

Tüm kurallar gibi derleme ayarı kurallarının da uygulama işlevleri vardır. Derleme ayarlarının temel Starlark türündeki değerine ctx.build_setting_value yöntemi kullanılarak 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 yönlendirebilir veya tür denetimi ya da daha karmaşık struct oluşturma gibi işlemler üzerinde ek işler 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)
)

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

Dize ayarlarında, işaretin komut satırında veya bazelrc'lerde 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/buildsettings/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ü zorunlu bir build_setting_default özelliği bulunur. Bu özellik, build_setting parametresiyle 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/buildsettings/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 yazmadan örneklendirebileceğiniz bir dizi önceden tanımlanmış 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 Ortak derleme ayarı kuralları bölümüne bakın.

Derleme ayarlarını kullanma

Derleme ayarlarına bağlı olarak

Hedef, bir yapılandırma bilgisini 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, tüm kuralların bağlı olduğu standart bir derleme ayarları grubu oluşturmak isteyebilir. Starlark yapılandırma dünyasında fragments yerel kavramı artık sabit kodlu bir nesne olarak bulunmasa da bu kavramı çevirmenin bir yolu, yaygın ö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şarete benzer şekilde, bayrak olarak işaretlenen 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

Derleme ayarı hedef yolunuz için bir takma ad belirleyerek komut satırında okumayı kolaylaştırabilirsiniz. Takma adlar, yerel işaretlere benzer şekilde çalışır ve çift kısa çizgi seçeneği söz diziminden de yararlanır.

.bazelrc hesabınıza --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 İyi Uygulama: Bir takma adın birden fazla kez ayarlanması, en yeni takma ada öncelik verilmesini sağlar. İstenmeyen ayrıştırma sonuçları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 ayarlanır:

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

Etiket türünde derleme ayarları

Uçtan uca örneği

Diğer derleme ayarlarının aksine, etiket türünde ayarlar build_setting kural parametresi kullanılarak tanımlanamaz. 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şlerle okunabilir/yazılabilir ve label_flag, diğer build_setting kurallarının yaptığı 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ç giden varsayılan özellikler, nihai değerleri yapılandırmadan etkilenebilecek Etiket türünde özelliklerdir. Starlark'ta bu 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"
)

Derleme ayarları 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 geçirilebilir. 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ğindeki yapılandırılmış bir 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şler ekleyerek derleme grafiğinizin boyutunu kolayca büyütebilirsiniz. Bu işlem, bu kuralın hedeflerini oluşturabileceğiniz paketlerde bir izin verilenler listesi ayarlar. Yukarıdaki kod bloğunda bulunan varsayılan değer her şeyi izin verilenler listesine ekler. Ancak kuralınızı kullanan kişileri 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 öneri veya yardım almak isterseniz bazel-caption@googlegroups.com adresinden iletişime geçebilirsiniz.

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ş tarafından işlenir.

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ı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ş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, transition() değerine inputs parametresinde tanımlanan tüm ayarların {String:Object} sözlüğüdür.

attr, geçişin eklendiği kuralın özelliklerini ve değerlerini içeren bir sözlüktür. Giden uç geçişi olarak eklendiğinde bu özelliklerin değerlerinin tamamı, "select() sonrası" çözünürlükle yapılandırılmıştı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 bar özelliğini ayarlamak için --foo alanında da seçim yaparsa gelen kenar geçişinin geçişte yanlış bar değerini okuma ihtimali vardı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. Bir derleme ayarının geçiş boyunca gerçekten değiştirilmemiş olması durumunda bile bu durum geçerlidir. Orijinal değerin, döndürülen sözlükte açık bir şekilde iletilmesi gerekir.

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, çoklu mimari kodları içeren kuralları tanımlamak için yararlıdır.

1:2+ geçişleri, 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 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 örneği

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: Şu anda Starlark geçişlerini yerel kurallara eklemek mümkün değildir. Bunu yapmanız gerekiyorsa geçici çözümler bulmak üzere yardım almak için bazel-caption@googlegroups.com ile iletişime geçebilirsiniz.

Gelen kenar geçişleri

Gelen kenar geçişleri, rule() etiketinin 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 bölümüne bakın.

Yerel seçeneklerde geçişler

Uçtan uca örneği

Starlark geçişleri, seçenek adına özel bir ön ek kullanarak yerel derleme yapılandırma seçeneklerinde okuma ve yazma işlemlerini 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 tarihinde "//command_line_option:define" ile geçiş yapmayı desteklemiyor. 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 öğesinin diğer flag'lere genişleyen bir "genişletme" işareti olmasıdır.

--config, derleme yapılandırmasını etkilemeyen işaretleri de içerebilir (ör. --spawn_strategy). Tasarım gereği Bazel'in bu tür işaretleri tek tek hedeflere bağlaması mümkün değildir. Bu, bunların geçişlerde uygulanmasının tutarlı bir yolu olmadığı anlamına gelir.

Geçici bir çözüm olarak, geçişinizde yapılandırmanın parçası olan işaretleri açık bir şekilde öğe haline getirebilirsiniz. Bunun için --config öğesinin genişletilmesinin iki yerde sürdürülmesi gerekir. Bu durum, 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ı 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 bir çıktıyı açıkça 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, daha önce yapılmamışsa liste olarak kullanılmaya 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 inceleyebilirsiniz.

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şaretlerdeki açık geçişlerin yerini muhtemelen hedef platformda geçiş yapacaktır.

Bellek ve performansla ilgili dikkat edilmesi gereken noktalar

Yapınıza geçişler ve dolayısıyla yeni yapılandırmalar eklemenin bir maliyeti vardır: daha büyük yapı grafikleri, daha az anlaşılır yapı grafikleri ve daha yavaş derlemeler. Derleme kurallarınızda geçişleri kullanırken bu maliyetleri göz önünde bulundurmalısınız. Aşağıda, bir geçişin yapı grafiğinizde nasıl katlanarak büyüme sağlayabileceğ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 grafik, a //pkg:1_0 ve //pkg:1_1 olmak üzere iki hedefe bağlı olan üst düzey bir hedef (//pkg:app) gösterir. 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 işlem //pkg:n_0 ve //pkg:n_1 tarihine kadar devam eder. Bunların her ikisi de tek bir hedefe (//pkg:dep) bağlıdır.

//pkg:app oluşturmak için \(2n+2\) hedefler gereklidir:

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

implement) ve bir işaret --//foo:owner=<STRING> ve //pkg:i_b olduğunu varsayalım.

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

Yani //pkg:i_b, tüm düzeyleri için eski --owner 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, yapılandırılmış \(2^n\) hedefler oluşturur: config.owner= herkesin \(b_i\) \(\{0,1\}\)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ı ortaya çıkar.

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: