Tutorial Bazel: Mem-build Project C++

Laporkan masalah Lihat sumber Per Malam · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Pengantar

Baru mengenal Bazel? Anda sudah berada di tempat yang tepat. Ikuti tutorial Pembuatan Pertama ini untuk mendapatkan pengantar sederhana tentang penggunaan Bazel. Tutorial ini mendefinisikan istilah kunci seperti digunakan dalam konteks Bazel dan memandu Anda memahami dasar-dasar Bazel alur kerja. Dimulai dengan alat yang Anda perlukan, Anda akan membangun dan menjalankan tiga proyek dengan kompleksitas yang meningkat dan mempelajari bagaimana dan mengapa proyek itu menjadi lebih kompleks.

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

Perkiraan waktu penyelesaian: 30 menit.

Prasyarat

Mulailah dengan menginstal Bazel, jika Anda belum melakukannya . Tutorial ini menggunakan Git untuk kontrol sumber, sehingga untuk hasil terbaik instal Git sebagai ya.

Selanjutnya, ambil proyek contoh dari repositori GitHub Bazel dengan menjalankan 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 di bawah ini:

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

Ada tiga kumpulan file, masing-masing kumpulan mewakili satu tahapan dalam tutorial ini. Pada tahap pertama, Anda akan membangun satu target yang berada dalam satu paket. Pada tahap kedua, Anda akan Anda akan membangun sistem biner dan {i>library<i} dari satu paket. Di beberapa tahap ketiga dan terakhir, Anda akan membangun proyek 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 fondasi untuk bangunan pertama Anda dengan Bazel. Lanjutkan ke berikutnya untuk mendefinisikan beberapa istilah dan menyiapkan ruang kerja Anda.

Memulai

Menyiapkan ruang kerja

Sebelum dapat membuat project, Anda perlu menyiapkan ruang kerjanya. Ruang kerja adalah direktori yang menyimpan file sumber proyek Anda dan {i>output<i} build Bazel. Ini juga berisi file-file penting berikut:

  • WORKSPACE file , yang mengidentifikasi direktori dan kontennya sebagai ruang kerja Bazel dan berada di {i>root <i}dari struktur direktori proyek.
  • Satu atau beberapa BUILD files , yang memberi tahu Bazel cara membuat berbagai bagian project. J dalam ruang kerja yang berisi file BUILD adalah paket. (Selengkapnya tentang paket nanti di tutorial ini.)

Dalam proyek yang akan datang, untuk menetapkan direktori sebagai ruang kerja Bazel, buat file kosong bernama WORKSPACE di direktori tersebut. Untuk tujuan tutorial ini, File WORKSPACE sudah ada di setiap tahap.

CATATAN: Saat Bazel membuat project, semua input harus dalam ruang kerja yang sama. File yang berada di ruang kerja berbeda tidak bergantung pada satu sama lain kecuali ditautkan. Informasi lebih mendetail tentang aturan Workspace dapat dapat ditemukan dalam panduan ini.

Memahami file BUILD

File BUILD berisi beberapa jenis petunjuk yang berbeda untuk Bazel. Masing-masing File BUILD memerlukan setidaknya satu aturan sebagai satu set instruksi, yang memberi tahu Bazel cara membuat {i>output<i} yang diinginkan, seperti biner atau library yang dapat dieksekusi. Setiap instance dari aturan build di 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 kita, target hello-world membuat instance bawaan Bazel cc_binary rule. Aturan tersebut memberitahu Bazel untuk membuat biner yang dapat dieksekusi mandiri dari File sumber hello-world.cc tanpa dependensi.

Ringkasan: memulai

Sekarang Anda telah mengenal beberapa istilah kunci, dan apa artinya dalam konteks proyek ini dan Bazel secara umum. Pada bagian berikutnya, Anda akan membangun dan menguji Tahap 1 proyek.

Tahap 1: target tunggal, paket tunggal

Saatnya membangun bagian pertama proyek. Untuk referensi visual, struktur bagian Tahap 1 dari proyek adalah:

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

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

cd cpp-tutorial/stage1

