Bazel รองรับการอ้างอิงภายนอก ไฟล์ต้นฉบับ (ทั้งข้อความและไบนารี) ที่ใช้ ในการสร้างซึ่งไม่ได้มาจากพื้นที่ทำงาน เช่น อาจเป็นชุดกฎที่โฮสต์ในที่เก็บ GitHub, อาร์ติแฟกต์ Maven หรือไดเรกทอรีในเครื่องของคุณนอกพื้นที่ทำงานปัจจุบัน
ตั้งแต่ Bazel 6.0 เป็นต้นไป คุณจะจัดการการขึ้นต่อกันภายนอกด้วย Bazel ได้ 2 วิธี ได้แก่
WORKSPACE
ระบบแบบเดิมที่เน้นที่เก็บ และ
MODULE.bazel
ระบบใหม่ที่เน้นโมดูล (มีชื่อรหัสว่า Bzlmod
และเปิดใช้ด้วยแฟล็ก --enable_bzlmod
) คุณใช้ทั้ง 2 ระบบร่วมกันได้ แต่ Bzlmod จะแทนที่ระบบ WORKSPACE
ใน Bazel รุ่นต่อๆ ไป โปรดดูคู่มือการย้ายข้อมูล Bzlmod เกี่ยวกับวิธีย้ายข้อมูล
เอกสารนี้จะอธิบายแนวคิดเกี่ยวกับการจัดการทรัพยากร Dependency ภายนอกใน Bazel ก่อนที่จะลงรายละเอียดเกี่ยวกับระบบทั้ง 2 ระบบตามลำดับ
แนวคิด
ที่เก็บ
ไดเรกทอรีที่มีไฟล์ WORKSPACE
หรือ WORKSPACE.bazel
ซึ่งมีไฟล์ต้นฉบับ
ที่จะใช้ในการสร้าง Bazel มักย่อเป็น repo
ที่เก็บหลัก
ที่เก็บที่ใช้เรียกใช้คำสั่ง Bazel ปัจจุบัน
Workspace
สภาพแวดล้อมที่คำสั่ง Bazel ทั้งหมดใช้ร่วมกันจะทำงานในที่เก็บหลักเดียวกัน
โปรดทราบว่าในอดีตแนวคิดเรื่อง "ที่เก็บ" และ "พื้นที่ทำงาน" มีความ สับสนกัน โดยมักใช้คำว่า "พื้นที่ทำงาน" เพื่ออ้างอิงถึงที่เก็บหลัก และบางครั้งยังใช้เป็นคำพ้องความหมายของ "ที่เก็บ" ด้วย
ชื่อที่เก็บ Canonical
ชื่อ Canonical ที่ใช้ระบุที่เก็บ ในบริบทของเวิร์กสเปซ
ที่เก็บข้อมูลแต่ละรายการจะมีชื่อมาตรฐานเพียงชื่อเดียว เป้าหมายภายในที่เก็บ
ซึ่งมีชื่อ Canonical เป็น canonical_name
สามารถระบุได้ด้วยป้ายกำกับ
@@canonical_name//pac/kage:target
(โปรดสังเกต @
สองตัว)
ที่เก็บหลักจะมีสตริงว่างเป็นชื่อที่แน่นอนเสมอ
ชื่อที่เก็บที่เห็น
ชื่อที่ใช้ในการระบุที่เก็บในบริบทของที่เก็บอื่น
คุณอาจคิดว่านี่คือ "ชื่อเล่น" ของที่เก็บ: ที่เก็บที่มีชื่อที่แน่นอน
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 จากโมดูล เรียกใช้ส่วนขยายบนกราฟ และกำหนดที่เก็บตามนั้น
โมดูล Bazel คือโปรเจ็กต์ Bazel ที่มีหลายเวอร์ชัน
ซึ่งแต่ละเวอร์ชันจะเผยแพร่ข้อมูลเมตาเกี่ยวกับโมดูลอื่นๆ ที่ขึ้นอยู่กับโมดูลนั้น โมดูลต้องมีไฟล์ MODULE.bazel
ที่รูทของที่เก็บถัดจากไฟล์
WORKSPACE
ไฟล์นี้คือไฟล์ Manifest ของโมดูล ซึ่งประกาศชื่อ
เวอร์ชัน รายการการอ้างอิง และข้อมูลอื่นๆ ตัวอย่างพื้นฐานมีดังนี้
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
โมดูลต้องแสดงเฉพาะการอ้างอิงโดยตรง ซึ่ง Bzlmod จะค้นหาในรีจิสทรี Bazel โดยค่าเริ่มต้นคือรีจิสทรีกลางของ Bazel รีจิสทรีมีไฟล์
dependencies' MODULE.bazel
ซึ่งช่วยให้ Bazel ค้นพบ
กราฟการอ้างอิงแบบทรานซิทีฟทั้งหมดก่อนที่จะทำการแก้ปัญหาเวอร์ชัน
หลังจากแก้ไขเวอร์ชันแล้ว ซึ่งจะมีการเลือกเวอร์ชันหนึ่งสำหรับแต่ละโมดูล
Bazel จะปรึกษารีจิสทรีอีกครั้งเพื่อดูวิธีระบุที่เก็บสำหรับแต่ละโมดูล
(ในกรณีส่วนใหญ่จะใช้ http_archive
)
นอกจากนี้ โมดูลยังระบุชิ้นส่วนข้อมูลที่กำหนดเองซึ่งเรียกว่าแท็กได้ด้วย ซึ่งส่วนขยายโมดูลจะใช้แท็กเหล่านี้หลังจากที่โมดูลได้รับการแก้ไขแล้ว เพื่อกำหนดที่เก็บเพิ่มเติม ส่วนขยายเหล่านี้มีความสามารถคล้ายกับ repo rules ซึ่งช่วยให้ส่วนขยายดำเนินการต่างๆ ได้ เช่น การรับส่งข้อมูลไฟล์และการส่งคำขอเครือข่าย ซึ่งช่วยให้ Bazel โต้ตอบกับระบบการจัดการแพ็กเกจอื่นๆ ได้ในขณะที่ยังคงใช้กราฟการอ้างอิงที่สร้างจากโมดูล Bazel
ลิงก์ภายนอกใน Bzlmod
- ตัวอย่างการใช้งาน Bzlmod ใน bazelbuild/examples
- การยกเครื่องการอ้างอิงภายนอกของ Bazel (เอกสารการออกแบบ Bzlmod ต้นฉบับ)
- การพูดคุยเกี่ยวกับ Bzlmod ใน BazelCon 2021
- การพูดคุยในวันชุมชน Bazel เกี่ยวกับ Bzlmod
กำหนดที่เก็บด้วย WORKSPACE
ในอดีต คุณสามารถจัดการการอ้างอิงภายนอกได้โดยการกำหนดที่เก็บในไฟล์
WORKSPACE
(หรือ WORKSPACE.bazel
) ไฟล์นี้มีไวยากรณ์คล้ายกับไฟล์
BUILD
โดยใช้กฎ repo แทนกฎการสร้าง
ข้อมูลโค้ดต่อไปนี้เป็นตัวอย่างการใช้กฎ http_archive
repo ในไฟล์
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
นับตั้งแต่มีการเปิดตัวระบบ WORKSPACE
ผู้ใช้ได้รายงานปัญหาต่างๆ มากมาย ซึ่งรวมถึง
- Bazel ไม่ได้ประเมินไฟล์
WORKSPACE
ของการอ้างอิงใดๆ ดังนั้นการอ้างอิงแบบทรานซิทีฟทั้งหมดต้องกำหนดไว้ในไฟล์WORKSPACE
ของที่เก็บหลัก นอกเหนือจากการอ้างอิงโดยตรง - โปรเจ็กต์จึงใช้รูปแบบ "deps.bzl" เพื่อหลีกเลี่ยงปัญหานี้ โดยจะกำหนดมาโครซึ่งจะกำหนดที่เก็บหลายรายการ และขอให้ผู้ใช้เรียกใช้มาโครนี้ในไฟล์
WORKSPACE
- ซึ่งก็มีปัญหาของมันเอง นั่นคือมาโครไม่สามารถ
load
ไฟล์.bzl
อื่นๆ ได้ ดังนั้น โปรเจ็กต์เหล่านี้จึงต้องกำหนดการอ้างอิงแบบทรานซิทีฟในมาโคร "deps" นี้ หรือแก้ไขปัญหานี้โดยให้ผู้ใช้เรียกใช้มาโคร "deps" แบบหลายเลเยอร์ - Bazel จะประเมินไฟล์
WORKSPACE
ตามลำดับ นอกจากนี้ คุณยังระบุ การอ้างอิงได้โดยใช้http_archive
กับ URL โดยไม่ต้องระบุ ข้อมูลเวอร์ชัน ซึ่งหมายความว่าไม่มีวิธีที่เชื่อถือได้ในการระบุเวอร์ชันในกรณีของการอ้างอิงแบบไดมอนด์ (A
ขึ้นอยู่กับB
และC
;B
และC
ต่างก็ขึ้นอยู่กับD
เวอร์ชันต่างๆ)
- ซึ่งก็มีปัญหาของมันเอง นั่นคือมาโครไม่สามารถ
เนื่องจากข้อบกพร่องของ WORKSPACE ทำให้ Bzlmod จะมาแทนที่ระบบ WORKSPACE เดิมใน Bazel รุ่นต่อๆ ไป โปรดอ่านคำแนะนำในการย้ายข้อมูล Bzlmod เพื่อดูวิธีย้ายข้อมูลไปยัง Bzlmod