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

Sorun bildirme Kaynağı görüntüleme Nightly · 7.4 .

Giriş

Bazel'i kullanmaya yeni mi başladınız? Doğru yerdesiniz. Bazel'i kullanmaya yönelik basit bir giriş için bu ilk derleme eğitimini izleyin. Bu eğitimde, Bazel'ın bağlamında kullanılan temel terimler tanımlanıp Bazel iş akışının temel özellikleri açıklanmaktadır. İhtiyacınız olan araçlardan başlayarak, daha karmaşık hale gelen üç 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ğitimde örnek olarak bir C++ projesi kullanılmakta ve çoğu dil için geçerli olan genel yönergeler ve akış sağlanmaktadır.

Tahmini tamamlama süresi: 30 dakika.

Ön koşullar

Henüz yapmadıysanız Bazel'i yükleyerek başlayın. Bu eğiticide kaynak kontrolü için Git kullanıldığından en iyi sonuçlar için Git'i de yükleyin.

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

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

Bu eğitim için örnek proje examples/cpp-tutorial dizinindedir.

Aşağıda, bu raporun 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 paket içinde bulunan tek bir hedef oluşturursunuz. İkinci aşamada tek bir paketten hem ikili program hem de kitaplık oluşturacaksınız. Üçüncü ve son aşamada, birden fazla paket içeren bir proje oluşturacak ve bu projeyi birden fazla hedef için derleyeceksiniz.

Özet: Giriş

Bu eğitim için Bazel'ı (ve Git) yükleyip depoyu klonlayarak Bazel ile ilk derlemenizin temelini atmış oldunuz. Bazı terimleri tanımlamak ve çalışma alanınızı ayarlamak için bir sonraki bölüme geçin.

Başlarken

Çalışma alanını ayarlama

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

  • Dizini ve içeriğini Bazel çalışma alanı olarak tanımlayan ve projenin dizin yapısının kökünde bulunan WORKSPACE file .
  • Bazel'e projenin farklı bölümlerini nasıl oluşturacağını bildiren bir veya daha fazla BUILD files . Çalışma alanındaki BUILD dosyası içeren bir dizin paket olarak adlandırılır. (Paketler hakkında daha fazla bilgiyi bu eğitimde daha sonra bulabilirsiniz.)

Gelecekteki projelerde bir dizini Bazel çalışma alanı olarak belirlemek için söz konusu dizinde WORKSPACE adlı boş bir dosya oluşturun. Bu eğitim kapsamında, her aşamada bir WORKSPACE dosyası zaten mevcuttur.

NOT: Bazel projeyi oluşturduğunda tüm girişlerin aynı çalışma alanında olması gerekir. 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 kılavuzda bulabilirsiniz.

BUILD dosyasını anlama

BUILD dosyası, Bazel için birkaç farklı türde talimat içerir. Her BUILD dosyası, bir dizi talimat olarak en az bir kural gerektirir. Bu kural, Bazel'a yürütülebilir ikili programlar veya kitaplıklar gibi istenen çıkışları nasıl derleyeceğini bildirir. BUILD dosyasında bir derleme kuralının her örneğine hedef denir ve belirli bir kaynak dosya ve bağımlılıklar kümesini işaret eder. Hedefler diğer 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'in yerleşik cc_binary rule öğesini örneklendirir. Kural, Bazel'a hello-world.cc kaynak dosyasından bağımlılık olmadan bağımsız yürütülebilir bir ikili program oluşturmasını söyler.

Özet: Başlarken

Artık bazı temel terimleri ve bu proje ile 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 bölümünü oluşturmanın zamanı geldi. Görsel referans olarak kullanabileceğiniz projenin 1. Aşama bölümünün yapısı:

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

cpp-tutorial/stage1 dizinine taşımak 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 etiketinde //main: kısmı, BUILD dosyasının çalışma alanının köküne göre konumudur ve hello-world, BUILD dosyasındaki hedef addır.

Bazel aşağıdaki gibi bir sonuç oluşturur:

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

Şimdi, yeni derlenen ikili programınızı test edin:

bazel-bin/main/hello-world

Bu işlem, "Hello world" mesajının yazdırılmasına neden olur.

1. Aşama'nın bağımlılık grafiği aşağıda verilmiştir:

Merhaba dünya programının bağımlılık grafiği, tek bir kaynak dosyaya sahip 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. Sonraki aşamada, başka bir hedef ekleyerek karmaşıklığı artıracaksınız.

2. Aşama: Birden fazla derleme hedefi

Küçük projeler için tek bir hedef yeterli olsa da büyük projeleri birden fazla hedefe ve pakete bölmek isteyebilirsiniz. Bu yöntem, artımlı derlemelerin hızlı olmasına olanak tanır. Yani, Bazel yalnızca değişiklikleri yeniden oluşturur. Ayrıca, projenin birden fazla parçasını tek seferde derleyerek derlemelerinizi hızlandırır. Eğiticinin bu aşaması bir hedef, sonraki aşama ise bir paket ekler.

2. Aşama için kullandığınız dizin budur:

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

Aşağıda, 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",
    ],
)

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

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

cd ../stage2

Artık aşağıdaki tanıdık komutu kullanarak yeni ikili dosyayı derleyebilirsiniz:

bazel build //main:hello-world

Bazel yine şuna benzer bir şey oluşturur:

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 yeni oluşturulan ikili dosyanızı test edebilirsiniz. Bu dosya başka bir "Hello world" döndürür:

bazel-bin/main/hello-world

Şimdi hello-greet.cc öğesini değiştirip projeyi yeniden derlerseniz Bazel yalnızca söz konusu dosyayı yeniden derler.

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

"hello-world" için bağımlılık grafiği, dosyadaki değişiklikten sonra yapı değişikliklerini gösterir.

Özet: 2. aşama

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

3. Aşama: Birden fazla paket

Bu sonraki aşamada, karmaşıklık bir kat daha artar ve birden fazla paket içeren bir proje oluşturulur. 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 bir BUILD dosyası içerdiğini görebilirsiniz. Bu nedenle, 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 bağlıdır (bu nedenle hedef etiketi //lib:hello-time). Bazel bunu deps özelliği aracılığıyla bilir. Bu durumu 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'daki //lib:hello-time hedefini main/BUILD'deki hedeflere 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üğünü kullanır.

Şimdi projenin bu son sürümünü derleyin. Şu komutu çalıştırarak cpp-tutorial/stage3 dizinine geçin:

cd  ../stage3

Bir kez daha aşağıdaki komutu çalıştırın:

bazel build //main:hello-world

Bazel aşağıdaki gibi bir sonuç oluşturur:

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ğitimdeki son ikili dosyayı test edin:

bazel-bin/main/hello-world

Özet: 3. aşama

Artık projeyi üç hedefi olan iki paket olarak oluşturdunuz ve aralarındaki bağımlılıkları anladınız. Bu sayede, Bazel ile gelecekteki projeleri oluşturmaya hazırsınız. Bir sonraki bölümde, Basel yolculuğunuza nasıl devam edeceğiniz açıklanmaktadır.

Sonraki adımlar

Bazel ile ilk temel derlemenizi tamamladınız. Ancak bu sadece başlangıç. Bazel ile ilgili daha fazla bilgi edinmek için aşağıdaki kaynaklardan yararlanabilirsiniz:

İyi çalışmalar.