Özellikler

. Sorun bildirin Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Bu sayfada, Çevik yaklaşımın temellerini göz önünde bulundurur ve hem basit hem de örnekler.

En boy oranları, ek bilgi içeren bağımlılık grafiklerinin artırılmasına olanak tanır ve işlemler. Özelliklerin yararlı olabileceği bazı tipik senaryolar:

  • Bazel'i entegre eden entegre geliştirme ortamları, Google Haritalar'daki belirler.
  • Kod oluşturma araçları, belli bir ekip üyesine ait girdileri hedeften bağımsız bir yöntemdir. Örneğin, BUILD dosyaları bir hiyerarşi belirtebilir protobuf kitaplığının tanımlar ve dile özgü kurallar, Çevik ve Scrum’ın belirli bir dil için protobuf destek kodu oluşturan işlemler.

Aspect ile ilgili temel bilgiler

BUILD dosyaları, bir projenin kaynak koduyla ilgili bir açıklama sağlar: Hangi kaynak? hangi yapıların (hedefler) oluşturulması gerektiğine, ve bu dosyalar arasındaki bağımlılıkların neler olduğu gibi konuları ele alacağız. Bazel, yani bir derleme işlemi için gereken işlemleri yapıları oluşturmak için gerekli olan (örneğin, derleyici veya bağlayıcı çalıştırma) ve bu işlemleri yürütür. Bazel bunu başarmak için bir bağımlılık grafiği ziyaret edin.

Şu BUILD dosyasını göz önünde bulundurun:

java_library(name = 'W', ...)
java_library(name = 'Y', deps = [':W'], ...)
java_library(name = 'Z', deps = [':W'], ...)
java_library(name = 'Q', ...)
java_library(name = 'T', deps = [':Q'], ...)
java_library(name = 'X', deps = [':Y',':Z'], runtime_deps = [':T'], ...)

Bu BUILD dosyası, aşağıdaki şekilde gösterilen bir bağımlılık grafiğini tanımlar:

Grafik oluştur

Şekil 1. BUILD dosya bağımlılık grafiği.

Bazel, bu bağımlılık grafiğini analiz etmek için her biri için karşılık gelen kural (bu örnekte "java_library") hedef. Kural uygulama işlevleri, .jar dosyaları gibi derleme yapıları ve konumlar gibi ilet bilgileri ve bu eserlerin adlarını, bu hedeflerin ters bağımlılıklarına sağlayıcılar.

Yönler kurallara benzer, çünkü özellik içeren bir uygulama işlevine işlem ve iade sağlayıcıları oluşturur. Ancak güçleri bağımlılık grafiğinin onlar için oluşturulduğu şeydir. Bir yöne göre uygulama mevcut ve yayıldığı tüm özelliklerin listesini içerir. Projenin gidişatı boyunca "deps" adlı özellikler boyunca yayılır. Bu özellik, bir hedef X oluşturduğundan, A(X) en boy uygulama düğümü elde edilir. Uygulaması sırasında A yönü, X'in "dep"lerinde atıfta bulunduğu tüm hedeflere yinelemeli olarak uygulanır. özelliği (A'nın yayılım listesindeki tüm özellikler).

Bu yüzden, A niteliğini bir hedef X'e uygularken tek bir işlem bir "gölge grafiği" üretir / aşağıda gösterilen hedeflerin orijinal bağımlılık grafiğidir:

En Boy Oranıyla Grafik Oluşturma

Şekil 2. Farklı yönleri olan bir grafik oluşturun.

Gölgelendirilen yalnızca kenarlar, yayılım seti olduğundan runtime_deps kenarı bu örneğine bakalım. Ardından, tablodaki tüm düğümlerde bir en boy uygulama işlevi Düğümlerde kural uygulamalarının çağrılmasına benzer şekilde gölge grafik farklı olabilir.

Basit örnek

Bu örnekte, bir kuralı ve tüm bağımlılıkları deps özelliğine sahiptir. Bu sonuçta özellik uygulaması, en boy tanımı ve hususun nasıl çağrılacağı komutunu çalıştırın.

def _print_aspect_impl(target, ctx):
    # Make sure the rule has a srcs attribute.
    if hasattr(ctx.rule.attr, 'srcs'):
        # Iterate through the files that make up the sources and
        # print their paths.
        for src in ctx.rule.attr.srcs:
            for f in src.files.to_list():
                print(f.path)
    return []

print_aspect = aspect(
    implementation = _print_aspect_impl,
    attr_aspects = ['deps'],
)

Örneği bölümlere ayıralım ve her birini ayrı ayrı inceleyelim.

En boy tanımı

print_aspect = aspect(
    implementation = _print_aspect_impl,
    attr_aspects = ['deps'],
)

En boy tanımları, kural tanımlarına benzer ve aspect işlevini kullanın.

Kural gibi, bir özelliğin de bir uygulama işlevi vardır. Bu örnekte _print_aspect_impl

attr_aspects, özelliğin yayıldığı kural özelliklerinin listesidir. Bu örnekte, boy oranıdeps tüm kuralları oluşturur.

