Bazel Eğitimi: C++ Projesi Oluşturma

Giriş

Bazel'da yeni misiniz? Doğru yerdesiniz. Bazel kullanımına basitleştirilmiş bir giriş için bu İlk Derleme eğiticisini izleyin. Bu eğiticide, anahtar terimlerin Bazel'ın bağlamında nasıl kullanıldığı açıklanmakta ve Bazel iş akışının temelleri konusunda rehberlik sunulmaktadır. İhtiyacınız olan araçlarla işe başlayarak karmaşıklık düzeyi giderek artan üç proje oluşturup yürütecek ve bu projelerin nasıl ve neden daha karmaşık hale geldiğini öğreneceksiniz.

Bazel, çok dilli derlemeleri destekleyen bir derleme sistemi olsa da bu eğitim, örnek olarak bir C++ projesi kullanır ve çoğu dilde geçerli olan genel yönergeleri ve akışı sağlar.

Tahmini tamamlanma süresi: 30 dakika.

Ön koşullar

Henüz yapmadıysanız Bazel'i yükleyerek başlayın. Bu eğitim, kaynak kontrolü için Git'i kullandığından en iyi sonuçları elde etmek için Git'i de yükleyin.

Ardından, istediğiniz komut satırı aracında aşağıdaki komutu çalıştırarak Bazel'in GitHub deposundan örnek projeyi alın:

git clone https://github.com/bazelbuild/examples

Bu eğitim için örnek proje examples/cpp-tutorial dizininde yer alıyor.

Çerçevenin nasıl yapılandırıldığına göz atın:

examples
└── cpp-tutorial
    ├──stage1
    │  ├── main
    │  │   ├── BUILD
    │  │   └── hello-world.cc
    │  └── WORKSPACE
    ├──stage2
    │  ├── main
    │  │   ├── BUILD
    │  │   ├── hello-world.cc
    │  │   ├── hello-greet.cc
    │  │   └── hello-greet.h
    │  └── WORKSPACE
    └──stage3
       ├── main
       │   ├── BUILD
       │   ├── hello-world.cc
       │   ├── hello-greet.cc
       │   └── hello-greet.h
       ├── lib
       │   ├── BUILD
       │   ├── hello-time.cc
       │   └── hello-time.h
       └── WORKSPACE

Her biri bu eğitimdeki bir aşamayı temsil eden üç dosya grubu vardır. İlk aşamada, tek bir pakette yer alan tek bir hedef oluşturursunuz. İkinci aşamada tek bir paketten hem ikili program hem de kitaplık derleyeceksiniz. Üçüncü ve son aşamada birden fazla paket içeren bir proje derleyecek ve birden çok hedefle oluşturacaksınız.

Özet: Giriş

Bazel'ı (ve Git) yükleyip bu eğiticide kullanılan depoyu klonlayarak Bazel ile ilk derlemenizin temelini attınız. Bazı terimler tanımlamak ve çalışma alanınızı ayarlamak için sonraki bölüme geçin.

Başlarken

Çalışma alanını ayarlama

Proje oluşturmadan önce çalışma alanını ayarlamanız gerekir. Çalışma alanı, projenizin kaynak dosyalarını ve Bazel'in derleme çıkışlarını barındıran bir dizindir. Ayrıca, şu önemli dosyaları da içerir:

  • Dizini ve içeriklerini Bazel çalışma alanı olarak tanımlayan ve projenin dizin yapısının kök dizininde çalışan WORKSPACE file .
  • Bazel'a projenin farklı bölümlerini nasıl oluşturacağını bildiren bir veya daha fazla BUILD files . Çalışma alanında bulunan ve BUILD dosyası içeren bir dizin, bir pakettir. (Bu eğiticinin ilerleyen bölümlerinde paketlerle ilgili daha fazla bilgi verilecektir.)

Gelecekteki projelerde bir dizini Bazel çalışma alanı olarak tanımlamak için ilgili dizinde WORKSPACE adlı boş bir dosya oluşturun. Bu eğiticinin amacı doğrultusunda, her aşamada bir WORKSPACE dosyası zaten mevcuttur.

NOT: Bazel projeyi derlerken tüm girişler aynı çalışma alanında olmalıdır. Farklı çalışma alanlarında bulunan dosyalar, bağlanmadıkları sürece birbirinden bağımsızdır. Çalışma alanı kuralları hakkında daha ayrıntılı bilgiyi bu rehberde bulabilirsiniz.

