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