ภาพรวมของทรัพยากร Dependency ภายนอก

รายงานปัญหา ดูแหล่งที่มา

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 ไปด้วย

กำหนดที่เก็บด้วย 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