BUILD dosyasını anlama

Bir BUILD dosyası, Bazel için birkaç farklı türde talimat içeriyor. Her BUILD dosyası, talimat kümesi olarak en az bir kural gerektirir. Bu, Bazel'a yürütülebilir ikili programlar veya kitaplıklar gibi istenen çıkışları nasıl derleyeceğini bildirir. BUILD dosyasındaki her derleme kuralı örneğine hedef adı verilir ve belirli bir kaynak dosya ve bağımlılık grubunu işaret eder. Bir hedef, başka hedeflere de işaret edebilir.

cpp-tutorial/stage1/main dizinindeki BUILD dosyasına göz atın:

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
)

Örneğimizde hello-world hedefi, Bazel'ın yerleşik cc_binary rule sürümünü gösterir. Kural, Bazel'a hello-world.cc kaynak dosyasından bağımlılık olmadan bağımsız bir yürütülebilir ikili program oluşturmasını söyler.

Özet: Başlarken

Artık bazı anahtar terimleri ve bu proje ve genel olarak Bazel bağlamında ne anlama geldiklerini biliyorsunuz. Bir sonraki bölümde projenin 1. Aşamasını oluşturup test edeceksiniz.

1. Aşama: tek hedef, tek paket

Projenin ilk kısmını oluşturma zamanı geldi. Görsel referans olması açısından, projenin 1. Aşama bölümü şu şekildedir:

examples
└── cpp-tutorial
    └──stage1
       ├── main
       │   ├── BUILD
       │   └── hello-world.cc
       └── WORKSPACE

cpp-tutorial/stage1 dizinine gitmek için aşağıdaki komutu çalıştırın:

cd cpp-tutorial/stage1

Ardından, şunu çalıştırın:

bazel build //main:hello-world

Hedef etikette, //main: bölümü, BUILD dosyasının çalışma alanı köküne göre konumudur. hello-world, BUILD dosyasındaki hedef addır.

Bazel, aşağıdakine benzer bir şey üretiyor:

INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 2.267s, Critical Path: 0.25s

İlk Bazel hedefinizi oluşturdunuz. Bazel, derleme çıkışlarını çalışma alanının kök kısmındaki bazel-bin dizinine yerleştirir.

Şimdi yeni derlediğiniz ikili programı test edin.

bazel-bin/main/hello-world

Bu işlem, yazdırılan "Hello world" mesajıyla sonuçlanır.

1. Aşamanın bağımlılık grafiği şöyledir:

hello-world'ün bağımlılık grafiği, tek bir kaynak dosyası içeren tek bir hedefi gösterir.

Özet: 1. aşama

Artık ilk derlemenizi tamamladığınıza göre, bir derlemenin nasıl yapılandırıldığına dair temel bir fikriniz var. Sonraki aşamada başka bir hedef ekleyerek karmaşıklığı artırırsınız.

2. Aşama: Birden çok derleme hedefi

Küçük projeler için tek bir hedef yeterli olsa da daha büyük projeleri birden fazla hedefe ve pakete bölmek isteyebilirsiniz. Bu, hızlı artımlı derlemelere olanak tanır, yani Bazel yalnızca yapılan değişiklikleri yeniden oluşturur ve projenin birden fazla bölümünü tek seferde derleyerek yapılarınızı hızlandırır. Eğiticinin bu aşaması bir hedef ekler, sonraki aşamada paket eklenir.

2. Aşama için çalıştığınız dizin aşağıda verilmiştir:

    ├──stage2
    │  ├── main
    │  │   ├── BUILD
    │  │   ├── hello-world.cc
    │  │   ├── hello-greet.cc
    │  │   └── hello-greet.h
    │  └── WORKSPACE

Aşağıdaki cpp-tutorial/stage2/main dizinindeki BUILD dosyasına göz atın:

cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
    ],
)

