Bazel รองรับทรัพยากร Dependency ภายนอก ไฟล์ต้นฉบับ (ทั้งข้อความและไบนารี) ที่ใช้ ในบิลด์ที่ไม่ได้มาจากพื้นที่ทํางาน ตัวอย่างเช่น อาจเป็น ชุดกฎที่โฮสต์ในที่เก็บ GitHub, อาร์ติแฟกต์ Maven หรือไดเรกทอรีในเครื่องของคุณ เครื่องที่อยู่นอกพื้นที่ทำงานปัจจุบันของคุณ
สำหรับ Bazel 6.0 คุณสามารถจัดการทรัพยากร Dependency ภายนอกด้วย Bazel ได้ 2 วิธี ดังนี้
ระบบ WORKSPACE
แบบดั้งเดิมที่มุ่งเน้นที่เก็บ และ
ระบบ MODULE.bazel
ที่เน้นโมดูลใหม่ (ใช้ชื่อว่า Bzlmod
และเปิดใช้ด้วยธง --enable_bzlmod
) สามารถใช้ทั้ง 2 ระบบ
แต่ Bzlmod จะมาแทนที่ระบบ WORKSPACE
ใน Bazel ในอนาคต
สำหรับรุ่นต่างๆ โปรดดูคำแนะนำในการย้ายข้อมูล Bzlmod
ย้ายข้อมูล
เอกสารนี้อธิบายแนวคิดเกี่ยวกับการจัดการทรัพยากร Dependency ภายนอก ใน Bazel ก่อนที่จะลงรายละเอียดเกี่ยวกับระบบทั้งสองนี้ตามลำดับ
แนวคิด
ที่เก็บ
แผนผังไดเรกทอรีที่มีไฟล์ตัวทำเครื่องหมายขอบเขตอยู่ที่ราก โดยมีแหล่งที่มา ที่ใช้ได้ในบิลด์ Bazel มักจะย่อให้เหลือเพียงที่เก็บ
ไฟล์เครื่องหมายขอบเขตที่เก็บสามารถ MODULE.bazel
(เป็นสัญญาณว่าที่เก็บนี้
หมายถึงโมดูล Bazel), REPO.bazel
(ดูด้านล่าง) หรือใน
บริบทเดิม WORKSPACE
หรือ WORKSPACE.bazel
ไฟล์เครื่องหมายขอบเขตที่เก็บใดก็ได้
จะหมายถึงขอบเขตของที่เก็บ ไฟล์เหล่านี้หลายๆ ไฟล์สามารถอยู่ร่วมกันใน
ไดเรกทอรี
ที่เก็บหลัก
ที่เก็บที่มีการเรียกใช้คำสั่ง Bazel ปัจจุบัน
รูทของที่เก็บหลักเรียกอีกอย่างว่า workspace root
Workspace
สภาพแวดล้อมที่แชร์โดยคำสั่ง Bazel ทั้งหมดจะทำงานในที่เก็บหลักเดียวกัน ทั้งนี้ ครอบคลุมที่เก็บหลักและชุดของที่เก็บภายนอกที่กำหนดไว้ทั้งหมด
โปรดทราบว่าที่ผ่านมา แนวคิดเรื่อง "ที่เก็บ" และ "พื้นที่ทำงาน" คือ ประชุมกัน; คำว่า "พื้นที่ทำงาน" มักใช้เพื่ออ้างอิงถึง และบางครั้งอาจนำไปใช้เป็นคำพ้องความหมายของ "repository"
ชื่อที่เก็บ Canonical
ชื่อ Canonical ที่ที่เก็บระบุที่อยู่ได้ ในบริบทของ
โดยที่เก็บแต่ละรายการจะมีชื่อ Canonical ชื่อเดียว เป้าหมายในที่เก็บ
ที่ชื่อ Canonical ซึ่งก็คือ canonical_name
จะเรียกด้วยป้ายกำกับนี้ได้
@@canonical_name//package:target
(โปรดสังเกต @
คู่)
ที่เก็บหลักจะมีสตริงว่างเป็นชื่อ Canonical เสมอ
ชื่อที่เก็บที่ชัดเจน
ชื่อที่เก็บระบุที่อยู่ได้ในบริบทของที่เก็บอื่น
อาจคิดว่าเป็น "ชื่อเล่น" ของที่เก็บซึ่งเป็นที่เก็บชื่อตามรูปแบบบัญญัติ
michael
อาจมีชื่อที่ชัดเจน mike
ในบริบทของที่เก็บ
alice
แต่อาจมีชื่อ mickey
อย่างชัดเจนในบริบทของที่เก็บ
bob
ในกรณีนี้ เป้าหมายภายใน michael
จะแก้ไขได้ด้วยป้ายกำกับ
@mike//package:target
ในบริบทของ alice
(โปรดสังเกต @
เดี่ยว)
ในทางกลับกัน อาจเป็นการแมปที่เก็บ ซึ่งก็คือที่เก็บแต่ละรายการ เก็บรักษาการแมปจาก "ชื่อที่เก็บที่ปรากฏ" เป็น "ชื่อที่เก็บ Canonical"
กฎที่เก็บ
สคีมาของคำจำกัดความของที่เก็บซึ่งบอก Bazel ถึงวิธีการแสดง
ที่เก็บได้ ตัวอย่างเช่น อาจเป็น "ดาวน์โหลดชุดไฟล์ Zip จาก URL ที่ระบุ
แล้วดึงข้อมูล" หรือ "ดึงข้อมูลอาร์ติแฟกต์ของ Maven และทำให้พร้อมใช้งานเป็น
java_import
เป้าหมาย" หรือเรียกง่ายๆ ว่า "symlink a local Directory" ทุกที่เก็บ
กำหนด โดยการเรียกใช้กฎที่เก็บที่มีจำนวนอาร์กิวเมนต์ที่เหมาะสม
ดูกฎของที่เก็บสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีเขียน กฎที่เก็บของคุณเอง
กฎที่เก็บที่พบบ่อยที่สุดในปัจจุบันคือ
http_archive
ซึ่งดาวน์โหลดไฟล์ที่เก็บถาวร
จาก URL แล้วดึงข้อมูล และ
local_repository
ซึ่งลิงก์สัญลักษณ์
ไดเรกทอรีในเครื่องที่เป็นที่เก็บ Bazel อยู่แล้ว
ดึงข้อมูลที่เก็บ
การดำเนินการทำให้ที่เก็บพร้อมใช้งานในดิสก์ภายในโดยการเรียกใช้ที่เก็บที่เกี่ยวข้อง กฎที่เก็บ ที่เก็บที่กำหนดไว้ในพื้นที่ทำงานไม่พร้อมใช้งานบนดิสก์ในเครื่อง ก่อนที่จะมีการดึงข้อมูล
โดยปกติแล้ว Bazel จะดึงที่เก็บก็ต่อเมื่อ ต้องการบางอย่างจากที่เก็บ และที่เก็บยังไม่ได้ถูกดึงข้อมูลมา หากมีการดึงข้อมูลที่เก็บแล้ว ก่อนหน้านี้ Bazel จะดึงข้อมูลอีกครั้งก็ต่อเมื่อคำจำกัดความมีการเปลี่ยนแปลง
ใช้คำสั่ง fetch
เพื่อเริ่มการดึงข้อมูลล่วงหน้าสำหรับที่เก็บได้
กำหนดเป้าหมาย หรือที่เก็บที่จำเป็นทั้งหมดเพื่อดำเนินการบิลด์ ความสามารถนี้
เปิดใช้งานบิลด์แบบออฟไลน์โดยใช้ตัวเลือก --nofetch
ตัวเลือก --fetch
มีไว้เพื่อจัดการการเข้าถึงเครือข่าย ค่าเริ่มต้นคือ "จริง"
แต่เมื่อตั้งค่าเป็น "เท็จ" (--nofetch
) คำสั่งจะใช้แคชทั้งหมด
ของ Dependency ได้ และถ้าไม่มี คำสั่งจะส่งผล
ล้มเหลว
ดูตัวเลือกการดึงข้อมูลสำหรับข้อมูลเพิ่มเติม ข้อมูลเกี่ยวกับการควบคุมการดึงข้อมูล
เลย์เอาต์ไดเรกทอรี
หลังจากดึงข้อมูลแล้ว คุณสามารถดูที่เก็บได้ในไดเรกทอรีย่อย external
ใน
ฐานเอาต์พุตภายใต้ชื่อ Canonical
คุณสามารถเรียกใช้คำสั่งต่อไปนี้เพื่อดูเนื้อหาของที่เก็บที่มี
ชื่อ Canonical canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
ไฟล์ REPO.bazel
ไฟล์ REPO.bazel
ใช้เพื่อทำเครื่องหมายขอบเขตบนสุดของโครงสร้างไดเรกทอรี
ที่ประกอบขึ้นเป็นที่เก็บ ไม่จำเป็นต้องมีรายการใดๆ เพื่อใช้เป็นที่เก็บ
ไฟล์ขอบเขต; แต่ยังสามารถใช้เพื่อระบุแอตทริบิวต์ทั่วไปบางอย่าง
สำหรับเป้าหมายบิลด์ทั้งหมดภายในที่เก็บ
ไวยากรณ์ของไฟล์ REPO.bazel
คล้ายกับไฟล์ BUILD
ยกเว้นว่าไม่มี
ระบบรองรับคำสั่ง load
และฟังก์ชัน repo()
ซึ่งเป็นฟังก์ชันเดี่ยวเท่านั้น
พร้อมใช้งาน repo()
ใช้อาร์กิวเมนต์เดียวกับ package()
ฟังก์ชัน ใน BUILD
ไฟล์ ขณะที่ package()
ระบุแอตทริบิวต์ทั่วไปสำหรับเป้าหมายบิลด์ทั้งหมดภายในแพ็กเกจ repo()
เช่นเดียวกับเป้าหมายบิลด์ทั้งหมดภายในที่เก็บ
ตัวอย่างเช่น คุณสามารถระบุใบอนุญาตทั่วไปสำหรับเป้าหมายทั้งหมดในที่เก็บของคุณได้โดยดำเนินการดังนี้
มีไฟล์ REPO.bazel
ต่อไปนี้
repo(
default_package_metadata = ["//:my_license"],
)
จัดการทรัพยากร Dependency ภายนอกด้วย Bzlmod
Bzlmod ซึ่งเป็นระบบย่อยของทรัพยากร Dependency ภายนอกแบบใหม่ไม่ทำงานกับที่เก็บโดยตรง คำจำกัดความ แต่จะสร้างกราฟทรัพยากร Dependency จากโมดูลแทน ส่วนขยาย ที่ด้านบนของกราฟ และกำหนดที่เก็บตามนั้น
โมดูลของ 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 ตามค่าเริ่มต้น
รีจิสทรี องค์กรจัดการข้อมูลโดเมนจะมี
ทรัพยากร Dependency MODULE.bazel
ซึ่งทำให้ Bazel ค้นพบเนื้อหาทั้งหมด
กราฟการขึ้นต่อกันแบบสับเปลี่ยนก่อนดำเนินการแปลงเวอร์ชัน
หลังจากความละเอียดเวอร์ชัน โดยมีการเลือกเวอร์ชัน 1 เวอร์ชันสำหรับแต่ละโมดูล
Bazel ปรึกษากับบริษัทรับจดทะเบียนอีกครั้งเพื่อดูวิธีกำหนดที่เก็บสำหรับแต่ละโมดูล
(ในกรณีส่วนใหญ่คือการใช้ http_archive
)
โมดูลยังสามารถระบุข้อมูลที่กำหนดเองที่เรียกว่าแท็ก ใช้โดยส่วนขยายโมดูลหลังจากความละเอียดโมดูล เพื่อกำหนดที่เก็บเพิ่มเติม ส่วนขยายเหล่านี้มีความสามารถคล้ายกับที่เก็บ ทำให้สามารถดำเนินการต่างๆ เช่น I/O ไฟล์และส่งเครือข่าย คำขอ รวมถึงช่วยให้ Bazel โต้ตอบกับแพ็กเกจอื่น ที่สอดคล้องกับกราฟทรัพยากร Dependency ที่สร้างขึ้นจาก Bazel โมดูล
ลิงก์ภายนอกบน Bzlmod
- ตัวอย่างการใช้ Bzlmod ใน bazelbuild/ตัวอย่าง
- การยกเครื่องการพึ่งพาภายนอกของ Bazel (เอกสารการออกแบบ Bzlmod ต้นฉบับ)
- การบรรยายในงาน BazelCon 2021 ใน Bzlmod
- การเสวนาเกี่ยวกับวันชุมชนชาว Bazel ใน 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
ในช่วงหลายปีที่ผ่านมา นับตั้งแต่มีการเปิดตัวระบบ WORKSPACE
ผู้ใช้ได้รายงาน
หลายประเด็น ได้แก่
- Bazel ไม่ได้ประเมินไฟล์
WORKSPACE
ของทรัพยากร Dependency ทั้งหมด ดังนั้น ต้องกำหนดทรัพยากร Dependency แบบทรานซิทีฟในไฟล์WORKSPACE
ของ ที่เก็บนอกเหนือจากทรัพยากร Dependency โดยตรง - ในการแก้ปัญหานี้ โครงการได้ใช้ "deps.bzl" โดยที่มี
ก็จะกำหนดมาโครซึ่งจะระบุที่เก็บหลายรายการและขอให้ผู้ใช้ดำเนินการ
เรียกใช้มาโครนี้ใน
WORKSPACE
ไฟล์- ซึ่งมีปัญหาของตัวเอง นั่นคือ มาโครไม่สามารถ
load
ไฟล์.bzl
อื่นๆ ได้ ดังนั้น โปรเจ็กต์เหล่านี้ต้องกำหนดทรัพยากร Dependency แบบทรานซิทีฟใน "deps" หรือแก้ปัญหานี้โดยให้ผู้ใช้เรียก "deps" หลายชั้น มาโคร - Bazel ประเมินไฟล์
WORKSPACE
ตามลำดับ นอกจากนี้ ระบุทรัพยากร Dependency โดยใช้http_archive
ด้วย URL โดยไม่มี ข้อมูลเวอร์ชัน นั่นหมายความว่า จะไม่มีวิธีที่เชื่อถือได้ในการดำเนินการ ความละเอียดของเวอร์ชันในกรณีของทรัพยากร Dependency แบบไดมอนด์ (A
ขึ้นอยู่กับB
และC
ทั้งB
และC
ต้องใช้D
เวอร์ชันที่แตกต่างกัน)
- ซึ่งมีปัญหาของตัวเอง นั่นคือ มาโครไม่สามารถ
เนื่องจาก WORKSPACE มีข้อบกพร่องอยู่ Bzlmod จะมาแทนที่เครื่องมือเดิม ระบบ WORKSPACE ใน Bazel รุ่นต่อๆ ไป โปรดอ่านการย้ายข้อมูล Bzlmod เกี่ยวกับวิธีย้ายข้อมูลไปยัง Bzlmod