ตัวแปร "ผู้ผลิต"

ตัวแปร "สร้าง" เป็นคลาสพิเศษของตัวแปรสตริงที่ขยายได้ซึ่งพร้อมใช้งานสำหรับแอตทริบิวต์ที่มีเครื่องหมาย "อยู่ภายใต้การแทนที่ "สร้างตัวแปร""

ตัวอย่างวิธีการเหล่านี้อาจใช้เพื่อแทรกเส้นทาง 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

ตัวแปรเส้นทาง

  • 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/app

    rootpath ของไฟล์ในที่เก็บภายนอก repo จะขึ้นต้นด้วย ../repo/ ตามด้วยเส้นทางที่สัมพันธ์กับที่เก็บ

    ซึ่งมีข้อกำหนด "เอาต์พุตเดียวเท่านั้น" เช่นเดียวกับ execpath

  • rlocationpath: เส้นทางที่ไบนารีที่สร้างจะส่งผ่านไปยังฟังก์ชัน Rlocation ของไลบรารี Runfiles เพื่อค้นหาทรัพยากร Dependency ขณะรันไทม์ ไม่ว่าจะในไดเรกทอรี Runfiles (หากมี) หรือใช้ไฟล์ Manifest ของ Runfiles

    ชื่อนี้คล้ายกับ rootpath ตรงที่ไม่มีคำนำหน้าการกำหนดค่า แต่แตกต่างตรงที่คำนำหน้าจะเริ่มต้นด้วยชื่อของที่เก็บเสมอ ในตัวอย่างข้างต้น หมายความว่า empty.source และ app ให้ผลลัพธ์ในเส้นทางต่อไปนี้ myproject/testapp/empty.source และ myproject/testapp/app

    rlocationpath ของไฟล์ในที่เก็บภายนอก 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 จะอ่านค่าได้

ดูตัวอย่างตัวแปรที่กำหนดโดย Starlark