Bu BUILD dosyasıyla Bazel önce hello-greet kitaplığını (Bazel'ın yerleşik cc_library rule kitaplığını kullanarak) oluşturur, ardından hello-world ikili programını oluşturur. hello-world hedefindeki deps özelliği, Bazel'a hello-world ikili programını oluşturmak için hello-greet kitaplığının gerekli olduğunu bildirir.

Projenin bu yeni sürümünü derlemeden önce dizinleri değiştirmeniz ve aşağıdaki komutu çalıştırarak cpp-tutorial/stage2 dizinine geçmeniz gerekir:

cd ../stage2

Artık aşağıdaki bilindik komutu kullanarak yeni ikili programı oluşturabilirsiniz:

bazel build //main:hello-world

Bir kez daha, Bazel şuna benzer bir şey oluşturuyor:

INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 2.399s, Critical Path: 0.30s

Artık başka bir "Hello world" döndüren yeni derlenmiş ikili programınızı test edebilirsiniz:

bazel-bin/main/hello-world

Şimdi hello-greet.cc üzerinde değişiklik yapar ve projeyi yeniden derlerseniz Bazel yalnızca bu dosyayı yeniden derler.

Bağımlılık grafiğine baktığınızda hello-world'ün öncekiyle aynı girişlere bağlı olduğunu görebilirsiniz, ancak derlemenin yapısı farklıdır:

"hello-world"ün bağımlılık grafiği, dosyada değişiklik yapıldıktan sonra yapı değişikliklerini görüntüler.

Özet: 2. aşama

Artık projeyi iki hedefle oluşturdunuz. hello-world hedefi, bir kaynak dosya oluşturur ve iki ek kaynak dosya oluşturan bir hedefe (//main:hello-greet) bağlıdır. Bir sonraki bölümde, bunu bir adım ileriye giderek başka bir paket ekleyin.

3. Aşama: Birden fazla paket

Bu aşama, bir komplikasyon katmanı daha ekler ve birden fazla paket içeren bir proje oluşturur. cpp-tutorial/stage3 dizininin yapısını ve içeriğini aşağıda görebilirsiniz:

└──stage3
   ├── main
   │   ├── BUILD
   │   ├── hello-world.cc
   │   ├── hello-greet.cc
   │   └── hello-greet.h
   ├── lib
   │   ├── BUILD
   │   ├── hello-time.cc
   │   └── hello-time.h
   └── WORKSPACE

Artık iki alt dizin olduğunu ve her birinin birer BUILD dosyası içerdiğini görebilirsiniz. Bu nedenle, Bazel için çalışma alanı artık iki paket içeriyor: lib ve main.

lib/BUILD dosyasına göz atın:

cc_library(
    name = "hello-time",
    srcs = ["hello-time.cc"],
    hdrs = ["hello-time.h"],
    visibility = ["//main:__pkg__"],
)

main/BUILD dosyasında:

cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
        "//lib:hello-time",
    ],
)

Ana paketteki hello-world hedefi, lib paketindeki hello-time hedefine (dolayısıyla //lib:hello-time hedef etiketi) bağlıdır. Bazel, bunu deps özelliği aracılığıyla bilir. Bağımlılık grafiğinde bunun yansıdığını görebilirsiniz:

"hello-world"ün bağımlılık grafiği, ana paketteki hedefin "lib" paketindeki hedefe nasıl bağlı olduğunu gösterir.

Derlemenin başarılı olması için, visibility özelliğini kullanarak lib/BUILD bölgesindeki //lib:hello-time hedefini main/BUILD bölgesindeki hedefler tarafından açıkça görülebilecek şekilde ayarlarsınız. Bunun nedeni, varsayılan olarak hedeflerin yalnızca aynı BUILD dosyasındaki diğer hedefler tarafından görülebilmesidir. Bazel, uygulama ayrıntılarını içeren kitaplıkların herkese açık API'lere sızması gibi sorunları önlemek için hedef görünürlüğü kullanır.

Şimdi projenin bu son sürümünü oluşturun. Aşağıdaki komutu çalıştırarak cpp-tutorial/stage3 dizinine geçin:

cd  ../stage3

Aşağıdaki komutu tekrar çalıştırın:

bazel build //main:hello-world

Bazel, aşağıdakine benzer bir şey üretiyor:

INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s

Şimdi bu eğiticinin son ikili programını son Hello world mesajı için test edin:

bazel-bin/main/hello-world

Özet: 3. aşama

Artık projeyi üç hedef içeren iki paket halinde derlediniz ve bu paketler arasındaki bağımlılıkları anladınız. Bu da size Bazel ile devam edip gelecek projeler üretmenizi sağlayacak. Bir sonraki bölümde, Bazel yolculuğunuza nasıl devam edeceğinize bakacağız.

Sonraki adımlar

Artık Bazel ile ilk temel derlemenizi tamamladınız, ancak bu daha başlangıç. Bazel ile öğrenmeye devam etmek için kullanabileceğiniz diğer kaynakları aşağıda bulabilirsiniz:

Kolay gelsin!