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

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

Bazel, diğer projelerdeki hedeflere bağlı olabilir. Bu diğer projelerdeki bağımlılıklara dış bağımlılıklar denir.

Çalışma alanı dizinindeki WORKSPACE dosyası (veya WORKSPACE.bazel dosyası), Bazel'a diğer projelerin kaynaklarını nasıl alacağını söyler. Bu diğer projeler, kendi hedefleri olan bir veya daha fazla BUILD dosyası içerebilir. Ana proje içindeki BUILD dosyaları, WORKSPACE dosyasındaki 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 hedef olan :foo'e bağlı olmak istiyorsa project2 adlı bir deponun /home/user/project2 konumunda bulunabileceğini belirtebilir. Ardından, /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ümlerindeki veya internetten indirilen hedeflere bağlı olmasına olanak tanır. BUILD dosyalarıyla aynı söz dizimini kullanır ancak depo kuralları (bazen çalışma alanı kuralları olarak da bilinir) adı verilen farklı bir kural grubuna izin verir. Bazel'de birkaç yerleşik depo kuralı ve bir dizi yerleştirilmiş Starlark depo kuralı bulunur. 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 harici bağımlılık türü kullanılabilir:

Diğer Bazel projelerine bağlı olma

İkinci bir Bazel projesindeki hedefleri kullanmak istiyorsanız yerel dosya sisteminden sembolik bağlantı oluşturmak, bir Git deposuna referans vermek veya indirmek için (sırasıyla) local_repository, git_repository ya da http_archive kullanabilirsiniz.

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

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

İş arkadaşınızın hedefi //foo:bar ise projeniz bu hedefe @coworkers_project//foo:bar olarak atıfta bulunabilir. Harici proje adları geçerli çalışma alanı adları olmalıdır.

Bazel dışı projelere bağlılık

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

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

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

build_file, mevcut projeye yer paylaşımı olarak eklenecek bir BUILD dosyasını belirtir. Örneğin:

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

Ardından, projenizin @coworkers_project//:some-lib dosyalarından BUILD öğesini kullanabilirsiniz.

Harici paketlere bağlı olma

Maven yapıları ve depoları

Maven depolarından yapıları indirmek ve bunları Java bağımlılıkları olarak kullanıma sunmak için rules_jvm_external kural kümesini kullanın.

Bağımlılıkları getirme

Varsayılan olarak, dış bağımlılıklar bazel build sırasında gerektiğinde getirilir. Belirli bir hedef grubu için gereken bağımlılıkları önceden getirmek istiyorsanız bazel fetch kullanın. Tüm harici bağımlılıkları koşulsuz olarak getirmek için bazel sync kullanın. Getirilen depolar çıkış 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ı kullanmanız önerilir. Bu, derlediğiniz ve nihai ikili dosyanızda yer alan bağımlılıklar için gereklidir. Ancak bu durumun geçerli olmadığı durumlarda bağımlılıkları gölgelemek mümkündür. Aşağıdaki senaryoyu değerlendirin:

myproject/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, testrunner'ye bağlıdır ancak testrunner'nin farklı sürümlerine bağlıdırlar. Bu test çalıştırıcıların myproject içinde sorunsuz bir şekilde birlikte çalışmaması için bir neden yoktur ancak aynı ada sahip olduklarından birbirleriyle çakışırlar. Her iki bağımlılığı da bildirmek 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 farklı adlarla çağrılıyorsa bu bağımlılıklar myproject/WORKSPACE'te birleştirilebilir.

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

Bildirilmiş bir depoyu komut satırından yerel bir depoyla geçersiz kılmak için --override_repository işaretini kullanın. Bu işaretin kullanılması, 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, değişiklikleri daha kolay yapabileceğiniz yerel bir dizine http_archive deposunu geçersiz kılabilirsiniz.
  • Vendoring. Ağ araması yapamayacağınız bir ortamdaysanız ağ tabanlı depo kurallarını geçersiz kılarak bunun yerine yerel dizinleri işaret edin.

Proxy kullanma

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

IPv6 desteği

