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