บทนำ
หากเพิ่งเริ่มใช้ Bazel คุณมาถูกที่แล้ว ทำตามบทแนะนำการสร้างครั้งแรกนี้สำหรับ ข้อมูลเบื้องต้นเกี่ยวกับการใช้ Bazel บทแนะนำนี้จะให้นิยามคำศัพท์สำคัญดังต่อไปนี้ ในบริบทของ Bazel และแนะนำพื้นฐานต่างๆ ของ Bazel เริ่มจากเครื่องมือที่จำเป็น คุณจะต้องสร้างและเรียกใช้ โดยจะมีความซับซ้อนมากขึ้นเรื่อยๆ รวมถึงเรียนรู้วิธีและสาเหตุที่ทำให้ซับซ้อนมากขึ้น
แม้ว่า 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
│ └── 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
ไฟล์มีอยู่ 3 ชุด โดยแต่ละชุดจะแสดงขั้นตอนในบทแนะนำนี้ ในระยะแรก คุณจะต้องสร้างเป้าหมายเดียวที่อยู่ในแพ็กเกจเดียว ในขั้นตอนที่ 2 คุณจะ สร้างทั้งไบนารีและไลบรารีจากแพ็กเกจเดียว ในอินนิงที่ 3 และสุดท้าย คุณจะสร้างโปรเจ็กต์ที่มีแพ็กเกจหลายรายการ และสร้างด้วย หลายเป้าหมาย
สรุป: บทนำ
การติดตั้ง Bazel (และ Git) และโคลนที่เก็บสำหรับบทแนะนำนี้ทำให้คุณสามารถ ได้วางรากฐานในการสร้างสิ่งแรกกับ Bazel ไปยังรายการถัดไป เพื่อกำหนดคำศัพท์และตั้งค่า workspace
เริ่มต้นใช้งาน
คุณต้องตั้งค่าพื้นที่ทำงานของโปรเจ็กต์ก่อนจึงจะสร้างโปรเจ็กต์ได้ พื้นที่ทำงาน เป็นไดเรกทอรีที่ใช้เก็บไฟล์ต้นฉบับของโครงการและเอาต์พุตบิลด์ของ Bazel นอกจากนี้ยังมีไฟล์สำคัญเหล่านี้ด้วย
- ไฟล์
MODULE.bazel
ซึ่งระบุไดเรกทอรีและเนื้อหาในไดเรกทอรีเป็น พื้นที่ทำงานของ Bazel และอยู่ที่รูทของไดเรกทอรีของโปรเจ็กต์ ใหม่ นอกจากนี้ยังเป็นที่ที่คุณระบุทรัพยากร Dependency ภายนอกด้วย BUILD
อย่างน้อย 1 รายการ ซึ่งจะทำให้ Bazel ทราบ วิธีสร้างส่วนอื่นๆ ของโครงการ ไดเรกทอรีภายในแท็ก พื้นที่ทำงานที่มีไฟล์BUILD
คือ package (ข้อมูลเพิ่มเติมเกี่ยวกับแพ็กเกจ ต่อไปในบทแนะนำนี้)
ในโปรเจ็กต์ในอนาคต หากต้องการกำหนดไดเรกทอรีเป็นพื้นที่ทำงานของ Bazel ให้สร้าง
ไฟล์ว่างชื่อ MODULE.bazel
ในไดเรกทอรีนั้น เพื่อจุดประสงค์ของกรณีนี้
บทแนะนำ ไฟล์ MODULE.bazel
มีอยู่แล้วในแต่ละขั้นตอน
ทำความเข้าใจไฟล์ BUILD
ไฟล์ BUILD
มีวิธีการหลายประเภทสำหรับ Bazel ชิ้น
BUILD
ไฟล์ต้องมีอย่างน้อย 1 ไฟล์
กฎเป็นชุดคำสั่ง
ซึ่งบอก Bazel ถึงวิธีสร้างเอาต์พุตที่คุณต้องการ เช่น ไบนารีที่ดำเนินการได้
หรือห้องสมุด อินสแตนซ์แต่ละรายการของกฎบิลด์ในไฟล์ BUILD
จะเรียกว่า
กำหนดเป้าหมายและชี้ไปยัง
ชุดของไฟล์ต้นฉบับและ
การพึ่งพากัน เป้าหมายสามารถ
ชี้ไปที่เป้าหมายอื่นๆ ด้วย
ดูไฟล์ BUILD
ในไดเรกทอรี cpp-tutorial/stage1/main
:
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
ในตัวอย่าง เป้าหมาย hello-world
จะสร้างอินสแตนซ์ในตัวของ Bazel
cc_binary
กฎ กฎ
บอก Bazel ให้สร้างไบนารีที่ดำเนินการได้ในตัวเองจาก
hello-world.cc
> ไฟล์ต้นฉบับที่ไม่มีทรัพยากร Dependency
สรุป: การเริ่มต้นใช้งาน
ตอนนี้คุณก็คุ้นเคยกับคำศัพท์สำคัญ และความหมายของคำเหล่านั้นในบริบทของ โครงการนี้ และ Bazel ทั่วไป ในส่วนถัดไป คุณจะได้สร้างและทดสอบ ขั้นที่ 1 ของโครงการ
ขั้นที่ 1: เป้าหมายเดียว แพ็กเกจเดียว
ถึงเวลาสร้างส่วนแรกของโปรเจ็กต์แล้ว เพื่อเป็นข้อมูลอ้างอิง ของส่วนขั้นที่ 1 ของโครงการคือ
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── MODULE.bazel
เรียกใช้คำสั่งต่อไปนี้เพื่อย้ายไปยังไดเรกทอรี 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
" ที่พิมพ์
กราฟการขึ้นต่อกันของระยะที่ 1 มีดังนี้
สรุป: ขั้นที่ 1
ตอนนี้คุณก็ได้สร้างเสร็จแล้ว พอมีไอเดียพื้นฐานว่า การสร้างโครงสร้าง ในขั้นตอนถัดไป คุณจะต้องเพิ่มความซับซ้อนโดยการเพิ่ม เป้าหมายอื่น
ขั้นที่ 2: เป้าหมายบิลด์หลายรายการ
แม้ว่าเป้าหมายเดียวจะเพียงพอแล้วสำหรับโปรเจ็กต์ขนาดเล็ก แต่คุณอาจต้องการแยกเป้าหมาย โปรเจ็กต์ขนาดใหญ่ให้กลายเป็นหลายเป้าหมายและแพ็กเกจ วิธีนี้ทำให้ได้เร็ว สิ่งก่อสร้างที่เพิ่มขึ้นเรื่อยๆ กล่าวคือ Bazel สร้างเฉพาะสิ่งที่เปลี่ยนแปลงไปขึ้นมาใหม่เท่านั้น และเร็วขึ้น ด้วยการสร้างส่วนต่างๆ ของโปรเจ็กต์พร้อมกัน ขั้นตอนนี้ บทแนะนำจะเพิ่มเป้าหมาย และรายการถัดไปจะเพิ่มแพ็กเกจ
นี่คือไดเรกทอรีที่คุณกำลังใช้งานสำหรับระยะที่ 2:
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
ดูไฟล์ 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
ในตัวของ Bazel
) จากนั้น
ไบนารี hello-world
แอตทริบิวต์ deps
ในเป้าหมาย hello-world
บอก
Bazel ว่าต้องมีไลบรารี hello-greet
เพื่อสร้าง hello-world
2.
ก่อนที่คุณจะสร้างโปรเจ็กต์เวอร์ชันใหม่นี้ได้ คุณต้องเปลี่ยน
ไดเรกทอรี โดยเปลี่ยนเป็นไดเรกทอรี 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 เท่านั้น
คอมไพล์ไฟล์นั้นซ้ำ
เมื่อดูกราฟการขึ้นต่อกัน คุณจะเห็นว่า hello-world
อ้างอิง
อินพุตเพิ่มเติมชื่อ hello-greet
:
สรุป: ขั้นที่ 2
ตอนนี้คุณได้สร้างโปรเจ็กต์ที่มีเป้าหมาย 2 รายการแล้ว บิลด์ hello-world
เป้าหมาย
ไฟล์ต้นฉบับ 1 ไฟล์และขึ้นอยู่กับเป้าหมายอื่นอีก 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
└── MODULE.bazel
คุณจะเห็นได้ว่าตอนนี้จะมีไดเรกทอรีย่อย 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
คุณจะเห็นข้อมูลนี้ในทรัพยากร Dependency
กราฟ
คุณกำหนดเป้าหมาย //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 เป้าหมายแล้ว และทำความเข้าใจ ทรัพยากร Dependency ต่างๆ ซึ่งจะช่วยให้คุณออกเดินทางและสร้างอนาคตได้ กับ Bazel ในส่วนถัดไป โปรดดูวิธีต่อ การเดินทางของ Bazel
ขั้นตอนถัดไป
ตอนนี้คุณได้สร้างงานพื้นฐานแรกกับ Bazel เสร็จแล้ว แต่นี่เป็น เริ่ม แหล่งข้อมูลเพิ่มเติมเพื่อการเรียนรู้กับ Bazel ต่อไปมีดังนี้
- หากต้องการมุ่งเน้นที่ C++ ต่อไป โปรดอ่านเกี่ยวกับการใช้งานบิลด์ C++ ทั่วไป กรณี
- หากต้องการเริ่มต้นสร้างแอปพลิเคชันอื่นๆ ด้วย Bazel โปรดดู บทแนะนำสำหรับ Java, Android แอปพลิเคชัน หรือ iOS แอปพลิเคชัน
- หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับการทำงานกับที่เก็บในเครื่องและระยะไกล โปรดอ่านเกี่ยวกับ ทรัพยากร Dependency ภายนอก
- ดูข้อมูลเพิ่มเติมเกี่ยวกับกฎอื่นๆ ของ Bazel ได้ที่ข้อมูลอ้างอิงนี้
ขอให้สนุกกับการสร้าง