Yalnızca IPv6'nın kullanıldığı 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/bu adreslere ulaşamadığında) bu durum Network unreachable istisnalarına ve derleme hatalarına neden olabilir. Bu durumlarda, java.net.preferIPv6Addresses=true sistem özelliğini kullanarak Bazel'in davranışını geçersiz kılabilir ve IPv6'yı tercih edebilirsiniz. Ö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ı ekleyin:

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

  • İnternete de bağlanması gereken Java derleme hedefleri çalıştırıyorsanız (bazen entegrasyon testleri için bu gerekir) --jvmopt=-Djava.net.preferIPv6Addresses=true tool flag'i de kullanın. Örneğin, .bazelrc dosyanızda şu satırın bulunması gerekir:

    build --jvmopt=-Djava.net.preferIPv6Addresses

  • Bağımlılık sürümü çözümü için rules_jvm_external kullanıyorsanız COURSIER_OPTS ortam değişkenine -Djava.net.preferIPv6Addresses=true ekleyerek Coursier için JVM seçenekleri de sağlayın.

Geçişli 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ığı listeleyen başka bir projeye (B) bağlıysa hem B hem de C projelerini projenizin WORKSPACE dosyasına eklemeniz gerekir. Bu koşul, WORKSPACE dosya boyutunu artırabilir ancak bir kitaplığın C sürüm 1.0'ı, diğerinin ise C sürüm 2.0'ı içerme olasılığını sınırlar.

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

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

Yeniden indirmeyi zorlamak için bazel sync kullanın.

Düzen

Tüm harici bağımlılıklar, output base içindeki external alt dizininin altındaki bir dizine indirilir. Yerel depo söz konusu olduğunda yeni bir dizin oluşturmak yerine 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 silmeyeceğini unutmayın. Tüm harici öğeleri kaldırmak için bazel clean --expunge simgesini kullanın.

Çevrimdışı derlemeler

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

Gerekli dosyaların bazel'den farklı bir tüzel kişi tarafından sağlanması gereken gerçek çevrimdışı derlemeler için bazel, --distdir seçeneğini destekler. Bir depo kuralı, bazel'den ctx.download veya ctx.download_and_extract aracılığıyla bir dosya getirmesini istediğinde ve gerekli 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 dizinlere bakar ve karma eşleşirse bu yerel kopyayı kullanır.

Bazel, dağıtım yapıtından çevrimdışı olarak başlatmak için bu tekniği kullanır. Bu işlem, gerekli tüm harici bağımlılıkları dahili bir distdir_tar içinde toplayarak yapılır.

Ancak Bazel, ağa bağlanıp bağlanmadıklarını bilmeden, depo kurallarında rastgele komutların yürütülmesine izin verir. Bu nedenle, bazel'de derlemelerin tamamen çevrimdışı olmasını zorunlu kılma seçeneği yoktur. Bu nedenle, bir derlemenin çevrimdışı olarak doğru çalışıp çalışmadığını test etmek için ağın harici olarak engellenmesi gerekir. Bu, bazel'in bootstrap testinde yaptığı gibi bir işlemdir.

En iyi uygulamalar

Depo kuralları

Depo kuralı genellikle şunlardan sorumludur:

  • Sistem ayarlarını algılama ve dosyalara yazma
  • Sistemdeki diğer kaynakları bulma
  • URL'lerden kaynak indirme
  • BUILD dosyalarını oluşturma veya harici depo dizinine sembolik olarak bağlama.

Mümkün olduğunda repository_ctx.execute kullanmaktan kaçının. Örneğin, Make kullanılarak oluşturulmuş bir Bazel harici C++ kitaplığı kullanırken ctx.execute(["make"]) komutunu çalıştırmak yerine repository_ctx.download() komutunu kullanmak ve ardından kitaplığı oluşturan bir BUILD dosyası yazmak tercih edilir.

git_repository ve new_git_repository yerine http_archive tercih edilir. Bunun nedenleri şunlardır:

  • Git deposu kuralları sistem git(1)'ya bağlıyken HTTP indirici Bazel'e yerleştirilmiştir ve sistem bağımlılıkları yoktur.
  • http_archive, yansıtma olarak urls listesini destekler. git_repository ise 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 numaralı makaleyi inceleyin.

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