Dış Bağımlılıklarla Çalışma

Sorun bildirme Kaynağı görüntüleme Nightly · 8.0 . 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel, diğer projelerdeki hedeflere bağlı olabilir. Bu diğer projelerden gelen bağımlılıklara harici bağımlılıklar denir.

Çalışma alanı dizininde bulunan WORKSPACE dosyası (veya WORKSPACE.bazel dosyası), Bazel'e diğer projelerin kaynaklarını nasıl alacağını söyler. Bu diğer projeler, kendi hedeflerine sahip bir veya daha fazla BUILD dosyası içerebilir. Ana projedeki BUILD dosyaları, WORKSPACE dosyasından adlarını kullanarak bu harici hedeflere bağlı olabilir.

Örneğin, bir sistemde iki proje olduğunu varsayalım:

/
  home/
    user/
      project1/
        WORKSPACE
        BUILD
        srcs/
          ...
      project2/
        WORKSPACE
        BUILD
        my-libs/

project1, /home/user/project2/BUILD içinde tanımlanan bir hedefe (:foo) bağlı olmak isterse project2 adlı bir deposunun /home/user/project2 adresinde bulunabileceğini belirtebilir. Bu durumda, /home/user/project1/BUILD içindeki hedefler @project2//:foo'e bağlı olabilir.

WORKSPACE dosyası, kullanıcıların dosya sisteminin diğer bölümlerinden veya internetten indirilen hedeflere bağlı olmasına olanak tanır. BUILD dosyalarıyla aynı söz dizimi kullanılır ancak depo kuralları (bazen çalışma alanı kuralları olarak da bilinir) adlı farklı bir kural grubuna izin verilir. Bazel, birkaç yerleşik depo kuralıyla ve bir dizi yerleşik Starlark depo kuralıyla birlikte gelir. Kullanıcılar daha karmaşık davranışlar elde etmek için özel depo kuralları da yazabilir.

Desteklenen harici bağımlılık türleri

Birkaç temel türde harici bağımlılık kullanılabilir:

Diğer Bazel projelerine bağlı olarak

İkinci bir Bazel projesindeki hedefleri kullanmak istiyorsanız local_repository, git_repository veya http_archive simgesini kullanarak yerel dosya sisteminden simge bağlantısı oluşturabilir, bir git deposuna referans verebilir ya da dosyayı indirebilirsiniz (sırasıyla).

Örneğin, my-project/ adlı bir proje üzerinde çalıştığınızı ve iş arkadaşınızın coworkers-project/ adlı projesindeki hedeflere bağlı olmak istediğinizi varsayalım. Her iki proje de Bazel kullandığından iş arkadaşınızın projesini harici bir bağımlılık olarak ekleyebilir ve ardından iş arkadaşınızın kendi BUILD dosyalarınızdan tanımladığı tüm hedefleri kullanabilirsiniz. my_project/WORKSPACE alanına aşağıdakileri ekleyebilirsiniz:

local_repository(
    name = "coworkers_project",
    path = "/path/to/coworkers-project",
)

İş arkadaşınızın //foo:bar hedefi varsa projeniz bu hedefi @coworkers_project//foo:bar olarak referans alabilir. Harici proje adları geçerli çalışma alanı adları olmalıdır.

Bazel dışı projelere bağlı olarak

new_ ile başlayan kurallar (ör. new_local_repository), Bazel kullanmayan projelerden hedef oluşturmanıza olanak tanır.

Örneğin, my-project/ adlı bir proje üzerinde çalıştığınızı ve iş arkadaşınızın coworkers-project/ adlı projesine bağlı olmak istediğinizi varsayalım. İş arkadaşınızın projesi derleme için make kullanıyor ancak siz, oluşturduğu .so dosyalarından birine bağımlı olmak istiyorsunuz. Bunun için my_project/WORKSPACE alanına aşağıdakileri ekleyin:

new_local_repository(
    name = "coworkers_project",
    path = "/path/to/coworkers-project",
    build_file = "coworker.BUILD",
)

build_file, mevcut projenin üzerine yerleştirilecek bir BUILD dosyası belirtir. Örneğin:

cc_library(
    name = "some-lib",
    srcs = glob(["**"]),
    visibility = ["//visibility:public"],
)

Ardından, projenizin BUILD dosyalarındaki @coworkers_project//:some-lib dosyalarını kullanabilirsiniz.

Harici paketlere bağlı olarak

Maven yapıları ve depoları

Maven depolarından yapıları indirip Java bağımlılıkları olarak kullanılabilir hâle getirmek için rules_jvm_external kural kümesini kullanın.

Bağımlılıkları getirme

Varsayılan olarak, harici bağımlılıklar bazel build sırasında gerektiği şekilde getirilir. Belirli bir hedef grubu için gereken bağımlılıkları önceden almak istiyorsanız bazel fetch kullanın. Tüm harici bağımlılıkları koşulsuz olarak getirmek için bazel sync değerini kullanın. Getirilen depolar çıktı tabanında depolandığından getirme işlemi çalışma alanı başına gerçekleşir.