attr_aspects için yaygın olarak kullanılan bir diğer bağımsız değişken de ['*'] bağımsız değişkenidir. Bu bağımsız değişken özelliğini nasıl kullanacağınızı göstereceğim.

Aspect uygulaması

def _print_aspect_impl(target, ctx):
    # Make sure the rule has a srcs attribute.
    if hasattr(ctx.rule.attr, 'srcs'):
        # Iterate through the files that make up the sources and
        # print their paths.
        for src in ctx.rule.attr.srcs:
            for f in src.files.to_list():
                print(f.path)
    return []

Aspect uygulama işlevleri, kural uygulamasına benzer işlevlerine dahildir. Sağlayıcılar döndürürler, işlem yapın ve iki bağımsız değişken alın:

  • target: Özelliğin uygulandığı hedef.
  • ctx: Özelliklere erişmek için kullanılabilecek ctx nesnesi ve çıktılar ile eylemler üretin.

Uygulama işlevi, ctx.rule.attr. Şu anda Google’da çalışan uygulandığı hedef tarafından sağlanır (target bağımsız değişkeni aracılığıyla).

Sağlayıcı listesini döndürmek için özellikler gerekir. Bu örnekte, herhangi bir şey sağlamaz, bu nedenle boş bir liste döndürür.

Komut satırını kullanarak detayı çağırma

Bir özelliği uygulamanın en basit yolu, --aspects bağımsız değişkeninin önüne geçer. Yukarıdaki özelliğin print.bzl adlı bir dosyada tanımlandığı varsayıldığında bu:

bazel build //MyExample:example --aspects print.bzl%print_aspect

print_aspect, example hedefine ve deps özelliği aracılığıyla yinelemeli olarak erişilebilen hedef kuralları.

--aspects işareti bir bağımsız değişken alır. Bu bağımsız değişken, özelliğin özelliği <extension file label>%<aspect top-level name> biçimindedir.

Gelişmiş örnek

Aşağıdaki örnekte, hedef kuraldaki bir özelliğin kullanımı gösterilmektedir , hedeflerdeki dosyaları sayan, potansiyel olarak uzantıları uzantıya göre filtreleyen bir programdır. Değer döndürmek için bir sağlayıcının nasıl kullanılacağını, bir bağımsız değişkeni özellik uygulamasına ve bir kuraldan bir özelliğin nasıl çağrılacağını öğreneceksiniz.

file_count.bzl dosyası:

FileCountInfo = provider(
    fields = {
        'count' : 'number of files'
    }
)

def _file_count_aspect_impl(target, ctx):
    count = 0
    # Make sure the rule has a srcs attribute.
    if hasattr(ctx.rule.attr, 'srcs'):
        # Iterate through the sources counting files
        for src in ctx.rule.attr.srcs:
            for f in src.files.to_list():
                if ctx.attr.extension == '*' or ctx.attr.extension == f.extension:
                    count = count + 1
    # Get the counts from our dependencies.
    for dep in ctx.rule.attr.deps:
        count = count + dep[FileCountInfo].count
    return [FileCountInfo(count = count)]

file_count_aspect = aspect(
    implementation = _file_count_aspect_impl,
    attr_aspects = ['deps'],
    attrs = {
        'extension' : attr.string(values = ['*', 'h', 'cc']),
    }
)

def _file_count_rule_impl(ctx):
    for dep in ctx.attr.deps:
        print(dep[FileCountInfo].count)

file_count_rule = rule(
    implementation = _file_count_rule_impl,
    attrs = {
        'deps' : attr.label_list(aspects = [file_count_aspect]),
        'extension' : attr.string(default = '*'),
    },
)

BUILD.bazel dosyası:

load('//:file_count.bzl', 'file_count_rule')

cc_library(
    name = 'lib',
    srcs = [
        'lib.h',
        'lib.cc',
    ],
)

cc_binary(
    name = 'app',
    srcs = [
        'app.h',
        'app.cc',
        'main.cc',
    ],
    deps = ['lib'],
)

file_count_rule(
    name = 'file_count',
    deps = ['app'],
    extension = 'h',
)

En boy tanımı

file_count_aspect = aspect(
    implementation = _file_count_aspect_impl,
    attr_aspects = ['deps'],
    attrs = {
        'extension' : attr.string(values = ['*', 'h', 'cc']),
    }
)

Bu örnekte, en boy oranının deps özelliği aracılığıyla nasıl yayıldığı gösterilmektedir.

attrs, bir yönle ilgili özellik grubunu tanımlar. Herkese açık özellik özellikleri parametreleri tanımlar ve yalnızca bool, int veya string türünde olabilir. Kural yayılımlı unsurlar için int ve string parametrelerinde Bu öğelerde values belirtilmiş. Bu örnekte extension adlı bir parametre var '*', 'h' veya 'cc' içermesine izin verilen siteler belirtirsiniz.

Kural yayılımlı özellikler için parametre değerleri, istekte bulunan kuraldan alınır. kuralının aynı ada ve türe sahip özelliğini kullanarak en boy oranını girin. (file_count_rule kelimesinin tanımına bakın).

