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

Sorun bildir Kaynağı göster

Giriş

Bazel'i ilk kez mi kullanıyorsunuz? Doğru yerdesiniz. Bazel kullanmaya basitleştirilmiş bir giriş için bu İlk Derleme eğiticisini izleyin. Bu eğiticide, anahtar terimlerin Bazel bağlamında nasıl kullanıldığı açıklanmakta ve Bazel iş akışının temelleri açıklanmaktadır. İhtiyaç duyduğunuz araçlardan başlayarak karmaşıklığı artan üç proje oluşturup yürütecek ve bunların nasıl ve neden daha karmaşık hale geldiğini öğreneceksiniz.

Bazel, çok dilli derlemeleri destekleyen bir derleme sistemi olsa da bu eğiticide örnek olarak bir C++ projesi kullanılmıştır ve çoğu dil için geçerli olan genel kurallar ve akış sağlanır.

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ı almak için Git'i de yükleyin.

Ardından, istediğiniz komut satırı aracında aşağıdaki kodu ç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 dizinindedir.

İşleyiş şeklini aşağıda görebilirsiniz:

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 bulunan tek bir hedef oluşturursunuz. İkinci aşamada tek bir paketten hem ikili program hem de kitaplık derleyeceksiniz. Üçüncü ve son aşamada ise birden fazla paket içeren bir proje hazırlayacak ve bu projeyi birden fazla hedefle hazırlayacaksınız.

Özet: Giriş

Bazel'i (ve Git'i) yükleyip bu eğitim için 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.

Kullanmaya başlama

Çalışma alanını ayarlama

Bir proje derlemeden ö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 bulunan WORKSPACE file .
  • Bazel'a projenin farklı bölümlerini nasıl kuracağını anlatan 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 bulabilirsiniz.)

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 grubu 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 bir derleme kuralının her örneği hedef olarak adlandırılır ve belirli bir kaynak dosya grubuna ve bağımlılıklara işaret eder. Bir hedef, başka hedefleri de gösterebilir.

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 uygulamasını örneklendirir. Kural, Bazel'a hello-world.cc kaynak dosyasından herhangi bir bağımlılık olmadan bağımsız bir yürütülebilir ikili program oluşturmasını bildirir.

Özet: Başlarken

Bazı anahtar terimleri ve bu terimlerin genel olarak bu proje ve Bazel bağlamında ne anlama geldiğini biliyorsunuz. Bir sonraki bölümde projenin 1. Aşamasını oluşturacak ve test edeceksiniz.

1. Aşama: tek hedef, tek paket

Şimdi projenin ilk kısmını oluşturma zamanı. 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, şu komutu çalıştırın:

bazel build //main:hello-world

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

Bazel şuna benzeyen bir şey üretir:

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 dizinindeki bazel-bin dizinine yerleştirir.

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

bazel-bin/main/hello-world

Bu işlem sonucunda "Hello world" mesajı yazdırılır.

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

hello-world için bağımlılık grafiği, tek bir kaynak dosyası içeren tek bir hedef gösterir.

Özet: 1. aşama

İlk derlemenizi tamamladığınıza göre artık bir derlemenin nasıl yapılandırıldığına dair temel bir fikriniz var. Bir sonraki aşamada, başka bir hedef ekleyerek karmaşıklığı ekleyeceksiniz.

2. Aşama: Birden çok derleme hedefi

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

2. Aşama için çalıştığınız dizin şudur:

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

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 uygulaması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 tanıdık komutu kullanarak yeni ikili programı derleyebilirsiniz:

bazel build //main:hello-world

Yine, Bazel şuna benzeyen bir şey üretir:

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 dosyasını değiştirir ve projeyi yeniden oluşturursanız Bazel yalnızca bu dosyayı yeniden derler.

Bağımlılık grafiğine baktığınızda hello-world değerinin hello-greet adlı fazladan bir girişe bağlı olduğunu görebilirsiniz:

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

Özet: 2. aşama

Projeyi iki hedefle oluşturdunuz. hello-world hedefi, bir kaynak dosyası oluşturur ve iki ek kaynak dosya oluşturan bir diğer hedefe (//main:hello-greet) bağlıdır. Bir sonraki bölümde işlemi bir adım daha ileri götürüp başka bir paket ekleyin.

3. Aşama: Birden fazla paket

Bu sonraki aşama, bir komplikasyon katmanı daha ekler ve birden çok paket içeren bir proje oluşturur. cpp-tutorial/stage3 dizininin yapısına ve içeriğine aşağıdan göz atın:

└──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. Dolayısıyla Bazel'e göre ç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. Bunu bağımlılık grafiğinde görebilirsiniz:

"hello-world" için 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 görünürlük özelliğini kullanarak lib/BUILD bölgesindeki //lib:hello-time hedefini main/BUILD bölgesindeki hedefler tarafından açıkça görünür hale getirirsiniz. Bunun nedeni, hedeflerin varsayılan olarak 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. Şu 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 şuna benzeyen bir şey üretir:

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, son Hello world mesajı için bu eğitimin son ikili programını test edin:

bazel-bin/main/hello-world

Özet: 3. aşama

Artık projeyi üç hedef içeren iki paket halinde oluşturdunuz ve bunlar arasındaki bağımlılıkları anladınız. Bu sayede, Bazel ile devam edip gelecek projeler oluşturabilirsiniz. Bir sonraki bölümde, Bazel yolculuğunuza nasıl devam edeceğinize göz atalım.

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 aşağıdaki diğer kaynakları kullanabilirsiniz:

Kolay gelsin!