Gölgeleme bağımlılıkları

Mümkün olduğunda projenizde tek bir sürüm politikası belirlemeniz önerilir. Bu, derlediğiniz ve nihai ikili dosyanızda yer alan bağımlılar için gereklidir. Ancak bunun geçerli olmadığı durumlarda bağımlılıkları gölgelemek mümkündür. Aşağıdaki senaryoyu değerlendirin:

projem/WORKSPACE

workspace(name = "myproject")

local_repository(
    name = "A",
    path = "../A",
)
local_repository(
    name = "B",
    path = "../B",
)

A/WORKSPACE

workspace(name = "A")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner",
    urls = ["https://github.com/testrunner/v1.zip"],
    sha256 = "...",
)

B/WORKSPACE

workspace(name = "B")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner",
    urls = ["https://github.com/testrunner/v2.zip"],
    sha256 = "..."
)

Hem A hem de B bağımlılıkları testrunner'ye bağlıdır ancak testrunner'nin farklı sürümlerine bağlıdır. Bu test çalıştırıcılarının myproject içinde barış içinde birlikte yaşamaları için bir neden yoktur. Ancak aynı ada sahip olduklarından birbirleriyle çakışırlar. Her iki bağımlılığı da beyan etmek için myproject/WORKSPACE dosyasını güncelleyin:

workspace(name = "myproject")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner-v1",
    urls = ["https://github.com/testrunner/v1.zip"],
    sha256 = "..."
)
http_archive(
    name = "testrunner-v2",
    urls = ["https://github.com/testrunner/v2.zip"],
    sha256 = "..."
)
local_repository(
    name = "A",
    path = "../A",
    repo_mapping = {"@testrunner" : "@testrunner-v1"}
)
local_repository(
    name = "B",
    path = "../B",
    repo_mapping = {"@testrunner" : "@testrunner-v2"}
)

Bu mekanizma, elmasları birleştirmek için de kullanılabilir. Örneğin, A ve B aynı bağımlılığa sahipse ancak bu bağımlılığı farklı adlarla çağırıyorsa bu bağımlılıklar projem/WORKSPACE içinde birleştirilebilir.

Depoları komut satırından geçersiz kılma

Komut satırından, bildirilen bir deposu yerel bir depoyla geçersiz kılmak için --override_repository işaretini kullanın. Bu işareti kullanmak, kaynak kodunuzu değiştirmeden harici depoların içeriğini değiştirir.

Örneğin, @foo değerini yerel dizin /path/to/local/foo ile geçersiz kılmak için --override_repository=foo=/path/to/local/foo işaretini iletin.

Bazı kullanım alanları şunlardır:

  • Sorunları ayıklama Örneğin, http_archive deposunu, değişiklikleri daha kolay yapabileceğiniz yerel bir dizinle geçersiz kılabilirsiniz.
  • Tedarikçi firma Ağ çağrısı yapamadığınız bir ortamdaysanız ağ tabanlı depolama alanı kurallarını geçersiz kılıp yerel dizinleri işaret edecek şekilde değiştirin.

Proxy kullanma

Bazel, HTTPS_PROXY ve HTTP_PROXY ortam değişkenlerinden proxy adreslerini alır ve HTTP/HTTPS dosyalarını indirmek için (belirtilmişse) bunları kullanır.

IPv6 desteği

Yalnızca IPv6 kullanan makinelerde Bazel, bağımlılıkları herhangi bir değişiklik yapmadan indirebilir. Ancak çift yığınlı IPv4/IPv6 makinelerde Bazel, Java ile aynı kuralı izler: IPv4 etkinse IPv4 tercih edilir. Bazı durumlarda (ör. IPv4 ağı harici adresleri çözemediğinde/buralara ulaşamadığında) bu durum Network unreachable istisnalarına ve derleme hatalarına neden olabilir. Bu gibi durumlarda, java.net.preferIPv6Addresses=true sistem mülkünü kullanarak Bazel'in IPv6'yı tercih etme davranışını geçersiz kılabilirsiniz. Özellikle:

  • --host_jvm_args=-Djava.net.preferIPv6Addresses=true Başlatma seçeneğini kullanın. Örneğin, .bazelrc dosyanıza aşağıdaki satırı ekleyerek:

    startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true

  • İnternete de bağlanması gereken Java derleme hedefleri çalıştırıyorsanız (entegrasyon testleri bazen buna ihtiyaç duyar) --jvmopt=-Djava.net.preferIPv6Addresses=true araç işaretini de kullanın. Örneğin, .bazelrc dosyanızda şu satırı ekleyin:

    build --jvmopt=-Djava.net.preferIPv6Addresses

  • rules_jvm_external kullanıyorsanız (ör. bağımlılık sürümü çözümü için) Coursier için JVM seçenekleri sağlamak amacıyla COURSIER_OPTS ortam değişkenine -Djava.net.preferIPv6Addresses=true de ekleyin.

