- การใช้งาน
- ตัวแปรที่กำหนดไว้ล่วงหน้า
- ตัวแปร Genrule ที่กำหนดไว้ล่วงหน้า
- ตัวแปรเส้นทางแหล่งที่มา/เอาต์พุตที่กำหนดไว้ล่วงหน้า
- ตัวแปรที่กำหนดเอง
ตัวแปร "สร้าง" เป็นคลาสพิเศษของตัวแปรสตริงที่ขยายได้ซึ่งพร้อมใช้งานสำหรับแอตทริบิวต์ที่มีเครื่องหมาย "อยู่ภายใต้การแทนที่ "สร้างตัวแปร""
ตัวอย่างวิธีการเหล่านี้อาจใช้เพื่อแทรกเส้นทาง Toolchain ที่เฉพาะเจาะจงลงในการทำงานของบิลด์ที่ผู้ใช้สร้างได้
Bazel มีทั้งตัวแปรที่กำหนดไว้ล่วงหน้า ซึ่งมีให้กับเป้าหมายทั้งหมด และตัวแปรที่กำหนดเองซึ่งระบุไว้ในเป้าหมายการอ้างอิงและใช้ได้เฉพาะกับเป้าหมายที่อ้างอิงตัวแปรเหล่านี้เท่านั้น
เหตุผลของคำว่า "Make" คือข้อมูลย้อนหลัง: ไวยากรณ์และความหมายของตัวแปรเหล่านี้เดิมมีจุดประสงค์เพื่อให้ตรงกับ GNU Make
ใช้
แอตทริบิวต์ที่ทำเครื่องหมายว่า "อยู่ภายใต้การแทนที่ "สร้างตัวแปร"" สามารถอ้างอิงตัวแปร "ผู้ผลิต" FOO ดังนี้
my_attr = "prefix $(FOO) suffix"
กล่าวคือ ระบบจะขยายสตริงย่อยที่ตรงกับ $(FOO) ไปยังค่าของ FOO หากค่านั้นเป็น "bar" สตริงสุดท้ายจะกลายเป็น:
my_attr = "prefix bar suffix"
หาก FOO ไม่ตรงกับตัวแปรที่รู้จักกับเป้าหมายการบริโภค Bazel จะล้มเหลวโดยมีข้อผิดพลาด
นอกจากนี้ ตัวแปร "Make" ที่มีชื่อที่ไม่ใช่สัญลักษณ์ เช่น @ จะอ้างอิงได้โดยใช้เพียงสัญลักษณ์ดอลลาร์เท่านั้นโดยไม่ต้องมีวงเล็บ เช่น
my_attr = "prefix $@ suffix"
หากต้องการเขียน $ เป็นสตริงลิเทอรัล (นั่นคือเพื่อป้องกันการขยายตัวแปร) ให้เขียน $$
ตัวแปรที่กำหนดไว้ล่วงหน้า
ตัวแปร "สร้าง" ที่กำหนดไว้ล่วงหน้าสามารถอ้างอิงโดยแอตทริบิวต์ที่ทำเครื่องหมายเป็น "อยู่ภายใต้การแทนที่ "ตัวแปร"" ในทุกเป้าหมายได้
หากต้องการดูรายการตัวแปรเหล่านี้และค่าของตัวแปรสำหรับชุดตัวเลือกบิลด์ที่กำหนด ให้เรียกใช้
bazel info --show_make_env [build options]
และดูที่บรรทัดเอาต์พุตด้านบนโดยใช้อักษรตัวพิมพ์ใหญ่
ดูตัวอย่างตัวแปรที่กำหนดไว้ล่วงหน้า
ตัวแปรตัวเลือกของToolchain
COMPILATION_MODE:fastbuild,dbgหรือopt(รายละเอียดเพิ่มเติม)
ตัวแปรเส้นทาง
-
BINDIR: ฐานของแผนผังไบนารีที่สร้างขึ้นสำหรับสถาปัตยกรรมเป้าหมายโปรดทราบว่าอาจมีการใช้ต้นไม้ที่ต่างกันสำหรับโปรแกรมที่ทำงานระหว่าง บิลด์บนสถาปัตยกรรมโฮสต์ เพื่อรองรับการคอมไพล์ข้าม
หากต้องการเรียกใช้เครื่องมือจากภายใน
genruleวิธีที่แนะนำเพื่อรับเส้นทางคือ$(execpath toolname)โดยที่ ชื่อเครื่องมือ ต้องแสดงในแอตทริบิวต์toolsของgenrule GENDIR: ฐานของแผนผังโค้ดที่สร้างขึ้นสำหรับสถาปัตยกรรมเป้าหมาย
ตัวแปรสถาปัตยกรรมเครื่อง
-
TARGET_CPU: CPU ของสถาปัตยกรรมเป้าหมาย เช่นk8
ตัวแปร Genrule ที่กำหนดไว้ล่วงหน้า
ค่าต่อไปนี้พร้อมใช้งานสำหรับแอตทริบิวต์ cmd ของ genrule โดยเฉพาะ และโดยทั่วไปแล้วมีความสำคัญต่อการทำงานของแอตทริบิวต์ดังกล่าว
ดูตัวอย่างตัวแปร Genrule ที่กำหนดไว้ล่วงหน้า
OUTS: รายการoutsของgenruleคุณจะใช้$@ได้ด้วยหากมีไฟล์เอาต์พุตเพียงไฟล์เดียว-
SRCS: รายการsrcsของgenrule(หรือที่ชัดเจนกว่านั้นคือ ชื่อเส้นทางของไฟล์ที่เกี่ยวข้องกับป้ายกำกับในรายการsrcs) หากคุณมีไฟล์ต้นฉบับเพียงไฟล์เดียว คุณยังสามารถใช้$<ได้อีกด้วย -
<:SRCSหากเป็นไฟล์เดียว มิเช่นนั้นจะทำให้เกิดข้อผิดพลาดของบิลด์ -
@:OUTSหากเป็นไฟล์เดียว ไม่เช่นนั้นจะทริกเกอร์ข้อผิดพลาดของบิลด์ -
RULEDIR: ไดเรกทอรีเอาต์พุตของเป้าหมาย ซึ่งก็คือไดเรกทอรีที่ตรงกับชื่อของแพ็กเกจที่มีเป้าหมายใต้ต้นไม้genfilesหรือbinสำหรับ//my/pkg:my_genruleจะลงท้ายด้วยmy/pkgเสมอ แม้ว่าเอาต์พุตของ//my/pkg:my_genruleจะอยู่ในไดเรกทอรีย่อยก็ตาม -
@D: ไดเรกทอรีเอาต์พุต หาก outs มีรายการ 1 รายการ การดำเนินการนี้จะขยายไปยังไดเรกทอรีที่มีไฟล์นั้น หากมีหลายรายการ การดำเนินการนี้จะขยายไปยังไดเรกทอรีรากของแพ็กเกจในต้นไม้genfilesแม้ว่าไฟล์เอาต์พุตทั้งหมดจะอยู่ในไดเรกทอรีย่อยเดียวกันก็ตามหมายเหตุ: ใช้
RULEDIRใน@Dเนื่องจากRULEDIRมีความหมายที่เรียบง่ายกว่าและจะทำงานเหมือนกัน โดยไม่คำนึงถึงจำนวนไฟล์เอาต์พุตหากการสร้างไฟล์กลางชั่วคราว (อาจเป็นผลจากการใช้เครื่องมืออื่น เช่น คอมไพเลอร์) ระบบควรพยายามเขียนไฟล์ดังกล่าวใน
@D(แต่/tmpจะเขียนได้ด้วยเช่นกัน) และนำออกก่อนที่จะเสร็จสิ้นโดยเฉพาะอย่างยิ่ง ให้หลีกเลี่ยงการเขียนในไดเรกทอรีที่มีอินพุต โดยไฟล์เหล่านั้นอาจอยู่ในระบบไฟล์แบบอ่านอย่างเดียว แม้ว่าจะไม่ได้ทำเช่นนั้น การทำเช่นนั้นจะเป็นการทิ้งโครงสร้างต้นทาง
ตัวแปรเส้นทางแหล่งที่มา/เอาต์พุตที่กำหนดไว้ล่วงหน้า
ตัวแปรที่กำหนดไว้ล่วงหน้า execpath, execpaths, rootpath, rootpaths, location และ locations จะใช้พารามิเตอร์ป้ายกำกับ (เช่น $(execpath
//foo:bar)) และแทนที่เส้นทางไฟล์ซึ่งระบุโดยป้ายกำกับนั้น
สำหรับไฟล์ต้นฉบับ นี่คือเส้นทางที่เกี่ยวข้องกับรูทของพื้นที่ทำงาน สำหรับไฟล์ที่เป็นเอาต์พุตของกฎ นี่คือเส้นทางเอาต์พุตของไฟล์ (ดูคำอธิบายของไฟล์เอาต์พุตด้านล่าง)
ดูตัวอย่างตัวแปรเส้นทางที่กำหนดไว้ล่วงหน้า
-
execpath: แสดงถึงเส้นทางใต้ execroot โดยที่ Bazel เรียกใช้การดำเนินการของบิลด์ในตัวอย่างข้างต้น Bazel จะเรียกใช้การดำเนินการบิลด์ทั้งหมดในไดเรกทอรีที่ลิงก์โดย symlink ของ
bazel-myprojectในรูทของพื้นที่ทำงาน ไฟล์แหล่งที่มาempty.sourceลิงก์อยู่ที่เส้นทางbazel-myproject/testapp/empty.sourceดังนั้นเส้นทางการดำเนินการ (ซึ่งเป็นเส้นทางย่อยใต้รูท) จึงเป็นtestapp/empty.sourceนี่คือการดำเนินการบิลด์เส้นทางที่ใช้ค้นหาไฟล์ได้ไฟล์เอาต์พุตมีการจัดระยะคล้ายกัน แต่จะมีเส้นทางย่อย
bazel-out/cpu-compilation_mode/binนำหน้าด้วย (หรือสำหรับเอาต์พุตของเครื่องมือ:bazel-out/cpu-opt-exec-hash/bin) ในตัวอย่างด้านบน//testapp:appเป็นเครื่องมือเพราะปรากฏในแอตทริบิวต์toolsของshow_app_outputดังนั้นไฟล์เอาต์พุตappจะถูกเขียนไปยังbazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/appเส้นทางการดำเนินการจึงเป็นbazel-out/cpu-opt-exec-hash/bin/testapp/appคำนำหน้าเพิ่มเติมนี้ช่วยให้สร้างเป้าหมายเดียวกันได้ เช่น สำหรับ CPU 2 ตัวที่แตกต่างกันในบิลด์เดียวกันโดยไม่ทำให้ผลลัพธ์ขัดแย้งกันป้ายกำกับที่ส่งไปยังตัวแปรนี้ต้องแสดงถึงไฟล์เดียวเท่านั้น สำหรับป้ายกำกับที่แสดงถึงไฟล์ต้นฉบับ จะเป็นจริงโดยอัตโนมัติ สำหรับป้ายกำกับที่แสดงถึงกฎ กฎดังกล่าวจะต้องสร้างเอาต์พุตเพียงรายการเดียว หากนี่เป็น เท็จหรือป้ายกำกับผิดรูปแบบ บิลด์จะล้มเหลวโดยมีข้อผิดพลาด
-
rootpath: แสดงถึงเส้นทางที่ไบนารีที่สร้างขึ้นจะใช้ค้นหาทรัพยากร Dependency ในรันไทม์ที่สัมพันธ์กับไดเรกทอรีย่อยของไดเรกทอรี Runfiles ของที่เก็บหลัก หมายเหตุ: การดำเนินการนี้จะใช้ได้เมื่อเปิดใช้--enable_runfilesเท่านั้น ซึ่งจะไม่เป็นเช่นนั้นใน Windows โดยค่าเริ่มต้น โปรดใช้rlocationpathแทนสำหรับการรองรับข้ามแพลตฟอร์มซึ่งคล้ายกับ
execpathแต่จะลบคำนำหน้าการกำหนดค่าที่อธิบายข้างต้น ในตัวอย่างข้างต้นหมายความว่าทั้งempty.sourceและappใช้เส้นทางที่สัมพันธ์กับพื้นที่ทำงานทั้งหมด ได้แก่testapp/empty.sourceและtestapp/approotpathของไฟล์ในที่เก็บภายนอกrepoจะขึ้นต้นด้วย../repo/ตามด้วยเส้นทางที่สัมพันธ์กับที่เก็บซึ่งมีข้อกำหนด "เอาต์พุตเดียวเท่านั้น" เช่นเดียวกับ
execpath -
rlocationpath: เส้นทางที่ไบนารีที่สร้างจะส่งผ่านไปยังฟังก์ชันRlocationของไลบรารี Runfiles เพื่อค้นหาทรัพยากร Dependency ขณะรันไทม์ ไม่ว่าจะในไดเรกทอรี Runfiles (หากมี) หรือใช้ไฟล์ Manifest ของ Runfilesชื่อนี้คล้ายกับ
rootpathตรงที่ไม่มีคำนำหน้าการกำหนดค่า แต่แตกต่างตรงที่คำนำหน้าจะเริ่มต้นด้วยชื่อของที่เก็บเสมอ ในตัวอย่างข้างต้น หมายความว่าempty.sourceและappให้ผลลัพธ์ในเส้นทางต่อไปนี้myproject/testapp/empty.sourceและmyproject/testapp/apprlocationpathของไฟล์ในที่เก็บภายนอกrepoจะขึ้นต้นด้วยrepo/ตามด้วยเส้นทางที่สัมพันธ์กับที่เก็บการส่งเส้นทางนี้ไปยังไบนารีและแปลค่าไปยังเส้นทางระบบไฟล์โดยใช้ไลบรารี Runfiles เป็นวิธีที่แนะนำในการค้นหาทรัพยากร Dependency ขณะรันไทม์ เมื่อเทียบกับ
rootpathจะมีข้อดีตรงที่ทำงานกับทุกแพลตฟอร์มและแม้ว่าไดเรกทอรี Runfiles จะไม่พร้อมใช้งานซึ่งมีข้อกำหนด "เอาต์พุตเดียวเท่านั้น" เช่นเดียวกับ
execpath -
location: คำพ้องความหมายสำหรับexecpathหรือrootpathขึ้นอยู่กับแอตทริบิวต์ที่กำลังขยาย นี่เป็นลักษณะการทำงานของ Pre-Stark แบบเดิม ซึ่งไม่แนะนำ เว้นแต่คุณจะรู้ว่าจริงๆ แล้วจะส่งผลอย่างไรสำหรับกฎหนึ่งๆ ดูรายละเอียดได้ที่ #2475
execpaths, rootpaths, rlocationpaths และ locations เป็นรูปแบบพหูพจน์ของ execpath, rootpath, rlocationpaths และlocation ตามลำดับ โดยรองรับป้ายกำกับที่สร้างเอาต์พุตหลายรายการ ซึ่งในกรณีนี้แต่ละเอาต์พุตจะแสดงรายการแยกกันด้วยการเว้นวรรค กฎที่มีเอาต์พุตเป็นศูนย์และป้ายกำกับที่มีรูปแบบไม่ถูกต้องจะทำให้สร้างข้อผิดพลาดของบิลด์
ป้ายกำกับที่อ้างอิงทั้งหมดต้องปรากฏใน srcs, ไฟล์เอาต์พุต หรือ deps ของเป้าหมายที่ใช้ มิฉะนั้นการสร้างจะล้มเหลว เป้าหมาย C++ จะอ้างอิงป้ายกำกับใน data ได้ด้วย
ป้ายกำกับไม่จำเป็นต้องอยู่ในรูปแบบ Canonical foo, :foo และ //somepkg:foo ก็ใช้งานได้
ตัวแปรที่กำหนดเอง
คุณจะอ้างอิงตัวแปร "ผู้ผลิต" ที่กำหนดเองโดยแอตทริบิวต์ที่ทำเครื่องหมายว่า "อยู่ภายใต้การแทนที่ 'สร้างตัวแปร'" ได้ แต่จะอยู่ในเป้าหมายที่ขึ้นอยู่กับเป้าหมายอื่นที่กำหนดตัวแปรเหล่านี้เท่านั้น
ตามแนวทางปฏิบัติแนะนํา ตัวแปรทั้งหมดควรกําหนดเอง เว้นแต่จะมีเหตุผลที่ดีจริงๆ ที่จะต้องทำให้ตัวแปรเหล่านั้นเป็น Bazel หลัก วิธีนี้ช่วยให้ Bazel ไม่ต้องโหลดทรัพยากร Dependency ที่อาจมีราคาแพงเพื่อรองรับตัวแปรที่ใช้ทาเร็ตอาจไม่สนใจ
ตัวแปร Toolchain ของ C++
สิ่งต่อไปนี้มีการกำหนดไว้ในกฎ Toolchain ของ C++ และใช้ได้กับกฎใดๆ ที่กำหนด
toolchains =
["@bazel_tools//tools/cpp:current_cc_toolchain"] (หรือ
"@bazel_tools//tools/cpp:current_cc_host_toolchain"
สำหรับรายการเทียบเท่าใน Toolchain ของโฮสต์) กฎบางอย่าง เช่น java_binary จะรวมห่วงโซ่เครื่องมือ C++ ไว้ในคำจำกัดความของกฎโดยปริยาย โดยจะรับค่าตัวแปรเหล่านี้โดยอัตโนมัติ
กฎ C++ ในตัวมีความซับซ้อนกว่าการ "เรียกใช้คอมไพเลอร์" มาก กฎในตัวต้องใช้ระยะเวลาที่เหมาะสมในการตรวจสอบว่าอินพุต เอาต์พุต และแฟล็กบรรทัดคำสั่งที่ถูกต้องในแต่ละการดำเนินการที่อาจเกิดขึ้นภายใน เพื่อรองรับโหมดการคอมไพล์ได้หลากหลายแบบอย่าง *SAN, ThinLTO, แบบมี/ไม่มีโมดูล และไบนารีที่มีการเพิ่มประสิทธิภาพอย่างรอบคอบในเวลาเดียวกันกับการทดสอบการทำงานอย่างรวดเร็วในหลายแพลตฟอร์ม
ตัวแปรเหล่านี้เป็นกลไกสำรองซึ่งผู้เชี่ยวชาญด้านภาษาจะใช้ในบางกรณีซึ่งพบได้ไม่บ่อยนัก หากคุณอยากใช้ โปรดติดต่อนักพัฒนาแอป Bazel ก่อน
ABI: เวอร์ชัน ABI ของ C++-
AR: คำสั่ง "ar" จาก Crosstool -
C_COMPILER: ตัวระบุคอมไพเลอร์ C/C++ เช่นllvm -
CC: คำสั่งของคอมไพเลอร์ C และ C++เราขอแนะนำให้ใช้
CC_FLAGSร่วมกับCCเสมอ ไม่ดำเนินการดังกล่าวโดยแบกรับความเสี่ยงเอง CC_FLAGS: ชุดแฟล็กขั้นต่ำสำหรับคอมไพเลอร์ C/C++ ที่ genrules ใช้งานได้ กล่าวอย่างเจาะจงคือ คอลัมน์นี้มีแฟล็กให้เลือกสถาปัตยกรรมที่ถูกต้องหากCCรองรับสถาปัตยกรรมหลายรายการ-
NM: คำสั่ง "nm" จากcrosstool -
OBJCOPY: คำสั่ง objcopy จากชุดเดียวกันกับคอมไพเลอร์ C/C++ -
STRIP: คำสั่งตัดจากชุดโปรแกรมเดียวกันกับคอมไพเลอร์ C/C++
ตัวแปร Toolchain ของ Java
สิ่งต่อไปนี้กำหนดไว้ในกฎ Toolchain ของ Java และใช้ได้กับกฎใดๆ ที่กำหนด toolchains =
["@bazel_tools//tools/jdk:current_java_runtime"] (หรือ "@bazel_tools//tools/jdk:current_host_java_runtime" สำหรับรายการที่ตรงกันใน Toolchain ของโฮสต์)
ไม่ควรใช้เครื่องมือส่วนใหญ่ใน JDK โดยตรง กฎ Java ในตัวใช้วิธีการรวมและแพ็กเกจ Java ที่ซับซ้อนกว่ามากที่เครื่องมือแบบอัปสตรีมจะแสดงได้ เช่น Jars สำหรับอินเทอร์เฟซ, Jars อินเทอร์เฟซส่วนหัว และการใช้การรวมและการรวม Jar ที่เพิ่มประสิทธิภาพในระดับสูง
ตัวแปรเหล่านี้เป็นกลไกสำรองซึ่งผู้เชี่ยวชาญด้านภาษาจะใช้ในบางกรณีซึ่งพบได้ไม่บ่อยนัก หากคุณอยากใช้ โปรดติดต่อนักพัฒนาแอป Bazel ก่อน
-
JAVA: คำสั่ง "java" (เครื่องเสมือน Java) ให้หลีกเลี่ยงปัญหานี้และใช้กฎjava_binaryแทน หากทำได้ อาจเป็นเส้นทางแบบสัมพัทธ์ หากต้องเปลี่ยนไดเรกทอรีก่อนเรียกใช้javaคุณต้องบันทึกไดเรกทอรีที่ใช้งานอยู่ก่อนที่จะเปลี่ยน JAVABASE: ไดเรกทอรีฐานที่มียูทิลิตี Java อาจเป็นเส้นทางแบบสัมพัทธ์ ไดเรกทอรีดังกล่าวจะมีไดเรกทอรีย่อย "bin"
ตัวแปรที่กำหนดโดย Starlark
ผู้เขียนกฎและ toolchain ระบุตัวแปรที่กำหนดเองทั้งหมดได้โดยแสดงผลผู้ให้บริการ TemplateVariableInfo จากนั้นกฎที่ขึ้นอยู่กับกฎต่อไปนี้ผ่านแอตทริบิวต์ toolchains จะอ่านค่าได้