Tutorial Bazel: Mem-build Project C++

Laporkan masalah Lihat sumber Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Pengantar

Baru menggunakan Bazel? Anda berada di tempat yang tepat. Ikuti tutorial First Build ini untuk mendapatkan pengantar yang disederhanakan tentang penggunaan Bazel. Tutorial ini mendefinisikan istilah-istilah penting sebagaimana digunakan dalam konteks Bazel dan memandu Anda mempelajari dasar-dasar alur kerja Bazel. Dimulai dengan alat yang Anda butuhkan, Anda akan membangun dan menjalankan tiga project dengan kompleksitas yang meningkat dan mempelajari cara serta alasan kompleksitasnya meningkat.

Meskipun Bazel adalah sistem build yang mendukung build multi-bahasa, tutorial ini menggunakan project C++ sebagai contoh dan memberikan panduan serta alur umum yang berlaku untuk sebagian besar bahasa.

Estimasi waktu penyelesaian: 30 menit.

Prasyarat

Mulai dengan menginstal Bazel, jika Anda belum melakukannya. Tutorial ini menggunakan Git untuk kontrol sumber, jadi untuk hasil terbaik, instal Git juga.

Selanjutnya, ambil project contoh dari repositori GitHub Bazel dengan menjalankan perintah berikut di alat command line pilihan Anda:

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

Project contoh untuk tutorial ini ada di direktori examples/cpp-tutorial.

Lihat strukturnya:

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

Ada tiga set file, yang masing-masing set mewakili tahap dalam tutorial ini. Pada tahap pertama, Anda akan membuat satu target yang berada dalam satu paket. Pada tahap kedua, Anda akan membuat biner dan library dari satu paket. Pada tahap ketiga dan terakhir, Anda akan membuat project dengan beberapa paket dan membangunnya dengan beberapa target.

Ringkasan: Pengantar

Dengan menginstal Bazel (dan Git) serta meng-clone repositori untuk tutorial ini, Anda telah meletakkan dasar untuk build pertama dengan Bazel. Lanjutkan ke bagian berikutnya untuk menentukan beberapa istilah dan menyiapkan ruang kerja Anda.

Memulai

Sebelum dapat membangun project, Anda harus menyiapkan ruang kerjanya. Ruang kerja adalah direktori yang menyimpan file sumber project dan output build Bazel. Folder ini juga berisi file penting berikut:

  • File MODULE.bazel, yang mengidentifikasi direktori dan isinya sebagai ruang kerja Bazel dan berada di root struktur direktori project. Di sini juga Anda menentukan dependensi eksternal.
  • Satu atau beberapa BUILD file, yang memberi tahu Bazel cara membangun berbagai bagian project. Direktori dalam ruang kerja yang berisi file BUILD adalah paket. (Selengkapnya tentang paket di tutorial ini.)

Pada project mendatang, untuk menetapkan direktori sebagai ruang kerja Bazel, buat file kosong bernama MODULE.bazel di direktori tersebut. Untuk tujuan tutorial ini, file MODULE.bazel sudah ada di setiap tahap.

Memahami file BUILD

File BUILD berisi beberapa jenis petunjuk yang berbeda untuk Bazel. Setiap file BUILD memerlukan setidaknya satu aturan sebagai serangkaian petunjuk, yang memberi tahu Bazel cara membuat output yang Anda inginkan, seperti biner yang dapat dieksekusi atau pustaka. Setiap instance aturan build dalam file BUILD disebut target dan mengarah ke kumpulan file sumber dan dependensi tertentu. Target juga dapat mengarah ke target lain.

Lihat file BUILD di direktori cpp-tutorial/stage1/main:

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

Dalam contoh kami, target hello-world membuat instance aturan cc_binary bawaan Bazel. Aturan ini memberi tahu Bazel untuk membuat program biner yang dapat dieksekusi mandiri dari file sumber hello-world.cc> tanpa dependensi.

Ringkasan: memulai

Sekarang Anda sudah memahami beberapa istilah utama, dan artinya dalam konteks proyek ini dan Bazel secara umum. Di bagian berikutnya, Anda akan membuat dan menguji Tahap 1 project.

Tahap 1: satu target, satu paket

Saatnya membangun bagian pertama proyek. Sebagai referensi visual, struktur bagian Tahap 1 project adalah:

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

Jalankan perintah berikut untuk berpindah ke direktori cpp-tutorial/stage1:

cd cpp-tutorial/stage1

Kemudian jalankan:

bazel build //main:hello-world

Dalam label target, bagian //main: adalah lokasi file BUILD relatif terhadap root ruang kerja, dan hello-world adalah nama target dalam file BUILD.

Bazel menghasilkan sesuatu yang terlihat seperti ini:

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

Anda baru saja membuat target Bazel pertama Anda. Bazel menempatkan output build di direktori bazel-bin di root ruang kerja.

Sekarang, uji biner yang baru Anda buat, yaitu:

bazel-bin/main/hello-world

Hal ini akan menghasilkan pesan "Hello world" yang dicetak.

Berikut grafik dependensi Stage 1:

Grafik dependensi untuk hello-world menampilkan satu target dengan satu file sumber.

Ringkasan: tahap 1

Setelah menyelesaikan build pertama, Anda memiliki ide dasar tentang struktur build. Pada tahap berikutnya, Anda akan menambahkan kompleksitas dengan menambahkan target lain.

Tahap 2: beberapa target build

Meskipun satu target sudah cukup untuk project kecil, Anda mungkin ingin membagi project yang lebih besar menjadi beberapa target dan paket. Hal ini memungkinkan build inkremental yang cepat – yaitu, Bazel hanya membangun ulang apa yang berubah – dan mempercepat build Anda dengan membangun beberapa bagian project sekaligus. Tahap tutorial ini menambahkan target, dan tahap berikutnya menambahkan paket.

Ini adalah direktori yang Anda gunakan untuk Tahap 2:

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

Lihat file BUILD di direktori cpp-tutorial/stage2/main:

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",
    ],
)

Dengan file BUILD ini, Bazel pertama-tama membangun library hello-greet (menggunakan aturan cc_library bawaan Bazel), lalu biner hello-world. Atribut deps di target hello-world memberi tahu Bazel bahwa library hello-greet diperlukan untuk membuat biner hello-world.

Sebelum dapat membuat project versi baru ini, Anda perlu mengubah direktori, beralih ke direktori cpp-tutorial/stage2 dengan menjalankan:

cd ../stage2

Sekarang Anda dapat membangun program biner baru menggunakan perintah yang sudah dikenal berikut:

bazel build //main:hello-world

Sekali lagi, Bazel menghasilkan sesuatu yang terlihat seperti ini:

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

Sekarang Anda dapat menguji biner yang baru saja di-build, yang menampilkan "Hello world" lainnya:

bazel-bin/main/hello-world

Jika Anda sekarang mengubah hello-greet.cc dan membangun ulang project, Bazel hanya mengompilasi ulang file tersebut.

Dengan melihat grafik dependensi, Anda dapat melihat bahwa hello-world bergantung pada input tambahan bernama hello-greet:

Grafik dependensi untuk `hello-world` menampilkan perubahan dependensi setelah
modifikasi pada file.

Ringkasan: tahap 2

Anda kini telah membuat project dengan dua target. Target hello-world membangun satu file sumber dan bergantung pada satu target lain (//main:hello-greet), yang membangun dua file sumber tambahan. Di bagian berikutnya, lanjutkan dan tambahkan paket lain.

Tahap 3: beberapa paket

Tahap berikutnya menambahkan lapisan komplikasi lain dan membangun project dengan beberapa paket. Lihat struktur dan isi direktori cpp-tutorial/stage3:

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

Anda dapat melihat bahwa sekarang ada dua subdirektori, dan masing-masing berisi file BUILD. Oleh karena itu, bagi Bazel, ruang kerja kini berisi dua paket: lib dan main.

Lihat file lib/BUILD:

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

Dan di file main/BUILD:

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",
    ],
)

Target hello-world dalam paket utama bergantung pada target hello-time dalam paket lib (oleh karena itu, label target //lib:hello-time) - Bazel mengetahui hal ini melalui atribut deps. Anda dapat melihatnya tercermin dalam grafik dependensi:

Grafik dependensi untuk `hello-world` menampilkan cara target dalam paket utama bergantung pada target dalam paket `lib`.

Agar build berhasil, Anda membuat target //lib:hello-time di lib/BUILD terlihat secara eksplisit oleh target di main/BUILD menggunakan atribut visibilitas. Hal ini karena secara default target hanya terlihat oleh target lain dalam file BUILD yang sama. Bazel menggunakan visibilitas target untuk mencegah masalah seperti library yang berisi detail implementasi bocor ke API publik.

Sekarang, bangun versi akhir project ini. Beralih ke direktori cpp-tutorial/stage3 dengan menjalankan:

cd  ../stage3

Jalankan kembali perintah berikut:

bazel build //main:hello-world

Bazel menghasilkan sesuatu yang terlihat seperti ini:

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

Sekarang, uji biner terakhir dari tutorial ini untuk mendapatkan pesan Hello world terakhir:

bazel-bin/main/hello-world

Ringkasan: tahap 3

Anda kini telah membangun project sebagai dua paket dengan tiga target dan memahami dependensi di antaranya, yang memungkinkan Anda melanjutkan dan membangun project mendatang dengan Bazel. Di bagian berikutnya, lihat cara melanjutkan perjalanan Bazel Anda.

Langkah berikutnya

Anda kini telah menyelesaikan build dasar pertama dengan Bazel, tetapi ini baru permulaan. Berikut beberapa referensi lainnya untuk melanjutkan pembelajaran dengan Bazel:

Selamat membangun!