Bazel รองรับทรัพยากร Dependency ภายนอก ไฟล์ต้นฉบับ (ทั้งข้อความและไบนารี) ที่ใช้ในบิลด์ที่ไม่ได้มาจากพื้นที่ทำงาน เช่น อาจเป็นชุดกฎที่โฮสต์อยู่ในที่เก็บ GitHub, อาร์ติแฟกต์ Maven หรือไดเรกทอรีบนเครื่องภายในนอกพื้นที่ทำงานปัจจุบัน
สำหรับ Bazel 6.0 มี 2 วิธีในการจัดการทรัพยากร Dependency ภายนอกด้วย Bazel ได้แก่
ระบบWORKSPACE
แบบดั้งเดิมที่เน้นที่เก็บ และระบบใหม่ที่เน้นโมดูล (ใช้โค้ดชื่อ Bzlmod และเปิดใช้ด้วยแฟล็ก --enable_bzlmod
) คุณสามารถใช้ทั้ง 2 ระบบร่วมกันได้ แต่ Bzlmod จะเข้ามาแทนที่ระบบ WORKSPACE
ใน Bazel รุ่นต่อๆ ไป{/0 สำหรับการย้ายข้อมูลของ Bazel{/0MODULE.bazel
เอกสารนี้จะอธิบายแนวคิดเกี่ยวกับการจัดการทรัพยากร Dependency ภายนอกใน Bazel ก่อนที่จะลงลึกรายละเอียดเพิ่มเติมเกี่ยวกับทั้ง 2 ระบบตามลำดับ
แนวคิด
ที่เก็บ
ไดเรกทอรีที่มีไฟล์ WORKSPACE
หรือ WORKSPACE.bazel
ซึ่งมีไฟล์ต้นฉบับที่จะใช้ในบิวด์ Bazel บ่อยครั้งจะย่อไว้เพียงที่เก็บ
ที่เก็บหลัก
ที่เก็บที่คำสั่ง Bazel ปัจจุบันกำลังทำงาน
Workspace
สภาพแวดล้อมที่แชร์โดยคำสั่ง Bazel ทั้งหมดจะทำงานในที่เก็บหลักเดียวกัน
โปรดทราบว่าก่อนหน้านี้แนวคิดของ "ที่เก็บ" และ "พื้นที่ทำงาน" นั้นขัดแย้งกัน คำว่า "พื้นที่ทำงาน" มักหมายถึงที่เก็บหลัก และบางครั้งอาจหมายถึง "ที่เก็บ" ด้วยซ้ำ
ชื่อที่เก็บ Canonical
Canonical Name (CNAME) ที่ที่เก็บเป็นแอดเดรสได้ ภายในบริบทของพื้นที่ทำงาน ที่เก็บแต่ละรายการจะมีชื่อ Canonical เดียวกัน เป้าหมายในที่เก็บ
ซึ่งมี Canonical Name canonical_name
จะจัดการได้โดยใช้ป้ายกำกับ
@@canonical_name//pac/kage:target
(ให้สังเกตุ@
ซ้อน)
ที่เก็บหลักจะมีสตริงว่างเป็นชื่อ Canonical เสมอ
ชื่อที่เก็บที่ปรากฏ
ชื่อของที่เก็บนั้นจะแก้ไขได้โดยในบริบทของที่เก็บอื่น
ซึ่งอาจถือได้ว่าเป็น "ชื่อเล่น" ของที่เก็บ: ที่เก็บที่มีชื่อ Canonical michael
อาจมีชื่อที่เห็นได้ชัดว่า mike
ในบริบทของที่เก็บ
alice
แต่อาจมีชื่อที่ชัดเจนว่าmickey
ในบริบทของที่เก็บ
bob
ในกรณีนี้ ป้ายกำกับ @mike//pac/kage:target
จะจัดการเป้าหมายภายใน michael
ได้ในบริบทของ alice
(โปรดสังเกต @
รายการเดียว)
ในทางกลับกัน คุณอาจทราบว่าสิ่งนี้เป็นการแมปที่เก็บ โดยที่ที่เก็บแต่ละรายการจะมีการแมปจาก "ชื่อที่เก็บปรากฏ" ไปจนถึง "ชื่อที่เก็บ Canonical"
กฎที่เก็บ
สคีมาสำหรับคำจำกัดความของที่เก็บซึ่งบอก Bazel เกี่ยวกับวิธีทำให้ที่เก็บเป็นรูปธรรม เช่น "ดาวน์โหลดไฟล์ ZIP จาก URL บางรายการและแตกไฟล์" หรือ "ดึงข้อมูลอาร์ติแฟกต์ Maven ที่กำหนดและทำให้พร้อมใช้งานเป็นเป้าหมาย java_import
" หรือเพียง "ลิงก์ไดเรกทอรีในเครื่อง" ก็ได้ ที่เก็บทั้งหมดมีการกำหนดด้วยการเรียกใช้กฎที่เก็บด้วยจำนวนอาร์กิวเมนต์ที่เหมาะสม
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีเขียนกฎที่เก็บของคุณเองได้ที่กฎที่เก็บ
กฎที่เก็บที่ใช้กันมากที่สุดในปัจจุบันคือ http_archive
ซึ่งดาวน์โหลดที่เก็บถาวรจาก URL แล้วดึงข้อมูล และ local_repository
ซึ่งลิงก์กับไดเรกทอรีในเครื่องที่เป็นที่เก็บ Bazel อยู่แล้ว
ดึงข้อมูลที่เก็บ
การดำเนินการสร้างที่เก็บที่ใช้ได้ในดิสก์ในเครื่องโดยการเรียกใช้กฎที่เก็บที่เกี่ยวข้อง ที่เก็บที่กำหนดในพื้นที่ทำงานไม่พร้อมใช้งานบนดิสก์ในเครื่องก่อนที่จะมีการดึงข้อมูล
ปกติแล้ว Bazel จะดึงข้อมูลที่เก็บเฉพาะเมื่อต้องการบางสิ่งจากที่เก็บ และยังไม่มีการดึงข้อมูลที่เก็บ หากมีการดึงข้อมูลที่เก็บมาก่อนแล้ว Bazel จะดึงข้อมูลอีกครั้งก็ต่อเมื่อมีการเปลี่ยนแปลงคำจำกัดความเท่านั้น
เลย์เอาต์ไดเรกทอรี
หลังจากดึงข้อมูลแล้ว คุณจะดูที่เก็บได้ในไดเรกทอรีย่อย external
ในฐานเอาต์พุตภายใต้ชื่อ Canonical
คุณเรียกใช้คำสั่งต่อไปนี้เพื่อดูเนื้อหาของที่เก็บที่มีชื่อ Canonical canonical_name
ได้
ls $(bazel info output_base)/external/ canonical_name
จัดการทรัพยากร Dependency ภายนอกด้วย Bzlmod
Bzlmod ซึ่งเป็นระบบย่อยของทรัพยากร Dependency ภายนอกแบบใหม่ที่ทํางานกับคําจํากัดความของที่เก็บไม่ได้โดยตรง แต่จะสร้างกราฟการอ้างอิงจากโมดูล เรียกใช้ส่วนขยายที่ด้านบนของกราฟ และกำหนด Repos ตามความเหมาะสม
โมดูล Bazel คือโปรเจ็กต์ Bazel ที่มีได้หลายเวอร์ชัน โดยแต่ละเวอร์ชันจะเผยแพร่ข้อมูลเมตาเกี่ยวกับโมดูลอื่นๆ ที่โมดูลนี้อ้างอิงอยู่ โมดูลต้องมีไฟล์ MODULE.bazel
ที่รูทของที่เก็บ ถัดจากไฟล์ WORKSPACE
ไฟล์นี้คือไฟล์ Manifest ของโมดูล โดยประกาศชื่อ เวอร์ชัน รายการทรัพยากร Dependency และข้อมูลอื่นๆ ของโมดูล ตัวอย่างเบื้องต้นมีดังนี้
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
โมดูลต้องแสดงเฉพาะทรัพยากร Dependency โดยตรงที่ Bzlmod จะค้นหาในรีจิสทรีของ Belle - Bazel Central Registry โดยค่าเริ่มต้น องค์กรจัดการข้อมูลโดเมนจะมีไฟล์ MODULE.bazel
ของการขึ้นต่อกัน ซึ่งช่วยให้ Bazel ค้นพบกราฟทรัพยากร Dependency แบบสกรรมกริยาทั้งหมดก่อนทำการแปลงเวอร์ชัน
หลังจากแก้ไขเวอร์ชันแล้ว ซึ่งระบบจะเลือกเวอร์ชันเดียวสำหรับแต่ละโมดูล
Bazel จะปรึกษารีจิสทรีอีกครั้งเพื่อดูวิธีกำหนดที่เก็บสำหรับแต่ละโมดูล
(ในกรณีส่วนใหญ่ ให้ใช้ http_archive
)
โมดูลยังสามารถระบุข้อมูลที่ปรับแต่งแล้วที่เรียกว่าแท็ก ซึ่งใช้โดยส่วนขยายโมดูลหลังจากการจำแนกโมดูลเพื่อกำหนดที่เก็บเพิ่มเติม ส่วนขยายเหล่านี้มีความสามารถที่คล้ายกับกฎที่เก็บ ซึ่งทำให้ส่วนขยายดำเนินการต่างๆ เช่น ไฟล์ I/O และการส่งคำขอเครือข่ายได้ เครื่องมือเหล่านี้ช่วยให้ Bazel โต้ตอบกับระบบการจัดการแพ็กเกจอื่นๆ ได้ และในขณะเดียวกันก็ยังทำงานตามกราฟทรัพยากร Dependency ที่สร้างจากโมดูล Bazel ไปด้วย
ลิงก์ภายนอกใน Bzlmod
- ตัวอย่างการใช้ Bzlmod ใน bazelbuild/ตัวอย่าง
- ยกเครื่องการพึ่งพากันภายนอกของ Bazel (เอกสารการออกแบบ Bzlmod ต้นฉบับ)
- BazelCon 2021 พูดถึง Bzlmod
- พูดคุยกันในวัน Bazel Community Day ใน Bzlmod
กำหนดที่เก็บด้วย WORKSPACE
ก่อนหน้านี้คุณจัดการทรัพยากร Dependency ภายนอกได้โดยกําหนดที่เก็บในไฟล์ WORKSPACE
(หรือ WORKSPACE.bazel
) ไฟล์นี้มีไวยากรณ์คล้ายกับไฟล์ BUILD
ซึ่งใช้กฎที่เก็บแทนกฎการสร้าง
ข้อมูลโค้ดต่อไปนี้คือตัวอย่างการใช้กฎที่เก็บ http_archive
ในไฟล์ WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)
ข้อมูลโค้ดกำหนดที่เก็บซึ่งมีชื่อ Canonical คือ foo
ในระบบ WORKSPACE
โดยค่าเริ่มต้น ชื่อ Canonical ของที่เก็บจะเป็นชื่อที่เห็นได้ชัดของที่เก็บอื่นๆ ทั้งหมดด้วย
ข้อบกพร่องของระบบ WORKSPACE
ในช่วงหลายปีนับตั้งแต่มีการใช้ระบบ WORKSPACE
ผู้ใช้ได้รายงานประเด็นต่างๆ มากมาย ได้แก่
- Bazel ไม่ได้ประเมินไฟล์
WORKSPACE
ของทรัพยากร Dependency ทั้งหมด จึงต้องกำหนดทรัพยากร Dependency แบบสกรรมทั้งหมดไว้ในไฟล์WORKSPACE
ของที่เก็บหลักด้วย นอกเหนือจากทรัพยากร Dependency โดยตรง - ในการแก้ปัญหานี้ โปรเจ็กต์ได้ใช้รูปแบบ "deps.bzl" ซึ่งจะกำหนดมาโครซึ่งจะกลายเป็นที่เก็บหลายรายการ และขอให้ผู้ใช้เรียกมาโครนี้ในไฟล์
WORKSPACE
ของตน- ซึ่งมีปัญหาของตัวเองคือ มาโครไม่สามารถ
load
ไฟล์.bzl
อื่นๆ ได้ ดังนั้นโปรเจ็กต์เหล่านี้จะต้องกำหนดทรัพยากร Dependency แบบสับเปลี่ยนของตนในมาโคร "deps" นี้ หรือแก้ปัญหานี้โดยให้ผู้ใช้เรียกมาโคร "deps" หลายเลเยอร์ - Bazel ประเมินไฟล์
WORKSPACE
ตามลำดับ นอกจากนี้ จะมีการระบุทรัพยากร Dependency โดยใช้http_archive
กับ URL โดยที่ไม่มีข้อมูลเวอร์ชัน ซึ่งหมายความว่าไม่มีวิธีที่เชื่อถือได้ในการดำเนินการแก้ไขเวอร์ชันในกรณีที่เป็นทรัพยากร Dependency ของ Diamond (A
ขึ้นอยู่กับB
และC
ทั้งนี้B
และC
ขึ้นอยู่กับD
เวอร์ชันที่แตกต่างกัน)
- ซึ่งมีปัญหาของตัวเองคือ มาโครไม่สามารถ
เนื่องจาก WorkSPACE มีข้อบกพร่อง ทำให้ Bzlmod จะมาแทนที่ระบบ WORKSPACE เดิมในรุ่น Bazel ในอนาคต โปรดอ่านคำแนะนำในการย้ายข้อมูล Bzlmod เกี่ยวกับวิธีย้ายข้อมูลไปยัง Bzlmod