Geçiş bağımlılıkları

Bazel yalnızca WORKSPACE dosyanızda listelenen bağımlılıkları okur. Projeniz (A), WORKSPACE dosyasında üçüncü bir projeye (C) bağımlılığını listeleyen başka bir projeye (B) bağlıysa hem B hem de C dosyasını projenizin WORKSPACE dosyasına eklemeniz gerekir. Bu şart, WORKSPACE dosya boyutunu artırabilir ancak bir kitaplığın 1.0 sürümünde C, diğerinin ise 2.0 sürümünde C içerme olasılığını sınırlandırır.

Harici bağımlılıkların önbelleğe alınması

Varsayılan olarak Bazel, harici bağımlılıkları yalnızca tanımları değişirse yeniden indirir. Tanımda atıfta bulunulan dosyalarda yapılan değişiklikler (yamalar veya BUILD dosyaları gibi) bazel tarafından da dikkate alınır.

Yeniden indirme işlemini zorlamak için bazel sync simgesini kullanın.

Düzen

Harici bağımlılıkların tümü, çıktı tabanında external alt dizininin altındaki bir dizine indirilir. Yerel depo söz konusu olduğunda, yeni bir dizin yerine burada bir sembolik bağlantı oluşturulur. Aşağıdaki komutu çalıştırarak external dizinini görebilirsiniz:

ls $(bazel info output_base)/external

bazel clean komutunun çalıştırılmasının harici dizini gerçekten silmediğini unutmayın. Tüm harici yapıları kaldırmak için bazel clean --expunge simgesini kullanın.

Çevrimdışı derlemeler

Bazen bir derlemeyi çevrimdışı olarak çalıştırmak istenebilir veya gerekli olabilir. Uçakla seyahat etmek gibi basit kullanım alanları için bazel fetch veya bazel sync ile gerekli depoları prefetching yeterli olabilir. Ayrıca, --nofetch seçeneği kullanılarak derleme sırasında başka depoların getirilmesi devre dışı bırakılabilir.

Gerekli dosyaların bazel'den farklı bir varlık tarafından sağlanacağı gerçek çevrimdışı derlemeler için bazel, --distdir seçeneğini destekler. Bir depo kuralı, bazel'den ctx.download veya ctx.download_and_extract üzerinden bir dosya getirmesini istediğinde ve gereken dosyanın karma toplamını sağladığında bazel, önce sağlanan ilk URL'nin temel adıyla eşleşen bir dosya için bu seçenekle belirtilen dizinleri arar ve karma eşleşirse bu yerel kopyayı kullanır.

Bazel de dağıtım yapısını kullanarak çevrimdışı önyükleme yapmak için bu tekniği kullanır. Bunu, gerekli tüm harici bağımlılıkları dahili bir distdir_tar içinde toplayarak yapar.

Ancak bazel, ağa çağrı yapıp yapmadıklarını bilmeden depo kurallarında keyfi komutların yürütülmesine izin verir. Bu nedenle bazel, derlemelerin tamamen çevrimdışı olmasını zorunlu kılma seçeneği sunmaz. Bu nedenle, bir derlemenin çevrimdışı olarak düzgün çalışıp çalışmadığını test etmek için ağın harici olarak engellenmesi gerekir (bazel'in önyükleme testinde yaptığı gibi).

En iyi uygulamalar

Depo kuralları

Depo kuralları genellikle aşağıdakilerden sorumludur:

  • Sistem ayarlarını algılama ve dosyalar halinde yazma
  • Sistemde başka yerlerdeki kaynakları bulma
  • URL'lerden kaynak indirme
  • Harici depolama alanı dizininde BUILD dosyaları oluşturma veya bu dosyalara simge bağlantısı oluşturma.

Mümkünse repository_ctx.execute kullanmamaya çalışın. Örneğin, Make'i kullanan bir derleme içeren Bazel dışı bir C++ kitaplığı kullanırken ctx.execute(["make"]) çalıştırmak yerine repository_ctx.download()'ü kullanmak ve ardından derlemeyi yapan bir BUILD dosyası yazmak tercih edilir.

git_repository ve new_git_repository yerine http_archive seçeneğini tercih edin. Bunun nedenleri şunlardır:

  • Git deposu kuralları sisteme bağlıdır git(1), ancak HTTP indirici Bazel'e yerleştirilmiştir ve sistem bağımlılığı yoktur.
  • http_archive, ayna olarak urls listesini destekler ve git_repository yalnızca tek bir remote'ı destekler.
  • http_archive, depo önbelleği ile çalışır ancak git_repository ile çalışmaz. Daha fazla bilgi için #5116 konusuna bakın.

bind() kullanmayın. Sorunları ve alternatifleri hakkında ayrıntılı bilgi için "Bağlantıyı kaldırmayı düşünün" bölümüne bakın.