Yapılandırmalar

Sorun bildir Kaynağı görüntüle Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Bu sayfada, projenizin nasıl oluşturulacağını özelleştirmek için Bazel'in API'si olan Starlark yapılandırmalarının avantajları ve temel kullanımı açıklanmaktadır. Derleme ayarlarının nasıl tanımlanacağı ve örnekler yer alır.

Bu sayede:

  • projeniz için özel işaretler tanımlayarak --define ihtiyacını ortadan kaldırın
  • Üst öğelerinden farklı yapılandırmalarda (ör. --compilation_mode=opt veya --cpu=arm) bağımlılıkları yapılandırmak için geçişler yazma
  • Kurallara daha iyi varsayılan değerler ekleyin (ör. belirtilen bir SDK ile otomatik olarak //my:android_app oluşturma)

ve daha fazlası, tamamen .bzl dosyalarından (Bazel sürümü gerekmez). Örnekler için bazelbuild/examples deposuna bakın.

Kullanıcı tanımlı derleme ayarları

Derleme ayarı, tek bir yapılandırma bilgisidir. Yapılandırmayı anahtar/değer eşlemesi olarak düşünebilirsiniz. --cpu=ppc ayarı ve --copt="-DFoo", {cpu: ppc, copt: "-DFoo"} gibi görünen bir yapılandırma oluşturur. Her giriş bir derleme ayarıdır.

cpu ve copt gibi geleneksel işaretler yerel ayarlardır. Anahtarları tanımlanır ve değerleri yerel Bazel Java kodu içinde ayarlanır. Bazel kullanıcıları bunları yalnızca komut satırı ve yerel olarak desteklenen diğer API'ler üzerinden okuyup yazabilir. Yerel işaretlerin ve bunları gösteren API'lerin değiştirilmesi için bazel sürümü gerekir. Kullanıcı tanımlı derleme ayarları .bzl dosyalarında tanımlanır (bu nedenle, değişikliklerin kaydedilmesi için Bazel sürümü gerekmez). Bu geçişler komut satırı üzerinden de ayarlanabilir (flags olarak belirlenmişse, daha fazla bilgiyi aşağıda bulabilirsiniz). Ayrıca kullanıcı tanımlı geçişler üzerinden de ayarlanabilir.

Derleme ayarlarını tanımlama

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 bir dizi temel Starlark türüyle sınırlıdır. Ayrıntılar için config modülü belgelerini inceleyin. Daha karmaşık yazma işlemleri, kuralın uygulama işlevinde yapılabilir. Bu konuyla ilgili daha fazla bilgiyi aşağıda bulabilirsiniz.

config modülünün işlevleri, varsayılan olarak false değerine ayarlanmış isteğe bağlı bir boolean parametresi olan flag alır. flag true olarak ayarlanırsa derleme ayarı, komut satırında kullanıcılar tarafından ve kural yazanlar tarafından varsayılan değerler ve geçişler aracılığıyla dahili olarak da ayarlanabilir. Tüm ayarlar kullanıcılar tarafından belirlenememelidir. Örneğin, kural yazarı olarak test kurallarında etkinleştirmek istediğiniz bir hata ayıklama modunuz varsa kullanıcıların bu özelliği diğer test dışı kurallarda rastgele etkinleştirmesine izin vermek istemezsiniz.

ctx.build_setting_value kullanma

Tüm kurallar gibi, derleme ayarı kurallarının da uygulama işlevleri vardır. Derleme ayarlarının temel Starlark türü değerine ctx.build_setting_value yöntemiyle erişilebilir. Bu yöntem yalnızca derleme ayarı kurallarının ctx nesneleri için kullanılabilir. Bu uygulama yöntemleri, derleme ayarları değerini doğrudan iletebilir veya üzerinde ek işlemler (ör. tür kontrolü ya da daha karmaşık yapı oluşturma) yapabilir. enum türünde bir derleme ayarını nasıl uygulayacağınız aşağıda açıklanmıştır:

# example/buildsettings/build_settings.bzl
TemperatureProvider = provider(fields = ['type'])

temperatures = ["HOT", "LUKEWARM", "ICED"]

def _impl(ctx):
    raw_temperature = ctx.build_setting_value
    if raw_temperature not in temperatures:
        fail(str(ctx.label) + " build setting allowed to take values {"
             + ", ".join(temperatures) + "} but was set to unallowed value "
             + raw_temperature)
    return TemperatureProvider(type = raw_temperature)

temperature = rule(
    implementation = _impl,
    build_setting = config.string(flag = True)
)

Çoklu küme dize işaretlerini tanımlama

Dize ayarlarında, komut satırında veya bazelrc'lerde işaretin birden çok kez ayarlanmasına olanak tanıyan ek bir allow_multiple parametresi bulunur. Varsayılan değerleri, dize türünde bir özellikle ayarlanmaya devam eder:

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

Her işaret ayarı tek bir değer olarak kabul edilir:

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

Yukarıdaki ifade {"//example:roasts": ["blonde", "medium,dark"]} olarak ayrıştırılır ve ctx.build_setting_value, ["blonde", "medium,dark"] listesini döndürür.

Derleme ayarlarını başlatma

build_setting parametresiyle tanımlanan kurallar, örtülü bir zorunlu build_setting_default özelliğine sahiptir. Bu özellik, build_setting parametresi tarafından bildirilen türle aynı türü alır.

# example/buildsettings/build_settings.bzl
FlavorProvider = provider(fields = ['type'])

def _impl(ctx):
    return FlavorProvider(type = ctx.build_setting_value)

flavor = rule(
    implementation = _impl,
    build_setting = config.string(flag = True)
)
# example/buildsettings/BUILD
load("//example/buildsettings:build_settings.bzl", "flavor")
flavor(
    name = "favorite_flavor",
    build_setting_default = "APPLE"
)

Önceden tanımlanmış ayarlar

Uçtan uca örnek

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

Örneğin, sınırlı bir dize değerleri kümesini kabul eden bir ayar tanımlamak için:

# example/BUILD
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
string_flag(
    name = "myflag",
    values = ["a", "b", "c"],
    build_setting_default = "a",
)

Tam liste için Ortak derleme ayarı kuralları başlıklı makaleyi inceleyin.

Derleme ayarlarını kullanma

Derleme ayarlarına bağlı olarak

Bir hedef, yapılandırma bilgisini okumak istiyorsa normal bir özellik bağımlılığı aracılığıyla doğrudan derleme ayarına bağlı olabilir.

# example/rules.bzl
load("//example/buildsettings:build_settings.bzl", "FlavorProvider")
def _rule_impl(ctx):
    if ctx.attr.flavor[FlavorProvider].type == "ORANGE":
        ...

drink_rule = rule(
    implementation = _rule_impl,
    attrs = {
        "flavor": attr.label()
    }
)
# example/BUILD
load("//example:rules.bzl", "drink_rule")
load("//example/buildsettings:build_settings.bzl", "flavor")
flavor(
    name = "favorite_flavor",
    build_setting_default = "APPLE"
)
drink_rule(
    name = "my_drink",
    flavor = ":favorite_flavor",
)

Diller, o dille ilgili tüm kuralların bağlı olduğu standart bir derleme ayarları grubu oluşturmak isteyebilir. fragments kavramı artık Starlark yapılandırma dünyasında sabit kodlanmış bir nesne olarak bulunmasa da bu kavramı çevirmenin bir yolu, ortak örtülü özellik kümelerini kullanmaktır. Örneğin:

# kotlin/rules.bzl
_KOTLIN_CONFIG = {
    "_compiler": attr.label(default = "//kotlin/config:compiler-flag"),
    "_mode": attr.label(default = "//kotlin/config:mode-flag"),
    ...
}

...

kotlin_library = rule(
    implementation = _rule_impl,
    attrs = dicts.add({
        "library-attr": attr.string()
    }, _KOTLIN_CONFIG)
)

kotlin_binary = rule(
    implementation = _binary_impl,
    attrs = dicts.add({
        "binary-attr": attr.label()
    }, _KOTLIN_CONFIG)

Komut satırında derleme ayarlarını kullanma

Çoğu yerel işaret gibi, işaret olarak işaretlenen derleme ayarlarını belirlemek için komut satırını kullanabilirsiniz. Derleme ayarının adı, name=value söz dizimi kullanılarak oluşturulan tam hedef yoludur:

$ bazel build //my/target --//example:string_flag=some-value # allowed
$ bazel build //my/target --//example:string_flag some-value # not allowed

Özel Boole söz dizimi desteklenir:

$ bazel build //my/target --//example:boolean_flag
$ bazel build //my/target --no//example:boolean_flag

Derleme ayarı takma adlarını kullanma

Derleme ayarı hedef yolunuz için komut satırında daha kolay okunmasını sağlamak amacıyla bir takma ad belirleyebilirsiniz. Diğer adlar, yerel işaretlere benzer şekilde çalışır ve çift tireli seçenek söz dizimini kullanır.

--flag_alias=ALIAS_NAME=TARGET_PATH ekleyerek .bazelrc için takma ad belirleyin . Örneğin, coffee için takma ad ayarlamak istiyorsanız:

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

En iyi uygulama: Bir takma adın birden çok kez ayarlanması, en son ayarlanan takma adın öncelikli olmasına neden olur. İstenmeyen ayrıştırma sonuçlarını önlemek için benzersiz takma adlar kullanın.

Takma adı kullanmak için derleme ayarı hedef yolu yerine takma adı yazın. Kullanıcının .bazelrc ayarlarında coffee olarak ayarlanmış yukarıdaki örnekte:

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

yerine

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

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

Etiket türünde derleme ayarları

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

Etiket türündeki ayarlar, sonunda geç bağlanan varsayılanların işlevinin yerini alacak. Geç bağlanan varsayılan özellikler, son değerleri yapılandırmadan etkilenebilen Etiket türünde özelliklerdir. Bu, Starlark'ta configuration_field API'nin yerini alacak.

# example/rules.bzl
MyProvider = provider(fields = ["my_field"])

def _dep_impl(ctx):
    return MyProvider(my_field = "yeehaw")

dep_rule = rule(
    implementation = _dep_impl
)

def _parent_impl(ctx):
    if ctx.attr.my_field_provider[MyProvider].my_field == "cowabunga":
        ...

parent_rule = rule(
    implementation = _parent_impl,
    attrs = { "my_field_provider": attr.label() }
)

# example/BUILD
load("//example:rules.bzl", "dep_rule", "parent_rule")

dep_rule(name = "dep")

parent_rule(name = "parent", my_field_provider = ":my_field_provider")

label_flag(
    name = "my_field_provider",
    build_setting_default = ":dep"
)

Ayarları oluşturma ve select() işlevini kullanma

Uçtan uca örnek

Kullanıcılar, select() kullanarak derleme ayarlarında özellikleri yapılandırabilir. Derleme ayarı hedefleri, flag_values özelliğine aktarılabilir. config_setting. Yapılandırmayla eşleştirilecek değer, String olarak iletilir ve ardından eşleştirme için derleme ayarının türüne ayrıştırılır.

config_setting(
    name = "my_config",
    flag_values = {
        "//example:favorite_flavor": "MANGO"
    }
)

Kullanıcı tanımlı geçişler

Yapılandırma geçişi, derleme grafiğinde bir yapılandırılmış hedeften diğerine dönüşümü eşler.

Bu kuralları belirleyen kurallar özel bir özellik içermelidir:

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

Geçiş ekleyerek derleme grafiğinizin boyutunu kolayca artırabilirsiniz. Bu işlem, bu kuralın hedeflerini oluşturabileceğiniz paketlerde bir izin verilenler listesi oluşturur. Yukarıdaki kod bloğunda varsayılan değer, her şeye izin verir. Ancak kuralınızı kimlerin kullanabileceğini kısıtlamak istiyorsanız bu özelliği kendi özel izin verilenler listenize yönlendirecek şekilde ayarlayabilirsiniz. Geçişlerin derleme performansınızı nasıl etkileyebileceğini anlamak için tavsiye veya yardım almak isterseniz bazel-discuss@googlegroups.com ile iletişime geçin.

Tanımlama

Geçişler, kurallar arasındaki yapılandırma değişikliklerini tanımlar. Örneğin, "bağımlılığımı üst öğesinden farklı bir CPU için derle" gibi bir istek geçişle işlenir.

Resmi olarak geçiş, bir giriş yapılandırmasından bir veya daha fazla çıkış yapılandırmasına yönelik bir işlevdir. Çoğu geçiş 1:1'dir (ör. "giriş yapılandırmasını --cpu=ppc ile geçersiz kıl"). 1:2'den fazla geçiş de olabilir ancak özel kısıtlamalarla birlikte gelir.

Starlark'ta geçişler, kurallara benzer şekilde tanımlanır. Tanımlayan bir transition() işlev ve bir uygulama işlevi vardır.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {"//example:favorite_flavor" : "MINT"}

hot_chocolate_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//example:favorite_flavor"]
)

transition() işlevi bir uygulama işlevi, okunacak bir dizi derleme ayarı(inputs) ve yazılacak bir dizi derleme ayarı (outputs) alır. Uygulama işlevinin iki parametresi vardır: settings ve attr. settings, inputs parametresinde transition() için belirtilen tüm ayarların sözlüğüdür {String:Object}.

attr, geçişin eklendiği kuralın özellik ve değer sözlüğüdür. Giden kenar geçişi olarak eklendiğinde bu özelliklerin değerleri, select() çözümlendirmesinden sonra yapılandırılır. Gelen kenar geçişi olarak eklendiğinde attr, değerini çözmek için seçici kullanan hiçbir özellik içermez. --foo üzerinde gelen bir kenar geçişi, bar özelliğini okuyup ardından bar özelliğini ayarlamak için --foo üzerinde seçim yaparsa gelen kenar geçişinin, geçişte bar özelliğinin yanlış değerini okuma ihtimali vardır.

Uygulama işlevi, uygulanacak yeni derleme ayarları değerlerinin sözlüğünü (veya birden fazla çıkış yapılandırması içeren geçişler söz konusu olduğunda sözlük listesini) döndürmelidir. Döndürülen sözlük anahtar kümeleri, geçiş işlevinin outputs parametresine iletilen derleme ayarları kümesini içermelidir. Bu durum, geçiş sırasında bir derleme ayarı gerçekten değiştirilmemiş olsa bile geçerlidir. Orijinal değeri, döndürülen sözlükte açıkça iletilmelidir.

1:2'den fazla geçiş tanımlama

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 kullanışlıdır.

1:2'den fazla geçiş, geçiş uygulama işlevinde sözlük listesi döndürülerek tanımlanır.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return [
        {"//example:favorite_flavor" : "LATTE"},
        {"//example:favorite_flavor" : "MOCHA"},
    ]

