İşlevler

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

İçindekiler

paket

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

Bu işlev, paketteki her kural için geçerli olan meta verileri bildirir. Bir pakette (BUILD dosyası) en fazla bir kez kullanılır.

Tüm depodaki her kural için geçerli olan meta verileri bildiren karşı taraf için deponuzun kökündeki REPO.bazel dosyasında repo() işlevini kullanın. repo() işlevi, package() ile aynı bağımsız değişkenleri alır.

package() işlevi, dosyanın en üstündeki tüm load() ifadelerinden hemen sonra ve herhangi bir kuraldan önce çağrılmalıdır.

Bağımsız değişkenler

Özellik Açıklama
default_applicable_licenses

default_package_metadata için diğer ad.

default_visibility

Etiket listesi; varsayılan değer []'dir.

Bu paketteki üst düzey kural hedeflerinin ve sembolik makroların varsayılan görünürlüğü (yani sembolik makro içinde bildirilmemiş olan hedefler ve sembolik makrolar). Hedef veya makro visibility değeri belirtiyorsa bu özellik yoksayılır.

Bu özelliğin söz dizimi hakkında ayrıntılı bilgi için görünürlük dokümanlarına bakın. Paketin varsayılan görünürlüğü, varsayılan olarak herkese açık olan exports_files için geçerli değildir.

default_deprecation

Dize; varsayılan değer ""

Bu paketteki tüm kurallar için varsayılan deprecation mesajını ayarlar.

default_package_metadata

Etiket listesi; varsayılan değer []'dir.

Paketteki diğer tüm hedefler için geçerli olan varsayılan bir meta veri hedefi listesi ayarlar. Bunlar genellikle OSS paketi ve lisans beyanlarıyla ilgili hedeflerdir. Örnekler için rules_license sayfasına bakın.

default_testonly

Boole değeri; belirtilenler hariç varsayılan değer False'dır.

Bu paketteki tüm kurallar için varsayılan testonly özelliğini ayarlar.

javatests altındaki paketlerde varsayılan değer True'dir.

features

Dizeleri listeleme; varsayılan değer []

Bu BUILD dosyasının semantiğini etkileyen çeşitli işaretleri ayarlar.

Bu özellik, öncelikli olarak derleme sistemi üzerinde çalışan kişiler tarafından, özel işlem gerektiren paketleri etiketlemek için kullanılır. Derleme sistemi üzerinde çalışan biri tarafından açıkça istenmediği sürece bunu kullanmayın.

Örnekler

Aşağıdaki beyan, bu paketteki kuralların yalnızca //foo:target paketi grubu üyeleri tarafından görülebileceğini belirtir. Bir kuralda varsa tek tek görünürlük bildirimleri bu spesifikasyonu geçersiz kılar.
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

Bu işlev, bir dizi paket tanımlar ve bu kümeyle bir etiket ilişkilendirir. Etikete visibility özelliklerinde referans verilebilir.

Paket grupları öncelikli olarak görünürlük kontrolü için kullanılır. Herkese açık olarak görünen bir hedef, kaynak ağacındaki her paketten referans alınabilir. Yalnızca kendi paketi (alt paketler değil) içinde özel olarak görünür bir hedefe referans verilebilir. Bu iki uç nokta arasında bir hedef, kendi paketine ve bir veya daha fazla paket grubu tarafından açıklanan paketlerin herhangi birine erişime izin verebilir. Görünürlük sistemi hakkında daha ayrıntılı bilgi için görünürlük özelliğine bakın.

Belirli bir paket, packages özelliğiyle eşleşiyorsa veya includes özelliğinde belirtilen diğer paket gruplarından birinde zaten yer alıyorsa grupta olduğu kabul edilir.

Paket grupları teknik olarak hedeflerdir ancak kurallar tarafından oluşturulmaz ve kendi başlarına görünürlük koruması içermezler.

Bağımsız değişkenler

Özellik Açıklama
name

Ad; zorunlu