Komut satırı özellikleri için parametre değerleri --aspects_parameters tıklayın. int ve string parametreleri için values kısıtlaması şu olabilir: atlandı.

En boyların label türünde gizli özelliklere de sahip olmasına izin verilir label_list. Özel etiket özellikleri, unsurlarla oluşturulan işlemler için gerekli araçlar veya kitaplıklar bulunur. Yok bu örnekte tanımlanmış bir gizli özellik, ancak aşağıdaki kod snippet'i , aracı belirli bir unsura nasıl iletebileceğinizi gösterir:

...
    attrs = {
        '_protoc' : attr.label(
            default = Label('//tools:protoc'),
            executable = True,
            cfg = "exec"
        )
    }
...

Aspect uygulaması

FileCountInfo = provider(
    fields = {
        'count' : 'number of files'
    }
)

def _file_count_aspect_impl(target, ctx):
    count = 0
    # Make sure the rule has a srcs attribute.
    if hasattr(ctx.rule.attr, 'srcs'):
        # Iterate through the sources counting files
        for src in ctx.rule.attr.srcs:
            for f in src.files.to_list():
                if ctx.attr.extension == '*' or ctx.attr.extension == f.extension:
                    count = count + 1
    # Get the counts from our dependencies.
    for dep in ctx.rule.attr.deps:
        count = count + dep[FileCountInfo].count
    return [FileCountInfo(count = count)]

Tıpkı kural uygulama işlevi gibi, bir görünüm uygulama işlevi de bağımlılıkları tarafından erişilebilen bir sağlayıcı yapısını döndürür.

Bu örnekte FileCountInfo, benzersiz bir hizmet sağlayıcısı olarak tanımlanmış bir sağlayıcı count alanı. En iyi uygulama olarak, bir reklamverenin alanlarını açıkça tanımlamak fields özelliğini kullanan bir sağlayıcıdır.

A(X) en boy uygulaması için sağlayıcı grubu, sağlayıcıların birleşimidir hedefi X için bir kuralın uygulanmasından ve uygulanır. Bir kural uygulamasının yaydığı sağlayıcılar öğeler uygulanmadan önce oluşturulur ve dondurulamaz ve emin olun. Bir hedef ve ona uygulanan bir unsur varsa bu bir hatadır aynı türde bir sağlayıcı sağlayabilir; OutputGroupInfo (birleştirildiği takdirde, kuralı ve en boy oranı farklı çıkış gruplarını belirtir) ve InstrumentedFilesInfo (görüntüyü dikkate alın). Bu, özellik uygulamalarının hiçbir zaman DefaultInfo değerini döndürmez.

Parametreler ve gizli özellikler, ctx Bu örnekte, extension parametresi kullanılmıştır ve sayılacağını unutmayın.

Geri dönen sağlayıcılar için, en boy oranı (attr_aspects listesinden) şununla değiştirilir: uygulamanın sonuçlarını tanımlamasına yardımcı olur. Örneğin, X'in noktalarında Y ve Z değerleri vardır. A(X) için ctx.rule.attr.deps değeri [A(Y), A(Z)] olur. Bu örnekte ctx.rule.attr.deps, en iyi performans gösteren “dep”lere uygulamanın sonuçları orijinal hedefin en boy oranı uygulandı.

Bu örnekte, özellik, FileCountInfo sağlayıcısına şuradan erişiyor: toplam geçişli dosya sayısını biriktirmek için bağımlıların bağımlılıklarını.

Bir kuraldan özellik çağrılıyor

def _file_count_rule_impl(ctx):
    for dep in ctx.attr.deps:
        print(dep[FileCountInfo].count)

file_count_rule = rule(
    implementation = _file_count_rule_impl,
    attrs = {
        'deps' : attr.label_list(aspects = [file_count_aspect]),
        'extension' : attr.string(default = '*'),
    },
)

Kural uygulamasında, FileCountInfo hedefine nasıl erişileceği gösterilmektedir ctx.attr.deps üzerinden.

Kural tanımı, bir parametrenin (extension) nasıl tanımlanacağını gösterir. ve varsayılan bir değer (*) belirleyin. Projenin gidişatı boyunca 'cc', 'h' veya '*' değerlerinden biri değildi en boy tanımındaki parametreye uygulanan kısıtlamalar.

Hedef kuralı aracılığıyla bir özelliği çağırma

load('//:file_count.bzl', 'file_count_rule')

cc_binary(
    name = 'app',
...
)

file_count_rule(
    name = 'file_count',
    deps = ['app'],
    extension = 'h',
)

Bu görselde, extension parametresinin özellik parametresine nasıl iletileceği gösterilmektedir aracılığıyla iletişim kurabilirsiniz. extension parametresinin kuralının uygulanması yerine, extension isteğe bağlı bir parametre olarak kabul edilir.

file_count hedefi oluşturulduğunda, özelliklerimiz şu şekilde değerlendirilir: kendisi ve deps üzerinden yinelemeli olarak erişilebilen tüm hedefler.

Referanslar