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

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

สภาพแวดล้อมที่แชร์โดยคำสั่ง Bazel ทั้งหมดจะทำงานในที่เก็บหลักเดียวกัน

โปรดทราบว่าที่ผ่านมา แนวคิดเรื่อง "ที่เก็บ" และ "พื้นที่ทำงาน" คือ ประชุมกัน; คำว่า "พื้นที่ทำงาน" มักใช้เพื่ออ้างอิงถึง และบางครั้งอาจนำไปใช้เป็นคำพ้องความหมายของ "repository"

ชื่อที่เก็บ Canonical

ชื่อ Canonical ที่ที่เก็บระบุที่อยู่ได้ ในบริบทของ โดยที่เก็บแต่ละรายการจะมีชื่อ Canonical ชื่อเดียว เป้าหมายในที่เก็บ ที่ชื่อ Canonical ซึ่งก็คือ canonical_name จะเรียกด้วยป้ายกำกับนี้ได้ @@canonical_name//pac/kage:target (โปรดสังเกต @ คู่)

ที่เก็บหลักจะมีสตริงว่างเป็นชื่อ Canonical เสมอ

ชื่อที่เก็บที่ชัดเจน

ชื่อที่เก็บระบุที่อยู่ได้ในบริบทของที่เก็บอื่น อาจคิดว่าเป็น "ชื่อเล่น" ของที่เก็บซึ่งเป็นที่เก็บชื่อตามรูปแบบบัญญัติ michael อาจมีชื่อที่ชัดเจน mike ในบริบทของที่เก็บ alice แต่อาจมีชื่อ mickey อย่างชัดเจนในบริบทของที่เก็บ bob ในกรณีนี้ เป้าหมายภายใน michael จะแก้ไขได้ด้วยป้ายกำกับ @mike//pac/kage: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 จะค้นหาใน รีจิสทรี BazelBazel Central ตามค่าเริ่มต้น รีจิสทรี องค์กรจัดการข้อมูลโดเมนจะมี ทรัพยากร Dependency MODULE.bazel ซึ่งทำให้ Bazel ค้นพบเนื้อหาทั้งหมด กราฟการขึ้นต่อกันแบบสับเปลี่ยนก่อนดำเนินการแปลงเวอร์ชัน

หลังจากความละเอียดเวอร์ชัน โดยมีการเลือกเวอร์ชัน 1 เวอร์ชันสำหรับแต่ละโมดูล 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

ในช่วงหลายปีที่ผ่านมา นับตั้งแต่มีการเปิดตัวระบบ 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