coffee_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//example:favorite_flavor"]
)

Ayrıca, kural uygulama işlevinin tek tek bağımlılıkları okumak için kullanabileceği özel anahtarlar da ayarlayabilirler:

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {
        "Apple deps": {"//command_line_option:cpu": "ppc"},
        "Linux deps": {"//command_line_option:cpu": "x86"},
    }

multi_arch_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//command_line_option:cpu"]
)

Geçiş ekleme

Uçtan uca örnek

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

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

Gelen kenar geçişleri

Gelen kenar geçişleri, transition nesnesi (transition() tarafından oluşturulur) rule()'nin cfg parametresine eklenerek etkinleştirilir:

# example/rules.bzl
load("example/transitions:transitions.bzl", "hot_chocolate_transition")
drink_rule = rule(
    implementation = _impl,
    cfg = hot_chocolate_transition,
    ...

Gelen kenar geçişleri 1:1 geçiş olmalıdır.

Giden kenar geçişleri

Giden kenar geçişleri, bir özelliğin cfg parametresine transition nesnesi (transition() tarafından oluşturulur) eklenerek etkinleştirilir:

# example/rules.bzl
load("example/transitions:transitions.bzl", "coffee_transition")
drink_rule = rule(
    implementation = _impl,
    attrs = { "dep": attr.label(cfg = coffee_transition)}
    ...

Giden kenar geçişleri 1:1 veya 1:2+ olabilir.

Bu anahtarları nasıl okuyacağınız hakkında bilgi edinmek için Geçişlerle özelliklere erişme başlıklı makaleyi inceleyin.

Yerel seçeneklerdeki geçişler

Uçtan uca örnek

Starlark geçişleri, seçenek adının başına özel bir önek ekleyerek yerel derleme yapılandırma seçeneklerinde okuma ve yazma işlemleri de bildirebilir.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {"//command_line_option:cpu": "k8"}

cpu_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//command_line_option:cpu"]

Desteklenmeyen yerel seçenekler

Bazel, --define üzerinde "//command_line_option:define" ile geçişi desteklemez. Bunun yerine özel bir derleme ayarı kullanın. Genel olarak, derleme ayarları yerine --define'nın yeni kullanımları önerilmez.

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

En önemlisi, --config, derleme yapılandırmasını etkilemeyen işaretler (ör. --spawn_strategy) içerebilir. Bazel, tasarım gereği bu tür işaretleri tek tek hedeflere bağlayamaz. Bu nedenle, geçişlerde tutarlı bir şekilde uygulanamazlar.

Geçici çözüm olarak, geçişinizde yapılandırmanın bir parçası olan işaretleri açıkça listeleyebilirsiniz. Bu, --config'nın iki yerde genişletilmesini gerektirir. Bu da bilinen bir kullanıcı arayüzü kusurudur.

Geçişler birden fazla derleme ayarına izin verir

Birden fazla değere izin veren derleme ayarları belirlenirken ayarın değeri bir liste ile ayarlanmalıdır.

# example/buildsettings/build_settings.bzl
string_flag = rule(
    implementation = _impl,
    build_setting = config.string(flag = True, allow_multiple = True)
)
# example/BUILD
load("//example/buildsettings:build_settings.bzl", "string_flag")
string_flag(name = "roasts", build_setting_default = "medium")
# example/transitions/rules.bzl
def _transition_impl(settings, attr):
    # Using a value of just "dark" here will throw an error
    return {"//example:roasts" : ["dark"]},

coffee_transition = transition(
    implementation = _transition_impl,
    inputs = [],
    outputs = ["//example:roasts"]
)

İşlemsiz geçişler

Bir geçiş {}, [] veya None değerini döndürürse bu, tüm ayarların orijinal değerlerinde tutulması için kullanılan kısa bir yöntemdir. Bu, her çıkışı açıkça kendisine ayarlamaktan daha kolay olabilir.

# example/transitions/transitions.bzl
def _impl(settings, attr):
    _ignore = (attr)
    if settings["//example:already_chosen"] is True:
      return {}
    return {
      "//example:favorite_flavor": "dark chocolate",
      "//example:include_marshmallows": "yes",
      "//example:desired_temperature": "38C",
    }

hot_chocolate_transition = transition(
    implementation = _impl,
    inputs = ["//example:already_chosen"],
    outputs = [
        "//example:favorite_flavor",
        "//example:include_marshmallows",
        "//example:desired_temperature",
    ]
)

Geçişlerle özelliklere erişme

Uçtan uca örnek

Giden bir kenara geçiş eklenirken (geçişin 1:1 veya 1:2+ geçişi olup olmadığına bakılmaksızın) ctx.attr, zaten bir liste değilse liste olmaya zorlanır. Bu listedeki öğelerin sırası belirtilmemiş.

# example/transitions/rules.bzl
def _transition_impl(settings, attr):
    return {"//example:favorite_flavor" : "LATTE"},

coffee_transition = transition(
    implementation = _transition_impl,
    inputs = [],
    outputs = ["//example:favorite_flavor"]
)

def _rule_impl(ctx):
    # Note: List access even though "dep" is not declared as list
    transitioned_dep = ctx.attr.dep[0]

    # Note: Access doesn't change, other_deps was already a list
    for other dep in ctx.attr.other_deps:
      # ...


coffee_rule = rule(
    implementation = _rule_impl,
    attrs = {
        "dep": attr.label(cfg = coffee_transition)
        "other_deps": attr.label_list(cfg = coffee_transition)
    })

Geçiş 1:2+ ise ve özel anahtarlar ayarlıyorsa her anahtar için bağımsız bağımlılıkları okumak üzere ctx.split_attr kullanılabilir:

# example/transitions/rules.bzl
def _impl(settings, attr):
    _ignore = (settings, attr)
    return {
        "Apple deps": {"//command_line_option:cpu": "ppc"},
        "Linux deps": {"//command_line_option:cpu": "x86"},
    }

multi_arch_transition = transition(
    implementation = _impl,
    inputs = [],
    outputs = ["//command_line_option:cpu"]
)

def _rule_impl(ctx):
    apple_dep = ctx.split_attr.dep["Apple deps"]
    linux_dep = ctx.split_attr.dep["Linux deps"]
    # ctx.attr has a list of all deps for all keys. Order is not guaranteed.
    all_deps = ctx.attr.dep

multi_arch_rule = rule(
    implementation = _rule_impl,
    attrs = {
        "dep": attr.label(cfg = multi_arch_transition)
    })

Tam örneği burada görebilirsiniz.

Platformlar ve araç zincirleriyle entegrasyon

Günümüzde --cpu ve --crosstool_top gibi birçok yerel işaret, araç zinciri çözümüyle ilgilidir. Gelecekte, bu tür işaretlerdeki açık geçişlerin yerini hedef platformda geçiş alma olasılığı yüksektir.

Bellek ve performansla ilgili dikkat edilmesi gereken noktalar

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

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

Ölçeklenebilirlik grafiği

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

Bu grafikte, //pkg:1_0 ve //pkg:1_1 olmak üzere iki hedefe bağlı olan //pkg:app üst düzey hedefi gösterilmektedir. Bu hedeflerin her ikisi de //pkg:2_0 ve //pkg:2_1 olmak üzere iki hedefe bağlıdır. Bu hedeflerin her ikisi de //pkg:3_0 ve //pkg:3_1 olmak üzere iki hedefe bağlıdır. Bu işlem, her ikisi de tek bir hedefe bağlı olan //pkg:n_0 ve //pkg:n_1'e kadar devam eder: //pkg:dep.

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

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

Bir işaret uyguladığınızı (--//foo:owner=<STRING>) ve //pkg:i_b'ün geçerli olduğunu düşünün.

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

Diğer bir deyişle, //pkg:i_b, tüm bağımlılıkları için --owner'nin eski değerine b ekler.

Bu işlem, aşağıdaki yapılandırılmış hedefleri oluşturur:

//pkg:app                              //foo:owner=""
//pkg:1_0                              //foo:owner=""
//pkg:1_1                              //foo:owner=""
//pkg:2_0 (via //pkg:1_0)              //foo:owner="0"
//pkg:2_0 (via //pkg:1_1)              //foo:owner="1"
//pkg:2_1 (via //pkg:1_0)              //foo:owner="0"
//pkg:2_1 (via //pkg:1_1)              //foo:owner="1"
//pkg:3_0 (via //pkg:1_0 → //pkg:2_0)  //foo:owner="00"
//pkg:3_0 (via //pkg:1_0 → //pkg:2_1)  //foo:owner="01"
//pkg:3_0 (via //pkg:1_1 → //pkg:2_0)  //foo:owner="10"
//pkg:3_0 (via //pkg:1_1 → //pkg:2_1)  //foo:owner="11"
...

//pkg:dep, \(2^n\) yapılandırılmış hedef oluşturur: config.owner= \(\{0,1\}\)içindeki tüm \(b_i\) için "\(b_0b_1...b_n\)".

Bu durum, derleme grafiğini hedef grafikten katlanarak daha büyük hale getirir ve buna bağlı olarak bellek ve performansla ilgili sonuçlar ortaya çıkar.

YAPILACAKLAR: Bu sorunların ölçülmesi ve azaltılmasına yönelik stratejiler ekleyin.

Daha fazla bilgi

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