Kemudian jalankan:

bazel build //main:hello-world

Di label target, bagian //main: adalah lokasi file BUILD relatif terhadap root ruang kerja, dan hello-world adalah nama target di 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

Kamu baru saja membuat target Bazel pertama. Menempatkan Bazel membuat output di Direktori bazel-bin di root Workspace.

Sekarang uji biner yang baru Anda bangun, yaitu:

bazel-bin/main/hello-world

Tindakan ini akan menghasilkan pesan “Hello world” yang dicetak.

Berikut adalah grafik dependensi Tahap 1:

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

Ringkasan: tahap 1

Sekarang setelah menyelesaikan bangunan pertama, Anda memiliki ide dasar tentang bagaimana sebuah bangunan adalah data terstruktur. Pada tahap selanjutnya, Anda akan menambahkan kompleksitas dengan target.

Tahap 2: beberapa target build

Meskipun satu target sudah cukup untuk project kecil, sebaiknya Anda membagi proyek yang lebih besar menjadi beberapa target dan paket. Hal ini memungkinkan tambahan – yaitu, Bazel hanya membangun ulang apa yang berubah – dan mempercepat dibangun dengan membangun beberapa bagian proyek sekaligus. Tahap ini tutorial menambahkan target, dan selanjutnya menambahkan paket.

Ini adalah direktori yang sedang Anda gunakan untuk Tahap 2:

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

Lihat di bawah pada file BUILD dalam 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 terlebih dahulu membangun library hello-greet (menggunakan cc_library rule bawaan Bazel), lalu biner hello-world. Atribut deps di target hello-world memberi tahu Bazel bahwa hello-greet library diperlukan untuk membuat biner hello-world.

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

cd ../stage2

Sekarang Anda dapat membangun 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 dibangun, yang menampilkan “Hello world” lain:

bazel-bin/main/hello-world

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

Pada grafik dependensi, Anda dapat melihat bahwa {i> hello-world<i} bergantung pada input yang sama seperti sebelumnya, tetapi struktur build-nya berbeda:

Grafik dependensi untuk `hello-world` menampilkan perubahan struktur setelah file dimodifikasi.

Ringkasan: tahap 2

Sekarang Anda telah membangun proyek dengan dua target. Target hello-world di-build satu file sumber dan bergantung pada satu target lain (//main:hello-greet), yang membangun dua file sumber tambahan. Di bagian berikutnya, lakukan lebih jauh dan menambahkan paket lain.

Tahap 3: beberapa paket

Tahap berikutnya ini menambahkan lapisan detail lain dan membangun project dengan beberapa paket. Lihat di bawah ini struktur dan isi dari Direktori cpp-tutorial/stage3:

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

Anda dapat melihat bahwa sekarang ada dua subdirektori, dan masing-masing berisi BUILD . Oleh karena itu, bagi Bazel, ruang kerja sekarang 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 pada 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 (maka label target //lib:hello-time) - Bazel tahu ini melalui atribut deps. Anda dapat melihatnya di dependensi {i>graphic<i}:

Grafik dependensi untuk `hello-world` menampilkan bagaimana 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 target default hanya terlihat oleh target lain dalam File BUILD. Bazel menggunakan visibilitas target untuk mencegah masalah seperti library berisi detail implementasi yang bocor ke API publik.

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

cd  ../stage3

Sekali lagi, jalankan 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 dalam tutorial ini untuk melihat pesan Hello world akhir:

bazel-bin/main/hello-world

Ringkasan: tahap 3

Anda sekarang telah membangun proyek sebagai dua paket dengan tiga target dan memahami dependensi di antara mereka, yang memungkinkan Anda untuk maju dan membangun masa depan proyek bersama Bazel. Di bagian berikutnya, lihat cara melanjutkan Perjalanan Bazel.

Langkah berikutnya

Anda sekarang telah menyelesaikan build dasar pertama Anda dengan Bazel, tetapi ini hanyalah memulai. Berikut beberapa referensi lainnya untuk melanjutkan pembelajaran dengan Bazel:

Selamat membangun!