Bu hedef için benzersiz bir ad.

packages

Dize listesi; varsayılan değer []'dır.

Sıfır veya daha fazla paket spesifikasyonunun listesi.

Her paket spesifikasyonu dizesi aşağıdaki biçimlerden birine sahip olabilir:

  1. Bir paketin tam adı (deposu olmadan ve çift eğik çizgiyle başlar). Örneğin, //foo/bar, bu ada sahip olan ve paket grubuyla aynı depoda bulunan paketi belirtir.
  2. Yukarıdakiyle aynı ancak sonunda /... var. Örneğin, //foo/..., //foo ve tüm alt paketlerini belirtir. //..., geçerli depodaki tüm paketleri belirtir.
  3. Sırasıyla her paketi veya hiçbir paketi belirtmeyen public ya da private dizeleri. (Bu form için --incompatible_package_group_has_public_syntax işaretinin ayarlanması gerekir.)

Ayrıca, ilk iki tür paket spesifikasyonu, olumsuzlandığını belirtmek için - ile de ön ekli olabilir.

Paket grubu, pozitif spesifikasyonlarından en az biriyle eşleşen ve negatif spesifikasyonlarından hiçbiriyle eşleşmeyen paketleri içerir. Örneğin, [//foo/..., -//foo/tests/...] değeri, //foo'nin //foo/tests'nin de alt paketleri olmayan tüm alt paketlerini içerir. (//foo kendisi dahil edilirken //foo/tests kendisi dahil edilmez.)

Herkese açık görünürlük dışında, mevcut depodaki paketleri doğrudan belirtmenin bir yolu yoktur.

Bu özellik eksikse boş bir listeye ayarlanmış gibi davranır. Bu da yalnızca private içeren bir listeye ayarlanmış gibi davranmakla aynıdır.

Not: Bazel 6.0'dan önce //... spesifikasyonu, public ile aynı olan eski bir davranışa sahipti. Bu davranış, --incompatible_fix_package_group_reporoot_syntax etkinleştirildiğinde düzeltilir. Bu, Bazel 6.0'dan sonraki sürümlerde varsayılan ayardır.

Not: Bazel 6.0'dan önce bu özellik bazel query --output=proto (veya --output=xml) kapsamında serileştirildiğinde baştaki eğik çizgiler atlanıyordu. Örneğin, //pkg/foo/..., \"pkg/foo/...\" olarak çıkış verir. Bu davranış, Bazel 6.0'dan sonra varsayılan olarak etkinleştirilen --incompatible_package_group_includes_double_slash özelliği etkinleştirildiğinde düzeltilir.

includes

Etiket listesi; varsayılan değer []'dir.

Bu pakete dahil olan diğer paket grupları.

Bu özellikteki etiketler, diğer paket gruplarına referans vermelidir. Referans verilen paket gruplarındaki paketlerin bu paket grubunun parçası olduğu kabul edilir. Bu geçişlidir. Paket grubu a, paket grubu b'yi içeriyorsa ve b, paket grubu c'yi içeriyorsa c'deki her paket a'nın da üyesi olur.

Olumsuzlanmış paket spesifikasyonlarıyla birlikte kullanıldığında, her grup için paket kümesinin önce bağımsız olarak hesaplandığını ve sonuçların daha sonra birleştirildiğini unutmayın. Bu, bir gruptaki olumsuzlanan özelliklerin başka bir gruptaki özellikler üzerinde hiçbir etkisi olmadığı anlamına gelir.

Örnekler

Aşağıdaki package_group beyanında, tropikal meyveler içeren "tropical" adlı bir paket grubu belirtiliyor.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

Aşağıdaki beyanlarda kurgusal bir uygulamanın paket grupları belirtilmektedir:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

exports_files

exports_files([label, ...], visibility, licenses)

exports_files(), bu pakete ait olup diğer paketlere aktarılan dosyaların listesini belirtir.

Bir paketin BUILD dosyası, başka bir pakete ait kaynak dosyaları yalnızca exports_files() ifadesiyle açıkça dışa aktarılmışlarsa doğrudan referans verebilir. Dosyaların görünürlüğü hakkında daha fazla bilgi edinin.

Eski bir davranış olarak, bir kurala giriş olarak belirtilen dosyalar da --incompatible_no_implicit_file_export işareti değiştirilene kadar varsayılan görünürlükle dışa aktarılır. Ancak bu davranışa güvenilmemeli ve aktif olarak bu davranıştan uzaklaşılmalıdır.

Bağımsız değişkenler

Bağımsız değişken, geçerli paketteki dosyaların adlarının listesidir. Görünürlük bildirimi de belirtilebilir. Bu durumda dosyalar, belirtilen hedefler tarafından görülebilir. Görünürlük belirtilmezse dosyalar, package işlevinde bir paket varsayılan görünürlüğü belirtilmiş olsa bile her paket tarafından görülebilir. Lisanslar da belirtilebilir.

Örnek

Aşağıdaki örnek, golden.txt adlı metin dosyasını test_data paketinden dışa aktarır. Böylece diğer paketler, örneğin testlerin data özelliğinde bu dosyayı kullanabilir.

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob, belirli yol kalıplarıyla eşleşen tüm dosyaları bulan ve bu dosyaların yollarının yeni, değiştirilebilir ve sıralanmış bir listesini döndüren yardımcı bir işlevdir. Glob yalnızca kendi paketindeki dosyaları arar ve yalnızca kaynak dosyaları (oluşturulan dosyalar veya diğer hedefler değil) arar.

Bir kaynak dosyanın paketle ilgili yolu, include kalıplarından herhangi biriyle eşleşiyor ancak exclude kalıplarından hiçbiriyle eşleşmiyorsa bu dosyanın etiketi sonuca dahil edilir.

include ve exclude listeleri, mevcut pakete göre göreceli olan yol kalıplarını içerir. Her desen bir veya daha fazla yol segmentinden oluşabilir. Unix yollarında olduğu gibi bu segmentler / ile ayrılır. Kalıptaki segmentler, yolun segmentleriyle eşleştirilir. Segmentler, * joker karakterini içerebilir: Bu karakter, dizin ayırıcı / hariç olmak üzere, yol segmentindeki herhangi bir alt dizeyle (boş alt dize bile) eşleşir. Bu joker karakter, bir yol segmentinde birden çok kez kullanılabilir. Ayrıca, ** joker karakteri sıfır veya daha fazla tam yol segmentiyle eşleşebilir ancak bağımsız bir yol segmenti olarak bildirilmelidir.

Örnekler:
  • foo/bar.txt, bu paketteki foo/bar.txt dosyasıyla tam olarak eşleşir (foo/ bir alt paket olmadığı sürece).
  • foo/*.txt, foo/ dizinindeki her dosyayla eşleşir Dosya .txt ile bitiyorsa (foo/ bir alt paket olmadığı sürece)
  • foo/a*.htm*, foo/ dizinindeki a ile başlayan, ardından rastgele bir dize (boş olabilir), ardından .htm ve başka bir rastgele dizeyle biten (foo/ bir alt paket olmadığı sürece) her dosyayla eşleşir. Örneğin, foo/axx.htm ve foo/a.html veya foo/axxx.html
  • foo/*, foo/ dizinindeki her dosyayla eşleşir (foo/ bir alt paket olmadığı sürece); exclude_directories 0 olarak ayarlanmış olsa bile foo diziniyle eşleşmez.
  • foo/**, paketin birinci düzey alt dizini foo/ altındaki her alt paket olmayan alt dizindeki her dosyayla eşleşir; exclude_directories 0 olarak ayarlanırsa foo dizinin kendisi de kalıpla eşleşir; bu durumda **'in sıfır yol segmentiyle eşleştiği kabul edilir.
  • **/a.txt, bu paketin dizinindeki a.txt dosyaları ve alt paket olmayan alt dizinlerle eşleşir.
  • Sonuçtaki yolda en az bir dizin bar olarak adlandırılıyorsa (ör. xxx/bar/yyy/zzz/a.txt veya bar/a.txt) bu paketin alt paket olmayan her alt dizinindeki her **/bar/**/*.txt dosyasıyla eşleşir (**'ın sıfır segmentle de eşleştiğini unutmayın) veya bar/zzz/a.txt.txt
  • **, bu paketin alt paket olmayan her alt dizinindeki her dosyayla eşleşir.
  • foo**/a.txt, geçersiz bir kalıptır. Çünkü **, tek başına bir segment olarak kullanılmalıdır.
  • foo/, /'den sonra tanımlanan ikinci segment boş bir dize olduğu için geçersiz bir kalıptır.

exclude_directories bağımsız değişkeni etkinleştirilirse (1 olarak ayarlanırsa) dizin türündeki dosyalar sonuçlardan çıkarılır (varsayılan 1).

allow_empty bağımsız değişkeni False olarak ayarlanırsa sonuç aksi takdirde boş liste olacağı için glob işlevi hata verir.

Birkaç önemli sınırlama ve uyarı vardır:

  1. glob(), BUILD dosyası değerlendirmesi sırasında çalıştığından, glob() yalnızca kaynak ağacınızdaki dosyaları eşleştirir, oluşturulan dosyaları asla eşleştirmez. Hem kaynak hem de oluşturulmuş dosyalar gerektiren bir hedef oluşturuyorsanız oluşturulmuş dosyaların açık bir listesini glob'a eklemeniz gerekir. :mylib ve :gen_java_srcs ile ilgili aşağıdaki örneğe bakın.

  2. Bir kural, eşleşen bir kaynak dosyayla aynı ada sahipse kural, dosyayı "gölgede bırakır".

    Bunu anlamak için glob() işlevinin bir yol listesi döndürdüğünü unutmayın.Bu nedenle, glob() işlevini diğer kuralların özelliğinde (ör. srcs = glob(["*.cc"])) kullanmak, eşleşen yolları açıkça listelemekle aynı etkiye sahiptir. Örneğin, glob(), ["Foo.java", "bar/Baz.java"] değerini veriyorsa ancak pakette "Foo.java" adlı bir kural da varsa (Bazel bu konuda uyarıda bulunsa da bu kurala izin verilir) glob() tüketicisi, "Foo.java" dosyası yerine "Foo.java" kuralını (çıktılarını) kullanır. Daha fazla bilgi için GitHub sorunu #10395'e göz atın.

  3. Globlar, alt dizinlerdeki dosyalarla eşleşebilir. Alt dizin adları joker karakter içerebilir. Ancak...
  4. Etiketlerin paket sınırını aşmasına izin verilmez ve glob, alt paketlerdeki dosyalarla eşleşmez.

    Örneğin, **/*.cc ifadesi, x paketinde x/y/z.cc ifadesini içermez. Bunun nedeni, x/y ifadesinin paket olarak (x/y/BUILD olarak veya paket yolunda başka bir yerde) bulunmasıdır. Bu, glob ifadesinin sonucunun aslında BUILD dosyalarının varlığına bağlı olduğu anlamına gelir. Başka bir deyişle, x/y adlı bir paket yoksa veya --deleted_packages işareti kullanılarak silinmiş olarak işaretlenmişse aynı glob ifadesi x/y/z.cc'yı içerir.

  5. Yukarıdaki kısıtlama, hangi joker karakterleri kullandıklarına bakılmaksızın tüm glob ifadeleri için geçerlidir.
  6. Dosya adı . ile başlayan gizli bir dosya, hem ** hem de * joker karakterleriyle tamamen eşleşir. Gizli bir dosyayı bileşik desenle eşleştirmek istiyorsanız deseniniz . ile başlamalıdır. Örneğin, * ve .*.txt, .foo.txt ile eşleşir ancak *.txt ile eşleşmez. Gizli dizinler de aynı şekilde eşleştirilir. Gizli dizinler, giriş olarak gerekmeyen dosyalar içerebilir ve gereksiz yere glob'lanmış dosyaların sayısını ve bellek tüketimini artırabilir. Gizli dizinleri hariç tutmak için bunları "exclude" liste bağımsız değişkenine ekleyin.
  7. "**" joker karakterinin bir köşe durumu vardır: "**" deseni, paketin dizin yoluyla eşleşmez. Yani glob(["**"], exclude_directories = 0), mevcut paketin dizininin altında bulunan tüm dosyalarla ve dizinlerle geçişli olarak tam eşleşir (ancak elbette alt paketlerin dizinlerine girmez. Bu konuda önceki nota bakın).

Genel olarak, bir glob deseni için yalnızca "*" kullanmak yerine uygun bir uzantı (ör. *.html) sağlamaya çalışmalısınız. Daha açık bir ad, hem kendi kendini belgeleyen hem de yedekleme dosyalarını veya emacs/vi/... otomatik kaydetme dosyalarını yanlışlıkla eşleştirmenizi önleyen bir addır.

Derleme kuralları yazarken glob'un öğelerini numaralandırabilirsiniz. Bu, örneğin her giriş için ayrı kurallar oluşturulmasını sağlar. Aşağıdaki genişletilmiş glob örneği bölümüne bakın.

Glob Örnekleri

Bu dizindeki tüm Java dosyalarından ve :gen_java_srcs kuralı tarafından oluşturulan tüm dosyalardan oluşturulmuş bir Java kitaplığı oluşturun.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

Dizindeki tüm txt dosyalarını (experimental.txt hariç) testdata dizinine ekleyin. testdata alt dizinlerindeki dosyaların dahil edilmeyeceğini unutmayın. Bu dosyaların dahil edilmesini istiyorsanız yinelemeli glob (**) kullanın.

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

Yinelenen Glob Örnekleri

Testin, testdata dizinindeki ve alt dizinlerindeki (ve bunların alt dizinlerindeki vb.) tüm txt dosyalarına bağlı olmasını sağlayın. BUILD dosyası içeren alt dizinler yoksayılır. (Yukarıdaki sınırlamalar ve uyarılar bölümüne bakın.)

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

Bu dizindeki tüm java dosyalarından ve yolu testing adlı bir dizin içerenler hariç tüm alt dizinlerden oluşan bir kitaplık oluşturun. Bu kalıp, mümkünse kullanılmamalıdır. Çünkü bu kalıp, derleme artımlılığını azaltabilir ve dolayısıyla derleme sürelerini artırabilir.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Genişletilmiş Glob Örnekleri

Geçerli dizinde, dosyadaki satır sayısını hesaplayan *_test.cc için ayrı bir genrule oluşturun.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

Yukarıdaki BUILD dosyası //foo paketindeyse ve paket üç eşleşen dosya (a_test.cc, b_test.cc ve c_test.cc) içeriyorsa bazel query '//foo:all' komutunun çalıştırılması, oluşturulan tüm kuralları listeler:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

seç

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select(), bir kural özelliğini yapılandırılabilir hale getiren yardımcı işlevdir. Neredeyse tüm özellik atamalarının sağ tarafının yerine geçebilir. Bu nedenle değeri, komut satırı Bazel işaretlerine bağlıdır. Örneğin, platforma özgü bağımlılıkları tanımlamak veya bir kuralın "geliştirici" ya da "yayın" modunda oluşturulup oluşturulmadığına bağlı olarak farklı kaynakları yerleştirmek için bu özelliği kullanabilirsiniz.

Temel kullanım şu şekildedir:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

Bu, normal etiket listesi ataması yerine yapılandırma koşullarını eşleşen değerlerle eşleyen bir select çağrısı kullanılarak srcs özelliğinin sh_binary yapılandırılabilir olmasını sağlar. Her koşul, config_setting veya constraint_value için bir etiket referansıdır. Hedefin yapılandırması beklenen bir değer grubuyla eşleşirse koşul "eşleşir". mytarget#srcs değeri, geçerli çağırmayla eşleşen etiket listesi olur.

Notlar:

  • Her çağırmada tam olarak bir koşul seçilir.
  • Birden fazla koşul eşleşiyorsa ve bunlardan biri diğerlerinin uzmanlık alanıysa uzmanlık alanı öncelikli olur. B, A ile aynı işaretlere ve kısıtlama değerlerine sahipse ve bunlara ek olarak bazı işaretler veya kısıtlama değerleri içeriyorsa B koşulu, A koşulunun uzmanlığı olarak kabul edilir. Bu durum, uzmanlık çözünürlüğünün aşağıdaki örnek 2'de gösterildiği gibi bir sıralama oluşturmak üzere tasarlanmadığı anlamına da gelir.
  • Birden fazla koşul eşleşiyorsa ve bunlardan biri diğerlerinin uzmanlık alanı değilse Bazel, tüm koşullar aynı değere çözümlenmediği sürece hata verir.
  • Diğer koşulların eşleşmemesi durumunda özel sahte etiket //conditions:default eşleşmiş kabul edilir. Bu koşul atlanırsa hatayı önlemek için başka bir kuralın eşleşmesi gerekir.
  • select, daha büyük bir özellik atamasının içine yerleştirilebilir. Bu nedenle srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) ve srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) geçerli ifadelerdir.
  • select, çoğu özellikle çalışır ancak bazı özelliklerle çalışmaz. Uyumsuz özellikler, dokümanlarında nonconfigurable olarak işaretlenir.

    alt paketler

    subpackages(include, exclude=[], allow_empty=True)

    subpackages(), glob() işlevine benzer bir yardımcı işlevdir. Dosya ve dizinleri listelemek yerine alt paketleri listeler. glob() ile aynı yol kalıplarını kullanır ve şu anda yüklenen BUILD dosyasının doğrudan alt öğesi olan tüm alt paketlerle eşleşebilir. Dahil etme ve hariç tutma kalıplarıyla ilgili ayrıntılı açıklama ve örnekler için glob sayfasına bakın.

    Döndürülen alt paketlerin listesi sıralı olarak verilir ve include içindeki belirli kalıplarla eşleşen, mevcut yükleme paketine göre göreceli yollar içerir. exclude içindeki yollar dahil edilmez.

    Örnek

    Aşağıdaki örnekte, foo/BUILD paketi için tüm doğrudan alt paketler listelenmektedir.

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/bar/but/bad/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs1 = subpackages(include = ["**"])
    
    # results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    
    subs2 = subpackages(include = ["bar/*"])
    # results in subs2 = ["bar/baz"]
    #
    # Since 'bar' is not a subpackage itself, this looks for any subpackages under
    # all first level subdirectories of 'bar'.
    
    subs3 = subpackages(include = ["bar/**"])
    # results in subs3 = ["bar/baz", "bar/but/bad"]
    #
    # Since bar is not a subpackage itself, this looks for any subpackages which are
    # (1) under all subdirectories of 'bar' which can be at any level, (2) not a
    # subpackage of another subpackages.
    
    subs4 = subpackages(include = ["sub"])
    subs5 = subpackages(include = ["sub/*"])
    subs6 = subpackages(include = ["sub/**"])
    # results in subs4 and subs6 being ["sub"]
    # results in subs5 = [].
    #
    # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
    # subpackage of 'foo').
    # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
    # 'foo/sub' is already a subpackage itself, the subdirectories will not be
    # traversed anymore.
    # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
    # is returned. But the subdirectories of 'foo/sub' will not be traversed
    # anymore.
    

    Genel olarak, bu işlevi doğrudan çağırmak yerine kullanıcıların skylib'in "subpackages" modülünü kullanması tercih edilir.