Bazel อาจขึ้นอยู่กับเป้าหมายจากโปรเจ็กต์อื่นๆ ทรัพยากร Dependency จากการแสดงผลอื่นๆ เหล่านี้ โปรเจ็กต์เรียกว่าทรัพยากร Dependency ภายนอก
ไฟล์ WORKSPACE
(หรือ WORKSPACE.bazel
ไฟล์) ใน
ไดเรกทอรี workspace
บอก Bazel ถึงวิธีรับโปรเจ็กต์อื่นๆ แหล่งที่มา โปรเจ็กต์อื่นๆ เหล่านี้สามารถ
มีไฟล์ BUILD
อย่างน้อย 1 ไฟล์ที่มีเป้าหมายของตนเอง BUILD
ไฟล์ภายใน
โปรเจ็กต์หลักสามารถขึ้นอยู่กับเป้าหมายภายนอกเหล่านี้โดยใช้ชื่อจาก
ไฟล์ WORKSPACE
ตัวอย่างเช่น สมมติว่าระบบหนึ่งมี 2 โปรเจ็กต์:
/
home/
user/
project1/
WORKSPACE
BUILD
srcs/
...
project2/
WORKSPACE
BUILD
my-libs/
หาก project1
ต้องการขึ้นอยู่กับเป้าหมาย :foo
ซึ่งกำหนดไว้ใน
/home/user/project2/BUILD
อาจระบุที่เก็บชื่อ
project2
อยู่ที่ /home/user/project2
จากนั้นกำหนดเป้าหมายเป็น
/home/user/project1/BUILD
อาจขึ้นอยู่กับ @project2//:foo
ไฟล์ WORKSPACE
ช่วยให้ผู้ใช้อ้างอิงเป้าหมายจากส่วนอื่นๆ ของ
ระบบไฟล์หรือดาวน์โหลดจากอินเทอร์เน็ต ใช้ไวยากรณ์เดียวกันกับ BUILD
แต่อนุญาตให้ใช้กฎชุดอื่นซึ่งเรียกว่ากฎที่เก็บ (บางครั้ง
หรือที่เรียกว่ากฎพื้นที่ทำงาน) Bazel มาพร้อมกล่อง 2-3 ตัว
กฎที่เก็บในตัวและชุดของ
กฎที่เก็บ Starlark ที่ฝัง
ผู้ใช้ยังเขียนกฎที่เก็บที่กำหนดเองได้ด้วย
เพื่อให้ได้พฤติกรรมที่ซับซ้อนยิ่งขึ้น
ประเภทของทรัพยากร Dependency ภายนอกที่รองรับ
ประเภททรัพยากร Dependency ภายนอกพื้นฐานที่นำมาใช้ได้มีดังนี้
- การพึ่งพาโปรเจ็กต์อื่นๆ ของ Bazel
- การพึ่งพาโปรเจ็กต์ที่ไม่ใช่ Bazel
- ทรัพยากร Dependency ของแพ็กเกจภายนอก
ขึ้นอยู่กับโปรเจ็กต์ Bazel อื่นๆ
หากต้องการใช้เป้าหมายจากโปรเจ็กต์ Bazel ที่สอง คุณสามารถ
ใช้
local_repository
git_repository
หรือ http_archive
เพื่อลิงก์สัญลักษณ์จากระบบไฟล์ในเครื่อง อ้างอิงที่เก็บ Git หรือดาวน์โหลด
ตามลำดับ
ตัวอย่างเช่น สมมติว่าคุณกำลังทำโครงการ my-project/
และคุณต้องการให้
จะขึ้นอยู่กับเป้าหมายจากโปรเจ็กต์ของเพื่อนร่วมงานชื่อ coworkers-project/
ทั้ง 2 อย่าง
ใช้ Bazel คุณจึงเพิ่มโปรเจ็กต์ของเพื่อนร่วมงานเป็นบุคคลภายนอกได้
ที่ต้องพึ่งพากัน จากนั้นใช้เป้าหมายที่เพื่อนร่วมงานกำหนดไว้จากตัวคุณเอง
สร้างไฟล์ คุณจะต้องเพิ่มสิ่งต่อไปนี้ลงใน my_project/WORKSPACE
local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
)
หากเพื่อนร่วมงานมี //foo:bar
เป้าหมาย โปรเจ็กต์จะเรียกว่า
@coworkers_project//foo:bar
ชื่อโปรเจ็กต์ภายนอกต้องเป็น
ชื่อพื้นที่ทำงานที่ถูกต้อง
ขึ้นอยู่กับโปรเจ็กต์ที่ไม่ใช่ Bazel
กฎที่ขึ้นต้นด้วย new_
เช่น
new_local_repository
,
ช่วยให้คุณสร้างเป้าหมายจากโปรเจ็กต์ที่ไม่ใช้ Bazel
ตัวอย่างเช่น สมมติว่าคุณกำลังทำโครงการ my-project/
และคุณต้องการให้
จะขึ้นอยู่กับโปรเจ็กต์ของเพื่อนร่วมงานชื่อ coworkers-project/
ของเพื่อนร่วมงาน
โปรเจ็กต์ใช้ make
เพื่อสร้าง แต่คุณต้องการใช้ไฟล์ .so ไฟล์ใดไฟล์หนึ่ง
ที่คิดค้นขึ้น วิธีการคือ ให้เพิ่มค่าต่อไปนี้ลงใน my_project/WORKSPACE
new_local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
build_file = "coworker.BUILD",
)
build_file
ระบุไฟล์ BUILD
ที่จะวางซ้อนบนโปรเจ็กต์ที่มีอยู่
ตัวอย่าง:
cc_library(
name = "some-lib",
srcs = glob(["**"]),
visibility = ["//visibility:public"],
)
จากนั้นคุณสามารถใช้ @coworkers_project//:some-lib
จากโปรเจ็กต์ของคุณ
BUILD
ไฟล์
ขึ้นอยู่กับแพ็กเกจภายนอก
อาร์ติแฟกต์และที่เก็บของ Maven
ใช้ชุดกฎ rules_jvm_external
เพื่อดาวน์โหลดอาร์ติแฟกต์จากที่เก็บ Maven และทำให้พร้อมใช้งานเป็น Java
ทรัพยากร Dependency
กำลังดึงข้อมูลทรัพยากร Dependency
โดยค่าเริ่มต้น ระบบจะดึงข้อมูลทรัพยากร Dependency ภายนอกตามความจำเป็นในช่วง bazel build
ถ้า
คุณต้องการดึงข้อมูลทรัพยากร Dependency ที่จำเป็นสำหรับชุดเป้าหมายที่เฉพาะเจาะจงไว้ล่วงหน้า ให้ใช้
bazel fetch
หากต้องการดึงข้อมูลทรัพยากร Dependency ภายนอกทั้งหมดอย่างไม่มีเงื่อนไข ให้ใช้
bazel sync
เนื่องจากที่เก็บที่ดึงข้อมูลมาจัดเก็บไว้ในฐานเอาต์พุต โดยการดึงข้อมูล
จะเกิดขึ้นต่อพื้นที่ทำงาน
ทรัพยากร Dependency ที่ไม่มีการแก้ไข
ขอแนะนำให้มีนโยบายเวอร์ชันเดียวใน ซึ่งจำเป็นสำหรับทรัพยากร Dependency ที่คุณคอมไพล์และนำไปคอมไพล์ ในไบนารีสุดท้าย แต่ในกรณีที่ไม่เป็นความจริง เราอาจ ทรัพยากร Dependency ของเงา พิจารณาสถานการณ์ต่อไปนี้
โปรเจ็กต์ของฉัน/พื้นที่ทำงาน
workspace(name = "myproject")
local_repository(
name = "A",
path = "../A",
)
local_repository(
name = "B",
path = "../B",
)
พื้นที่ทำงาน
workspace(name = "A")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "...",
)
B/พื้นที่ทำงาน
workspace(name = "B")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
ทั้งทรัพยากร Dependency A
และ B
ต่างกันตรงที่ testrunner
แต่ทรัพยากรดังกล่าวขึ้นอยู่กับ
เวอร์ชันต่างๆ ของ testrunner
ไม่มีเหตุผลที่จะ
ไม่ได้อยู่ร่วมกันอย่างสงบภายใน myproject
แต่จะปะทะกับ
อื่นๆ เพราะมีชื่อเดียวกัน หากต้องการประกาศทรัพยากร Dependency ทั้ง 2 แบบ
อัปเดต myproject/WORKSPACE:
workspace(name = "myproject")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner-v1",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "..."
)
http_archive(
name = "testrunner-v2",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
local_repository(
name = "A",
path = "../A",
repo_mapping = {"@testrunner" : "@testrunner-v1"}
)
local_repository(
name = "B",
path = "../B",
repo_mapping = {"@testrunner" : "@testrunner-v2"}
)
นอกจากนี้ยังใช้กลไกนี้เพื่อรวมเพชรได้ด้วย ตัวอย่างเช่น หาก A
และ B
เดียวกันมีทรัพยากร Dependency เดียวกัน แต่เรียกด้วยชื่ออื่น ทรัพยากร Dependency เหล่านี้
เข้าร่วมได้ใน myproject/WORKSPACE
การลบล้างที่เก็บจากบรรทัดคำสั่ง
หากต้องการลบล้างที่เก็บที่ประกาศด้วยที่เก็บในเครื่องจากบรรทัดคำสั่ง
ให้ใช้
--override_repository
แจ้ง การใช้แฟล็กนี้จะเปลี่ยนแปลงเนื้อหาของที่เก็บภายนอกโดยไม่มี
การเปลี่ยนซอร์สโค้ดของคุณ
เช่น หากต้องการลบล้าง @foo
ในไดเรกทอรีในเครื่อง /path/to/local/foo
ผ่านแฟล็ก --override_repository=foo=/path/to/local/foo
ตัวอย่างกรณีการใช้งานมีดังนี้
- การแก้ปัญหา เช่น คุณลบล้างที่เก็บ
http_archive
ได้ ลงในไดเรกทอรีภายในเครื่อง เพื่อให้คุณทำการเปลี่ยนแปลงได้ง่ายขึ้น - ตัวแทนจำหน่ายรายย่อย หากคุณอยู่ในสภาพแวดล้อมที่ไม่สามารถเรียกใช้เครือข่าย ลบล้างกฎที่เก็บตามเครือข่ายเพื่อชี้ไปยังไดเรกทอรีในเครื่อง แทน
การใช้พร็อกซี
Bazel จะรับที่อยู่พร็อกซีจาก HTTPS_PROXY
และ HTTP_PROXY
ตัวแปรสภาพแวดล้อมและใช้ตัวแปรเหล่านี้เพื่อดาวน์โหลดไฟล์ HTTP/HTTPS (หากระบุ)
รองรับ IPv6
บนเครื่องที่ใช้ IPv6 เท่านั้น Bazel จะดาวน์โหลดทรัพยากร Dependency ที่มี
ไม่มีการเปลี่ยนแปลง อย่างไรก็ตาม สำหรับเครื่อง IPv4/IPv6 แบบ 2 สแต็ก Bazel จะใช้
แบบ Java: หากเปิดใช้งาน IPv4 แนะนำให้ใช้ IPv4 ในบางสถานการณ์
ตัวอย่างเช่น เมื่อเครือข่าย IPv4 ไม่สามารถแปลค่า/เข้าถึงที่อยู่ภายนอก
ซึ่งอาจทำให้เกิดข้อยกเว้น Network unreachable
รายการและเวอร์ชันของบิลด์ไม่สำเร็จ
ในกรณีเหล่านี้ คุณอาจลบล้างลักษณะการทำงานของ Bazel หากต้องการเลือกใช้ IPv6
โดยใช้พร็อพเพอร์ตี้ระบบ java.net.preferIPv6Addresses=true
กล่าวอย่างเจาะจงคือ
ใช้
--host_jvm_args=-Djava.net.preferIPv6Addresses=true
ตัวเลือกการเริ่มต้นใช้งาน เช่น ด้วยการเพิ่มบรรทัดต่อไปนี้ใน.bazelrc
ไฟล์:startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true
หากคุณใช้เป้าหมายบิลด์ Java ที่ต้องเชื่อมต่ออินเทอร์เน็ต (บางครั้งต้องมีการทดสอบการผสานรวม) ให้ใช้
--jvmopt=-Djava.net.preferIPv6Addresses=true
แฟล็กเครื่องมือ เช่น การมี บรรทัดต่อไปนี้ใน.bazelrc
ไฟล์ของคุณ:build --jvmopt=-Djava.net.preferIPv6Addresses
หากคุณกำลังใช้ rules_jvm_external, ตัวอย่างเช่น สำหรับการแปลงเวอร์ชันของทรัพยากร Dependency ให้เพิ่ม
-Djava.net.preferIPv6Addresses=true
ไปยังCOURSIER_OPTS
ตัวแปรสภาพแวดล้อมเพื่อระบุตัวเลือก JVM สำหรับ Coursier
ทรัพยากร Dependency แบบทรานซิทีฟ
Bazel จะอ่านเฉพาะทรัพยากร Dependency ที่ระบุไว้ในไฟล์ WORKSPACE
เท่านั้น หากโปรเจ็กต์ของคุณ
(A
) ขึ้นอยู่กับโปรเจ็กต์อื่น (B
) ซึ่งแสดงรายการทรัพยากร Dependency ของหนึ่งในสาม
โปรเจ็กต์ (C
) ในไฟล์ WORKSPACE
ของโปรเจ็กต์ คุณจะต้องเพิ่มทั้ง B
และ C
ลงในไฟล์ WORKSPACE
ของโครงการ ข้อกำหนดนี้อาจทำให้
ไฟล์ WORKSPACE
ขนาด แต่จำกัดโอกาสการมีไลบรารีเดียว
มี C
ในเวอร์ชัน 1.0 และอีกเวอร์ชันคือ C
เวอร์ชัน 2.0
การแคชทรัพยากร Dependency ภายนอก
โดยค่าเริ่มต้น Bazel จะดาวน์โหลดทรัพยากร Dependency ภายนอกใหม่ก็ต่อเมื่อ
เปลี่ยนคำจำกัดความ การเปลี่ยนแปลงไฟล์ที่อ้างอิงในคำจำกัดความ (เช่น แพตช์
หรือ BUILD
ไฟล์) จะได้รับการพิจารณาด้วย Bazel
หากต้องการบังคับให้ดาวน์โหลดใหม่ ให้ใช้ bazel sync
เลย์เอาต์
ระบบจะดาวน์โหลดทรัพยากร Dependency ภายนอกทั้งหมดไปยังไดเรกทอรีภายใต้ไดเรกทอรีย่อย
external
ในฐานเอาต์พุต ในกรณีที่
ที่เก็บในเครื่อง มีการสร้างลิงก์สัญลักษณ์
แทนการสร้างไดเรกทอรีใหม่
คุณดูไดเรกทอรี external
ได้โดยเรียกใช้สิ่งต่อไปนี้
ls $(bazel info output_base)/external
โปรดทราบว่าการเรียกใช้ bazel clean
จะไม่ลบไฟล์ภายนอก
ไดเรกทอรี หากต้องการนำอาร์ติแฟกต์ภายนอกทั้งหมดออก ให้ใช้ bazel clean --expunge
บิลด์แบบออฟไลน์
บางครั้งการสร้างงานแบบออฟไลน์ก็เป็นไปตามความต้องการหรือจำเป็น สำหรับ
กรณีการใช้งานง่ายๆ เช่น การเดินทางบนเครื่องบิน
prefetching
ที่เก็บที่มี bazel fetch
หรือ bazel sync
ก็อาจเพียงพอแล้ว ยิ่งไปกว่านั้น
โดยใช้ตัวเลือก --nofetch
ทำให้สามารถปิดใช้การดึงข้อมูลที่เก็บเพิ่มเติม
ระหว่างการสร้าง
สำหรับบิลด์แบบออฟไลน์อย่างแท้จริง ซึ่งเป็นที่ที่ต้องจัดเตรียมไฟล์ที่จำเป็น
โดยเอนทิตีที่แตกต่างจาก bazel, bazel สนับสนุนตัวเลือก
--distdir
เมื่อกฎที่เก็บขอให้ Bazel ดึงข้อมูลไฟล์ผ่าน
ctx.download
หรือ
ctx.download_and_extract
และระบุแฮชผลรวมของไฟล์
ขั้นแรก bazel จะพิจารณาไดเรกทอรีที่ระบุโดยตัวเลือกนั้นสำหรับ
ไฟล์ที่ตรงกับชื่อฐานของ URL แรกที่ระบุ และใช้สำเนาในเครื่องนั้น
หากแฮชตรงกัน
Bazel เองก็ใช้เทคนิคนี้เพื่อกระตุ้นให้ทำงานแบบออฟไลน์จากการกระจาย
อาร์ติแฟกต์
แต่ทําโดยรวบรวมข้อมูลภายนอกที่จําเป็นทั้งหมด
ทรัพยากร Dependency
ภายใน
distdir_tar
แต่ bazel อนุญาตการดำเนินการตามคำสั่งที่กำหนดเองในกฎที่เก็บ โดยไม่ทราบว่าผู้ใช้โทรหาเครือข่ายหรือไม่ bazel จึงไม่มีตัวเลือก เพื่อบังคับใช้บิลด์แบบออฟไลน์โดยสมบูรณ์ ดังนั้นการทดสอบว่าบิลด์ทำงานได้อย่างถูกต้อง ในการออฟไลน์ จะต้องมีการบล็อกเครือข่ายจากภายนอก เช่นเดียวกับที่ bazel ทำใน การทดสอบ Bootstrap
แนวทางปฏิบัติแนะนำ
กฎที่เก็บ
โดยทั่วไปกฎที่เก็บควรมีหน้าที่ต่อไปนี้
- กำลังตรวจหาการตั้งค่าระบบและเขียนลงในไฟล์
- กำลังค้นหาแหล่งข้อมูลในส่วนอื่นๆ ของระบบ
- กำลังดาวน์โหลดทรัพยากรจาก URL
- กำลังสร้างหรือ Symlink ไฟล์ BUILD ลงในไดเรกทอรีที่เก็บภายนอก
หลีกเลี่ยงการใช้ repository_ctx.execute
เมื่อเป็นไปได้ เช่น เมื่อใช้ไฟล์ C++ ที่ไม่ใช่ Bazel
ไลบรารีที่มีบิลด์ที่ใช้Make ควรใช้ repository_ctx.download()
จากนั้น
เขียนไฟล์ BUILD ที่สร้าง แทนที่จะเรียกใช้ ctx.execute(["make"])
ให้ใช้ http_archive
เป็น git_repository
และ
new_git_repository
เหตุผลมีดังนี้
- กฎที่เก็บ Git ขึ้นอยู่กับ
git(1)
ของระบบในขณะที่เครื่องมือดาวน์โหลด HTTP สร้างขึ้น ลงใน Bazel และไม่มีทรัพยากร Dependency ของระบบ http_archive
รองรับรายการurls
เป็นมิเรอร์ และgit_repository
รองรับเฉพาะรายการremote
รายการเดียวhttp_archive
ใช้งานได้กับแคชที่เก็บ แต่ไม่สามารถใช้ได้กับgit_repository
โปรดดู #5116 เพื่อดูข้อมูลเพิ่มเติม
อย่าใช้ bind()
โปรดดู "โปรดพิจารณาการลบ
เชื่อมโยง" เป็นเวลานาน
การอภิปรายเกี่ยวกับประเด็นและทางเลือก