บทนำ
หากเพิ่งเริ่มใช้ Bazel คุณมาถูกที่แล้ว ดูบทแนะนำการสร้างครั้งแรกนี้เพื่อทำความเข้าใจการใช้ Bazel แบบง่ายๆ บทแนะนำนี้จะให้คำจำกัดความของคำสำคัญตามที่ใช้ในบริบทของ Bazel และแนะนำพื้นฐานของเวิร์กโฟลว์ Bazel คุณจะสร้างและเรียกใช้โปรเจ็กต์ 3 รายการที่มีความซับซ้อนเพิ่มขึ้นเรื่อยๆ โดยเริ่มจากเครื่องมือที่จำเป็น และเรียนรู้ว่าโปรเจ็กต์เหล่านี้ซับซ้อนขึ้นได้อย่างไรและเพราะเหตุใด
แม้ว่า Bazel จะเป็นระบบบิลด์ที่รองรับบิลด์หลายภาษา แต่บทแนะนำนี้จะใช้โปรเจ็กต์ C++ เป็นตัวอย่าง และให้คำแนะนำและขั้นตอนทั่วไปที่ใช้ได้กับภาษาส่วนใหญ่
เวลาที่ใช้โดยประมาณ: 30 นาที
ข้อกำหนดเบื้องต้น
เริ่มต้นด้วยการติดตั้ง Bazel หากยังไม่ได้ติดตั้ง บทแนะนำนี้ใช้ Git สำหรับการควบคุมแหล่งที่มา ดังนั้นเพื่อผลลัพธ์ที่ดีที่สุด โปรดติดตั้ง Git ด้วย
จากนั้นเรียกข้อมูลโปรเจ็กต์ตัวอย่างจากที่เก็บ GitHub ของ Bazel โดยเรียกใช้คำสั่งต่อไปนี้ในเครื่องมือบรรทัดคำสั่งที่คุณเลือก
git clone https://github.com/bazelbuild/examples
โปรเจ็กต์ตัวอย่างสำหรับบทแนะนำนี้อยู่ในไดเรกทอรี examples/cpp-tutorial
ดูโครงสร้างของข้อมูลด้านล่าง
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
มีไฟล์ 3 ชุด โดยแต่ละชุดแสดงถึงขั้นตอนในบทแนะนำนี้ ในระยะแรก คุณจะสร้างเป้าหมายเดียวที่อยู่ในแพ็กเกจเดียว ในขั้นตอนที่ 2 คุณจะ สร้างทั้งไบนารีและไลบรารีจากแพ็กเกจเดียว ใน ขั้นตอนที่ 3 ซึ่งเป็นขั้นตอนสุดท้าย คุณจะสร้างโปรเจ็กต์ที่มีหลายแพ็กเกจและ สร้างด้วยหลายเป้าหมาย
สรุป: บทนำ
การติดตั้ง Bazel (และ Git) และการโคลนที่เก็บสำหรับบทแนะนำนี้เป็นการวางรากฐานสำหรับการบิลด์แรกด้วย Bazel ไปที่ส่วนถัดไปเพื่อกำหนดคำศัพท์บางคำและตั้งค่าพื้นที่ทำงาน
เริ่มต้นใช้งาน
ตั้งค่าพื้นที่ทำงาน
คุณต้องตั้งค่าพื้นที่ทำงานของโปรเจ็กต์ก่อนจึงจะสร้างโปรเจ็กต์ได้ พื้นที่ทํางานคือ ไดเรกทอรีที่เก็บไฟล์ต้นฉบับของโปรเจ็กต์และเอาต์พุตการสร้างของ Bazel นอกจากนี้ ยังมีไฟล์สำคัญต่อไปนี้ด้วย
ซึ่งระบุไดเรกทอรีและเนื้อหาเป็นพื้นที่ทำงาน Bazel และ อยู่ในรูทของโครงสร้างไดเรกทอรีของโปรเจ็กต์WORKSPACE
file
อย่างน้อย 1 รายการ ซึ่งจะบอก Bazel วิธีสร้างส่วนต่างๆ ของโปรเจ็กต์ ไดเรกทอรีภายในพื้นที่ทำงานที่มีไฟล์BUILD
filesBUILD
คือแพ็กเกจ (ดูข้อมูลเพิ่มเติมเกี่ยวกับแพ็กเกจ ในบทแนะนำนี้)
ในโปรเจ็กต์ในอนาคต หากต้องการกำหนดให้ไดเรกทอรีเป็นพื้นที่ทำงาน Bazel ให้สร้างไฟล์ว่างชื่อ WORKSPACE
ในไดเรกทอรีนั้น สำหรับวัตถุประสงค์ของบทแนะนำนี้
WORKSPACE
ไฟล์จะอยู่ในแต่ละขั้นตอนแล้ว
หมายเหตุ: เมื่อ Bazel สร้างโปรเจ็กต์ อินพุตทั้งหมดต้องอยู่ในเวิร์กสเปซเดียวกัน ไฟล์ที่อยู่ในพื้นที่ทำงานต่างๆ จะแยกจากกัน เว้นแต่จะมีการลิงก์ ดูข้อมูลเพิ่มเติมโดยละเอียดเกี่ยวกับกฎของพื้นที่ทำงานได้ในคู่มือนี้
ทำความเข้าใจไฟล์ BUILD
BUILD
มีคำสั่งหลายประเภทสำหรับ Bazel ไฟล์ BUILD
แต่ละไฟล์ต้องมีกฎอย่างน้อย 1 ข้อ
เป็นชุดคำสั่งที่บอก Bazel วิธีสร้างเอาต์พุตที่ต้องการ
เช่น ไบนารีที่เรียกใช้งานได้หรือไลบรารี อินสแตนซ์แต่ละรายการของกฎการสร้างในไฟล์ BUILD
เรียกว่าเป้าหมาย
และชี้ไปยังชุดไฟล์ต้นฉบับและการอ้างอิงที่เฉพาะเจาะจง
เป้าหมายยังชี้ไปยังเป้าหมายอื่นๆ ได้ด้วย
ดูไฟล์ BUILD
ในไดเรกทอรี cpp-tutorial/stage1/main
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
ในตัวอย่างของเรา hello-world
เป้าหมายจะสร้างอินสแตนซ์ของ
cc_binary rule
ที่มีอยู่แล้วใน Bazel
กฎนี้จะบอกให้ Bazel สร้างไบนารีที่ปฏิบัติการได้แบบสแตนด์อโลนจากไฟล์ต้นฉบับ hello-world.cc
โดยไม่มีทรัพยากร Dependency
สรุป: การเริ่มต้นใช้งาน
ตอนนี้คุณคุ้นเคยกับคำศัพท์สำคัญบางคำแล้ว และรู้ความหมายของคำเหล่านั้นในบริบทของโปรเจ็กต์นี้และ Bazel โดยทั่วไป ในส่วนถัดไป คุณจะสร้างและทดสอบ Stage 1 ของโปรเจ็กต์
ระยะที่ 1: เป้าหมายเดียว แพ็กเกจเดียว
ได้เวลาสร้างส่วนแรกของโปรเจ็กต์แล้ว สำหรับข้อมูลอ้างอิงแบบภาพ โครงสร้างของส่วนระยะที่ 1 ของโปรเจ็กต์มีดังนี้
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── WORKSPACE
เรียกใช้คำสั่งต่อไปนี้เพื่อย้ายไปยังไดเรกทอรี cpp-tutorial/stage1
cd cpp-tutorial/stage1
จากนั้นเรียกใช้
bazel build //main:hello-world
ในป้ายกำกับเป้าหมาย ส่วน //main:
คือตำแหน่งของไฟล์ BUILD
ที่สัมพันธ์กับรูทของพื้นที่ทำงาน และ hello-world
คือชื่อเป้าหมายใน
ไฟล์ BUILD
Bazel จะสร้างไฟล์ที่มีลักษณะดังนี้
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
คุณเพิ่งสร้างเป้าหมาย Bazel แรก Bazel จะวางเอาต์พุตการสร้างในไดเรกทอรี bazel-bin
ที่รูทของพื้นที่ทำงาน
ตอนนี้ให้ทดสอบไบนารีที่เพิ่งสร้างขึ้น ซึ่งก็คือ
bazel-bin/main/hello-world
ซึ่งจะทำให้ข้อความ "Hello world
" พิมพ์ออกมา
ต่อไปนี้คือกราฟทรัพยากร Dependency ของระยะที่ 1
สรุป: ระยะที่ 1
ตอนนี้คุณสร้างบิลด์แรกเสร็จแล้ว และมีความคิดพื้นฐานเกี่ยวกับโครงสร้างของบิลด์ ในขั้นตอนถัดไป คุณจะเพิ่มความซับซ้อนโดยการเพิ่ม เป้าหมายอื่น
ระยะที่ 2: เป้าหมายการสร้างหลายรายการ
แม้ว่าเป้าหมายเดียวจะเพียงพอสำหรับโปรเจ็กต์ขนาดเล็ก แต่คุณอาจต้องการแบ่งโปรเจ็กต์ขนาดใหญ่เป็นหลายเป้าหมายและแพ็กเกจ ซึ่งช่วยให้สร้างแบบเพิ่มทีละส่วนได้อย่างรวดเร็ว กล่าวคือ Bazel จะสร้างเฉพาะสิ่งที่เปลี่ยนแปลงใหม่เท่านั้น และยังช่วยเร่งความเร็วในการสร้าง ด้วยการสร้างหลายส่วนของโปรเจ็กต์พร้อมกัน ขั้นตอนนี้ของ บทแนะนำจะเพิ่มเป้าหมาย และขั้นตอนถัดไปจะเพิ่มแพ็กเกจ
นี่คือไดเรกทอรีที่คุณใช้ในระยะที่ 2
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── WORKSPACE
ดูไฟล์ BUILD
ในไดเรกทอรี 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",
],
)
เมื่อใช้ไฟล์ BUILD
นี้ Bazel จะสร้างไลบรารี hello-greet
ก่อน
(โดยใช้ cc_library rule
ในตัวของ Bazel)
จากนั้นจึงสร้างไบนารี hello-world
แอตทริบิวต์ deps
ใน
เป้าหมาย hello-world
จะบอก Bazel ว่าต้องใช้ไลบรารี hello-greet
ในการสร้างไบนารี hello-world
ก่อนที่จะสร้างโปรเจ็กต์เวอร์ชันใหม่นี้ คุณต้องเปลี่ยนไดเรกทอรีโดยเปลี่ยนไปใช้ไดเรกทอรี cpp-tutorial/stage2
โดยเรียกใช้คำสั่งต่อไปนี้
cd ../stage2
ตอนนี้คุณสามารถสร้างไบนารีใหม่ได้โดยใช้คำสั่งที่คุ้นเคยต่อไปนี้
bazel build //main:hello-world
อีกครั้งที่ Bazel สร้างสิ่งที่คล้ายกับสิ่งต่อไปนี้
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
ตอนนี้คุณสามารถทดสอบไบนารีที่เพิ่งสร้าง ซึ่งจะแสดงผล "Hello world
" อีกรายการ
bazel-bin/main/hello-world
หากตอนนี้คุณแก้ไข hello-greet.cc
และสร้างโปรเจ็กต์ใหม่ Bazel จะคอมไพล์ไฟล์นั้นใหม่เท่านั้น
เมื่อดูกราฟทรัพยากร Dependency คุณจะเห็นว่า hello-world
ขึ้นอยู่กับอินพุตเพิ่มเติม
ชื่อ hello-greet
สรุป: ขั้นตอนที่ 2
ตอนนี้คุณได้สร้างโปรเจ็กต์ที่มีเป้าหมาย 2 รายการแล้ว hello-world
เป้าหมายจะสร้าง
ไฟล์ต้นฉบับ 1 ไฟล์และขึ้นอยู่กับเป้าหมายอื่น (//main:hello-greet
) ซึ่ง
สร้างไฟล์ต้นฉบับเพิ่มเติม 2 ไฟล์ ในส่วนถัดไป ให้ดำเนินการต่อ
และเพิ่มแพ็กเกจอื่น
ระยะที่ 3: หลายแพ็กเกจ
ระยะถัดไปนี้จะเพิ่มความซับซ้อนอีกชั้นและสร้างโปรเจ็กต์ที่มี
หลายแพ็กเกจ ดูโครงสร้างและเนื้อหาของไดเรกทอรี
cpp-tutorial/stage3
ด้านล่าง
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
คุณจะเห็นว่าตอนนี้มีไดเรกทอรีย่อย 2 รายการ และแต่ละรายการมีBUILD
ไฟล์ ดังนั้น ตอนนี้ Bazel จะเห็นว่าพื้นที่ทำงานมี 2 แพ็กเกจ ได้แก่ lib
และ
main
ดูไฟล์ lib/BUILD
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
และในไฟล์ 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",
],
)
hello-world
เป้าหมายในแพ็กเกจหลักขึ้นอยู่กับhello-time
เป้าหมาย
ในแพ็กเกจ lib
(จึงมีป้ายกำกับเป้าหมาย //lib:hello-time
) - Bazel รู้
สิ่งนี้ผ่านแอตทริบิวต์ deps
คุณจะเห็นการเปลี่ยนแปลงนี้ในกราฟการขึ้นต่อกัน
หากต้องการให้การสร้างสำเร็จ คุณต้องทำให้เป้าหมาย //lib:hello-time
ใน lib/BUILD
มองเห็นได้อย่างชัดเจนสำหรับเป้าหมายใน main/BUILD
โดยใช้แอตทริบิวต์การมองเห็น
เนื่องจากโดยค่าเริ่มต้น เป้าหมายจะมองเห็นได้เฉพาะเป้าหมายอื่นๆ ในไฟล์ BUILD
เดียวกัน
Bazel ใช้ระดับการเข้าถึงเป้าหมายเพื่อป้องกันปัญหาต่างๆ เช่น ไลบรารี
ที่มีรายละเอียดการใช้งานรั่วไหลไปยัง API สาธารณะ
ตอนนี้ให้สร้างโปรเจ็กต์เวอร์ชันสุดท้ายนี้ เปลี่ยนไปใช้ไดเรกทอรี cpp-tutorial/stage3
โดยเรียกใช้คำสั่งต่อไปนี้
cd ../stage3
เรียกใช้คำสั่งต่อไปนี้อีกครั้ง
bazel build //main:hello-world
Bazel จะสร้างไฟล์ที่มีลักษณะดังนี้
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
ตอนนี้ให้ทดสอบไบนารีสุดท้ายของบทแนะนำนี้เพื่อดูHello world
ข้อความสุดท้าย
bazel-bin/main/hello-world
สรุป: ขั้นตอนที่ 3
ตอนนี้คุณได้สร้างโปรเจ็กต์เป็น 2 แพ็กเกจที่มี 3 เป้าหมายแล้ว และเข้าใจ การขึ้นต่อกันระหว่างแพ็กเกจเหล่านั้น ซึ่งจะช่วยให้คุณสามารถสร้างโปรเจ็กต์ในอนาคตด้วย Bazel ได้ ในส่วนถัดไป ให้ดูวิธีดำเนินการต่อในเส้นทาง Bazel
ขั้นตอนถัดไป
ตอนนี้คุณได้สร้างบิลด์พื้นฐานแรกด้วย Bazel เสร็จแล้ว แต่ก็เป็นเพียง จุดเริ่มต้นเท่านั้น แหล่งข้อมูลเพิ่มเติมบางส่วนสำหรับการเรียนรู้ Bazel ต่อไปมีดังนี้
- หากต้องการมุ่งเน้นที่ C++ ต่อไป โปรดอ่านเกี่ยวกับ Use Case ทั่วไปในการสร้าง C++
- หากต้องการเริ่มต้นสร้างแอปพลิเคชันอื่นๆ ด้วย Bazel โปรดดูบทแนะนำ สำหรับ Java, แอปพลิเคชัน Android หรือแอปพลิเคชัน iOS)
- หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับการทำงานกับที่เก็บข้อมูลในเครื่องและที่เก็บข้อมูลระยะไกล โปรดอ่านเกี่ยวกับการขึ้นต่อกันภายนอก
- ดูข้อมูลเพิ่มเติมเกี่ยวกับกฎอื่นๆ ของ Bazel ได้ในคู่มืออ้างอิงนี้
ขอให้สนุกกับการสร้าง