Bazel รองรับทรัพยากร Dependency ภายนอก ซึ่งเป็นไฟล์ต้นฉบับ (ทั้งข้อความและไบนารี) ที่ใช้ในบิลด์ที่ไม่ได้มาจากพื้นที่ทํางาน ตัวอย่างเช่น อาจเป็นชุดกฎที่โฮสต์ในที่เก็บ GitHub, อาร์ติแฟกต์ Maven หรือไดเรกทอรีในเครื่องภายในพื้นที่ทํางานภายนอก
ใน Bazel 6.0 มี 2 วิธีในการจัดการทรัพยากร Dependency ภายนอกด้วย Bazel
ได้แก่ ระบบ WORKSPACE
แบบดั้งเดิมที่ใช้ที่เก็บข้อมูลเป็นหลัก และระบบ
MODULE.bazel
ใหม่ที่เน้นโมดูล (รหัสชื่อ Bzlmod
และเปิดใช้การติดธง --enable_bzlmod
) ระบบทั้งสองระบบสามารถใช้ด้วยกันได้ แต่ Bzlmod จะแทนที่ระบบ WORKSPACE
ใน Bazel ในอนาคต
บทความนี้จะอธิบายแนวคิดเกี่ยวกับการจัดการทรัพยากร Dependency ภายนอกใน Bazel ก่อนจะอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับทั้ง 2 ระบบตามลําดับ
แนวคิด
ที่เก็บ
ไดเรกทอรีที่มีไฟล์ WORKSPACE
หรือ WORKSPACE.bazel
ที่มีไฟล์ต้นฉบับที่จะใช้ในบิวด์ Bazel มักจะย่อให้สั้นลงเหลือเพียง repo
ที่เก็บหลัก
ที่เก็บที่ใช้คําสั่ง Bazel ปัจจุบันอยู่
Workspace
สภาพแวดล้อมที่คําสั่ง Bazel ทั้งหมดแชร์ไว้ในที่เก็บหลักเดียวกัน
โปรดทราบว่าที่ผ่านมาแนวคิด "ที่เก็บ" และ "พื้นที่ทํางาน" มีความสัมพันธ์กัน คําว่า "พื้นที่ทํางาน" มักใช้เพื่ออ้างถึงที่เก็บหลัก และบางครั้งยังใช้เป็นคําพ้องความหมายของ "ที่เก็บ" ด้วย
ชื่อที่เก็บมาตรฐาน
ชื่อ Canonical ที่ที่เก็บสามารถจัดการได้ ภายในบริบทของพื้นที่ทํางาน ที่เก็บแต่ละรายการจะมีชื่อมาตรฐานเพียงชื่อเดียว เป้าหมายภายในที่เก็บซึ่งมีชื่อ Canonical ที่มีชื่อ canonical_name
สามารถแก้ไขได้โดยป้ายกํากับ
@@canonical_name//pac/kage:target
(โปรดสังเกต @
คู่)
ที่เก็บหลักจะมีสตริงว่างเปล่าเป็นชื่อ Canonical เสมอ
ชื่อที่เก็บที่เห็นได้ชัด
ชื่อที่เก็บจะระบุได้โดยบริบทของที่เก็บอื่น
ซึ่งอาจถือว่าเป็น "ชื่อเล่น" ของที่เก็บ: ที่เก็บซึ่งมีชื่อ Canonical
michael
อาจมีชื่อ mike
ที่ชัดเจนในบริบทของที่เก็บ
alice
แต่อาจมีชื่อที่ชัดเจนคือ mickey
ในบริบทของที่เก็บ
bob
ในกรณีนี้ ป้ายกํากับภายใน michael
จะป้ายกํากับที่ @mike//pac/kage:target
จัดการในบริบทของ alice
(โปรดสังเกต @
รายการเดียว)
ในทางกลับกัน วิธีนี้อาจเรียกว่าการจับคู่ที่เก็บ เนื่องจากที่เก็บแต่ละรายการจะจับคู่จาก "ชื่อที่เก็บที่ถูกต้อง" กับ "ชื่อที่เก็บตามรูปแบบบัญญัติ"
กฎที่เก็บ
สคีมาสําหรับคําจํากัดความของที่เก็บซึ่งบอก Bazel เกี่ยวกับวิธีอัปเดตที่เก็บเนื้อหา เช่น อาจเป็น "ดาวน์โหลดชุดไฟล์ Zip จาก URL หนึ่งและแตกไฟล์ออก" หรือ "ดึงอาร์ติแฟกต์ Maven ที่ต้องการและทําให้ปรากฏเป็นเป้าหมาย java_import
" หรือเพียง "ลิงก์ไดเรกทอรีในเครื่อง" ระบุที่เก็บทั้งหมดโดยเรียกใช้กฎที่เก็บที่มีอาร์กิวเมนต์ตามจํานวนที่เหมาะสม
ดูกฎที่เก็บสําหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีเขียนกฎที่เก็บของคุณเอง
กฎที่เก็บที่พบบ่อยที่สุดคือ http_archive
ซึ่งจะดาวน์โหลดที่เก็บถาวรจาก URL แล้วดึงข้อมูล และ local_repository
ซึ่งจะลิงก์ไดเรกทอรีภายในซึ่งเป็นที่เก็บ Bazel อยู่แล้ว
กําลังดึงข้อมูลที่เก็บ
การทําให้ที่เก็บพร้อมใช้งานในดิสก์ในเครื่องโดยเรียกใช้กฎที่เก็บที่เกี่ยวข้อง พื้นที่เก็บข้อมูลที่กําหนดไว้ในพื้นที่ทํางานจะไม่พร้อมใช้งานในดิสก์ภายในเครื่องก่อนที่จะดึงข้อมูล
ปกติแล้ว Bazel จะเรียกข้อมูลที่เก็บเมื่อจําเป็นเท่านั้น จากการดึงข้อมูล และที่เก็บยังไม่ได้ดึงข้อมูล หากที่เก็บถูกเรียกข้อมูลมาก่อน Bazel จะดึงข้อมูลอีกครั้งก็ต่อเมื่อมีการเปลี่ยนแปลง
การจัดวางไดเรกทอรี
หลังจากเรียกข้อมูลแล้ว คุณจะดูที่เก็บได้ในไดเรกทอรีย่อย external
ในฐานเอาต์พุตใต้ชื่อ Canonical
คุณสามารถเรียกใช้คําสั่งต่อไปนี้เพื่อดูเนื้อหาของที่เก็บด้วยชื่อมาตรฐาน canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
การจัดการทรัพยากร Dependency ภายนอกด้วย Bzlmod
Bzlmod ซึ่งเป็นระบบย่อยที่ใช้ทรัพยากรภายนอกระบบใหม่นี้ไม่สามารถทํางานกับที่เก็บได้โดยตรง แต่จะสร้างกราฟ Dependency จากโมดูลแทน โดยเรียกใช้ extensions ที่ด้านบนของกราฟ และกําหนดการแสดงผลตามนั้น
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 จะค้นหาในรีจิสทรีของ Bazel โดยค่าเริ่มต้น Bazel Central
Registry องค์กรจัดการข้อมูลโดเมนมีไฟล์ MODULE.bazel
ที่ขึ้นต่อกันซึ่งช่วยให้ Bazel ค้นพบกราฟการพึ่งพาการเปลี่ยนรูปแบบทั้งหมดได้ก่อนที่จะดําเนินการแปลงเวอร์ชัน
หลังจากแก้ไขปัญหาเวอร์ชันแล้ว เมื่อเลือกเวอร์ชันหนึ่งสําหรับแต่ละโมดูล
Bazel จะปรึกษารีจิสทรีอีกครั้งเพื่อเรียนรู้วิธีกําหนดที่เก็บสําหรับแต่ละโมดูล
(ในกรณีส่วนใหญ่ โดยใช้ http_archive
)
นอกจากนี้ โมดูลยังสามารถระบุชิ้นข้อมูลที่กําหนดเองที่เรียกว่าแท็ก ซึ่งส่วนขยายโมดูลใช้หลังความละเอียดของโมดูลเพื่อระบุการกําหนดเพิ่มเติม ส่วนขยายเหล่านี้มีความสามารถคล้ายกับกฎที่เก็บ จึงดําเนินการต่างๆ ได้ เช่น ยื่นไฟล์ I/O และส่งคําขอของเครือข่าย เครื่องมือเหล่านี้ช่วยให้ Bazel โต้ตอบกับระบบการจัดการแพ็กเกจอื่นๆ ได้ในขณะที่ยังเคารพกราฟ Dependency ที่สร้างขึ้นจากโมดูล Bazel
ลิงก์ภายนอกใน Bzlmod
- คู่มือการย้ายข้อมูล Bzlmod
- ตัวอย่างการใช้งาน Bzlmod ใน bazelbuild/examples
- การยกเครื่องภายนอกของ Bazel (เอกสารการออกแบบ Bzlmod ต้นฉบับ)
- คุยเรื่อง BazelCon 2021 ใน Bzlmod
- พูดคุยเรื่อง Bazel Community Day ใน Bzlmod
การกําหนดที่เก็บใหม่ด้วย WORKSPACE
ที่ผ่านมา คุณจะจัดการการอ้างอิงภายนอกได้โดยกําหนดที่เก็บในไฟล์ 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",
)
ข้อมูลโค้ดกําหนดที่เก็บซึ่งมีชื่อมาตรฐานเป็น foo
ในระบบ WORKSPACE
โดยค่าเริ่มต้น ชื่อ Canonical ของที่เก็บจะเป็นชื่อที่ปรากฏอย่างชัดเจนสําหรับที่เก็บอื่นๆ ทั้งหมด
ดูรายการทั้งหมดของฟังก์ชันที่พร้อมใช้งานในไฟล์ WORKSPACE
ข้อบกพร่องของระบบ WORKSPACE
ในช่วงหลายปีที่ผ่านมานับตั้งแต่ที่มีการเปิดตัวระบบ WORKSPACE
ผู้ใช้ได้รายงานประเด็นปัญหาหลายประการ เช่น
- Bazel จะไม่ประเมินไฟล์
WORKSPACE
ของทรัพยากร Dependency ดังนั้นต้องกําหนดการอ้างอิงทางอ้อมทั้งหมดในไฟล์WORKSPACE
ของที่เก็บหลัก นอกเหนือจากการอ้างอิงโดยตรง - ในการแก้ไขปัญหานี้ โปรเจ็กต์ต่างๆ ได้นํารูปแบบ "deps.bzl" ไปใช้
ซึ่งกําหนดมาโครซึ่งจะกําหนดที่เก็บหลายรายการ และขอให้ผู้ใช้เรียกมาโครนี้ในไฟล์
WORKSPACE
- ปัญหานี้มีปัญหาเกิดขึ้นเอง: มาโครไม่สามารถ
load
ไฟล์.bzl
อื่นๆ ได้อีก โครงการเหล่านี้จึงต้องกําหนดทรัพยากร Dependency แบบส่งต่อในมาโคร "deps" นี้ หรือแก้ปัญหานี้โดยให้ผู้ใช้เรียกมาโคร "deps" หลายเลเยอร์ - Bazel จะประเมินไฟล์
WORKSPACE
ตามลําดับ นอกจากนี้ มีการระบุการพึ่งพาโดยใช้http_archive
ที่มี URL โดยไม่มีข้อมูลเวอร์ชัน ซึ่งหมายความว่าไม่มีวิธีที่เชื่อถือได้ในการดําเนินการแปลค่าเวอร์ชันในกรณีที่ต้องอาศัย Diamond (A
ที่ใช้B
และC
แต่B
และC
จะขึ้นอยู่กับD
เวอร์ชันอื่น)
- ปัญหานี้มีปัญหาเกิดขึ้นเอง: มาโครไม่สามารถ