สร้างตัวแปร

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

ตัวแปรเหล่านี้สามารถใช้ได้ เช่น เพื่อแทรกเส้นทาง Toolchain ที่เฉพาะเจาะจงลงใน การดำเนินการบิลด์ที่ผู้ใช้สร้างขึ้น

Bazel มีทั้งตัวแปร ที่กำหนดไว้ล่วงหน้า ซึ่งใช้ได้กับเป้าหมายทั้งหมด และตัวแปร ที่กำหนดเอง ซึ่งกำหนดไว้ในเป้าหมายทรัพยากร Dependency และใช้ได้เฉพาะกับเป้าหมายที่ขึ้นต่อกันเท่านั้น

เหตุผลที่ใช้คำว่า "Make" เป็นเพราะเหตุผลทางประวัติศาสตร์ โดยเดิมทีไวยากรณ์และความหมายของ ตัวแปรเหล่านี้มีไว้เพื่อให้ตรงกับ GNU Make

ใช้

แอตทริบิวต์ที่ทำเครื่องหมายเป็น "Subject to 'Make variable' substitution" สามารถ อ้างอิงตัวแปร "Make" FOO ได้ดังนี้

my_attr = "prefix $(FOO) suffix"

กล่าวอีกนัยหนึ่งคือ สตริงย่อยใดก็ตามที่ตรงกับ $(FOO) จะขยาย เป็นค่าของ FOO หากค่าดังกล่าวเป็น "bar" สตริงสุดท้าย จะเป็นดังนี้

my_attr = "prefix bar suffix"

หาก FOO ไม่ตรงกับตัวแปรที่เป้าหมายที่ใช้รู้จัก Bazel จะล้มเหลวและแสดงข้อผิดพลาด

ตัวแปร "Make" ที่มีชื่อเป็นสัญลักษณ์ที่ไม่ใช่ตัวอักษร เช่น @, สามารถอ้างอิงได้โดยใช้เครื่องหมายดอลลาร์เท่านั้นโดยไม่ต้อง ใส่วงเล็บ เช่น

my_attr = "prefix $@ suffix"

หากต้องการเขียน $ เป็นสตริงตัวอักษร (เช่น เพื่อป้องกันการขยายตัวแปร ) ให้เขียน $$

ตัวแปรที่กำหนดไว้ล่วงหน้า

ตัวแปร "Make" ที่กำหนดไว้ล่วงหน้าสามารถอ้างอิงได้โดยแอตทริบิวต์ใดก็ตามที่ทำเครื่องหมายเป็น "Subject to 'Make variable' substitution" ในเป้าหมายใดก็ได้

หากต้องการดูรายการตัวแปรเหล่านี้และค่าของตัวแปรสำหรับชุดตัวเลือกบิลด์ ที่กำหนด ให้เรียกใช้คำสั่ง

bazel info --show_make_env [build options]

แล้วดูบรรทัดเอาต์พุตด้านบนที่มีตัวอักษรตัวพิมพ์ใหญ่

ดูตัวอย่างตัวแปรที่กำหนดไว้ล่วงหน้า

ตัวแปรตัวเลือก Toolchain

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

  • BINDIR: ฐานของแผนผังไบนารีที่สร้างขึ้นสำหรับสถาปัตยกรรมเป้าหมาย

    โปรดทราบว่าระบบอาจใช้แผนผังอื่นสำหรับโปรแกรมที่ทำงานระหว่าง บิลด์ในสถาปัตยกรรมโฮสต์ เพื่อรองรับการคอมไพล์ข้าม

    หากต้องการเรียกใช้เครื่องมือจากภายใน genrule วิธีที่แนะนำในการรับเส้นทางของเครื่องมือคือ $(execpath toolname) โดย toolname ต้องแสดงอยู่ในแอตทริบิวต์ tools ของ genrule

  • GENDIR: ฐานของแผนผังโค้ดที่สร้างขึ้นสำหรับสถาปัตยกรรมเป้าหมาย

ตัวแปรสถาปัตยกรรมเครื่อง

  • TARGET_CPU: CPU ของสถาปัตยกรรมเป้าหมาย เช่น k8

ตัวแปร genrule ที่กำหนดไว้ล่วงหน้า

ตัวแปรต่อไปนี้ใช้ได้กับแอตทริบิวต์ genrule's cmd โดยเฉพาะ และ โดยทั่วไปแล้วมีความสำคัญต่อการทำให้แอตทริบิวต์ดังกล่าวทำงานได้

ดูตัวอย่างตัวแปร genrule ที่กำหนดไว้ล่วงหน้า

  • OUTS: รายการ outs ของ genrule หากมีไฟล์เอาต์พุตเพียงไฟล์เดียว คุณจะใช้ $@ ก็ได้
  • SRCS: รายการ srcs ของ genrule (หรือพูดให้ถูกต้องคือ ชื่อเส้นทางของไฟล์ที่ตรงกับป้ายกำกับในรายการ srcs) หากมีไฟล์ต้นฉบับเพียงไฟล์เดียว คุณจะใช้ $< ก็ได้
  • <: SRCS หากเป็นไฟล์เดียว หากไม่เป็นเช่นนั้น ระบบจะทริกเกอร์ ข้อผิดพลาดบิลด์
  • @: OUTS หากเป็นไฟล์เดียว หากไม่เป็นเช่นนั้น ระบบจะทริกเกอร์ข้อผิดพลาดบิลด์
  • RULEDIR: ไดเรกทอรีเอาต์พุตของเป้าหมาย ซึ่งก็คือไดเรกทอรีที่ตรงกับชื่อแพ็กเกจที่มีเป้าหมายอยู่ใต้แผนผัง genfiles หรือ bin สำหรับ //my/pkg:my_genrule ตัวแปรนี้จะลงท้ายด้วย my/pkg, เสมอ แม้ว่าเอาต์พุตของ //my/pkg:my_genrule's จะอยู่ในไดเรกทอรีย่อยก็ตาม

  • @D: ไดเรกทอรีเอาต์พุต หาก outs มีรายการเดียว ตัวแปรนี้จะขยายเป็นไดเรกทอรีที่มีไฟล์ดังกล่าว หากมีหลายรายการ ตัวแปรนี้จะขยายเป็นไดเรกทอรีรากของแพ็กเกจในแผนผัง genfiles แม้ว่าไฟล์เอาต์พุตทั้งหมดจะอยู่ในไดเรกทอรีย่อยเดียวกันก็ตาม!

    หมายเหตุ: ใช้ RULEDIR แทน @D เนื่องจาก RULEDIR มีความหมายที่ง่ายกว่าและทำงานในลักษณะเดียวกัน ไม่ว่าจะมีไฟล์เอาต์พุตจำนวนเท่าใดก็ตาม

    หาก genrule ต้องสร้างไฟล์ชั่วคราวระดับกลาง (อาจเป็นผลจากการใช้เครื่องมืออื่นๆ เช่น คอมไพเลอร์) เครื่องมือควรพยายามเขียนไฟล์เหล่านั้นลงใน @D (แม้ว่าจะเขียนลงใน /tmp ได้ด้วย) และนำไฟล์ออกก่อนที่จะเสร็จสิ้น

    โดยเฉพาะอย่างยิ่งควรหลีกเลี่ยงการเขียนลงในไดเรกทอรีที่มีอินพุต เนื่องจากไดเรกทอรีเหล่านั้นอาจอยู่ในระบบไฟล์แบบอ่านอย่างเดียว แม้ว่าจะไม่ได้อยู่ในระบบไฟล์แบบอ่านอย่างเดียว การเขียนลงในไดเรกทอรีเหล่านั้นก็จะทำให้แผนผังแหล่งที่มาเสียหาย

ตัวแปรเส้นทางแหล่งที่มา/เอาต์พุตที่กำหนดไว้ล่วงหน้า

ตัวแปรที่กำหนดไว้ล่วงหน้า execpath, execpaths, rootpath, rootpaths, location, และ locations ใช้พารามิเตอร์ป้ายกำกับ (เช่น $(execpath //foo:bar)) และแทนที่เส้นทางไฟล์ที่ระบุโดยป้ายกำกับนั้น

สำหรับไฟล์ต้นฉบับ เส้นทางนี้จะเป็นเส้นทางที่สัมพันธ์กับรากของพื้นที่ทำงาน สำหรับไฟล์ที่เป็นเอาต์พุตของกฎ เส้นทางนี้จะเป็น เส้นทางเอาต์พุต ของไฟล์ (ดูคำอธิบาย ไฟล์เอาต์พุตด้านล่าง)

ดูตัวอย่างตัวแปรเส้นทางที่กำหนดไว้ล่วงหน้า

  • execpath: ระบุเส้นทางใต้ execroot ที่ Bazel เรียกใช้การดำเนินการบิลด์

    ในตัวอย่างด้านบน Bazel จะเรียกใช้การดำเนินการบิลด์ทั้งหมดในไดเรกทอรีที่ลิงก์ โดย bazel-myproject ลิงก์สัญลักษณ์ ในรากของพื้นที่ทำงาน ไฟล์ต้นฉบับ empty.source จะลิงก์อยู่ที่เส้นทาง bazel-myproject/testapp/empty.source ดังนั้นเส้นทาง exec (ซึ่ง คือเส้นทางย่อยใต้ราก) คือ 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 ดังนั้นเส้นทาง exec จึงเป็น 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 เป็นแนวทางที่แนะนำในการค้นหาการขึ้นต่อกันในขณะรันไทม์ เมื่อเทียบกับ rootpath ตัวแปรนี้มีข้อดีตรงที่ทำงานได้ในทุกแพลตฟอร์มและแม้ว่าจะไม่มีไดเรกทอรี runfiles ก็ตาม

    ตัวแปรนี้มีข้อกำหนด "เอาต์พุตเดียวเท่านั้น" เหมือนกับ execpath

  • location: คำพ้องความหมายของ execpath หรือ rootpath ขึ้นอยู่กับแอตทริบิวต์ที่ขยาย ตัวแปรนี้เป็น ลักษณะการทำงานก่อน Starlark แบบเดิมและไม่แนะนำให้ใช้ เว้นแต่คุณจะทราบอย่างแน่ชัดว่าตัวแปรนี้ทำอะไรสำหรับกฎที่เฉพาะเจาะจง ดูรายละเอียดได้ที่ #2475

execpaths, rootpaths, rlocationpaths, และ locations เป็นรูปแบบพหูพจน์ของ execpath, rootpath, rlocationpaths และlocation, ตามลำดับ ตัวแปรเหล่านี้รองรับป้ายกำกับที่สร้างเอาต์พุตหลายรายการ ในกรณีนี้ ระบบจะแสดงเอาต์พุตแต่ละรายการโดยคั่นด้วยช่องว่าง กฎที่ไม่มีเอาต์พุตและป้ายกำกับที่มีรูปแบบไม่ถูกต้อง จะทำให้เกิดข้อผิดพลาดบิลด์

ป้ายกำกับที่อ้างอิงทั้งหมดต้องปรากฏใน srcs ไฟล์เอาต์พุต หรือ deps ของเป้าหมายที่ใช้ หากไม่เป็นเช่นนั้น บิลด์จะล้มเหลว เป้าหมาย C++ ยังอ้างอิงป้ายกำกับใน data ได้ด้วย

ป้ายกำกับไม่จำเป็นต้องอยู่ในรูปแบบ Canonical โดย foo, :foo และ //somepkg:foo ล้วนใช้ได้

ตัวแปรที่กำหนดเอง

ตัวแปร "Make" ที่กำหนดเองสามารถอ้างอิงได้โดยแอตทริบิวต์ใดก็ตามที่ทำเครื่องหมายเป็น "Subject to 'Make variable' substitution", แต่เฉพาะในเป้าหมายที่ ขึ้นต่อกันกับเป้าหมายอื่นๆ ที่ กำหนด ตัวแปรเหล่านี้

แนวทางปฏิบัติแนะนำคือตัวแปรทั้งหมดควรเป็นตัวแปรที่กำหนดเอง เว้นแต่จะมีเหตุผลที่สมควร ในการรวมตัวแปรเหล่านั้นไว้ใน Bazel หลัก วิธีนี้จะช่วยให้ Bazel ไม่ต้องโหลด การขึ้นต่อกันที่มีค่าใช้จ่ายสูงซึ่งเป้าหมายที่ใช้ตัวแปรอาจ ไม่สนใจ

ตัวแปร Toolchain ของ C++

ตัวแปรต่อไปนี้กำหนดไว้ในกฎ Toolchain ของ C++ และใช้ได้กับกฎใดก็ตาม ที่ตั้งค่า toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"] กฎบางอย่าง เช่น java_binary จะรวม Toolchain ของ C++ ไว้ในคำจำกัดความกฎโดยนัย กฎเหล่านั้นจะรับช่วงตัวแปรเหล่านี้ โดยอัตโนมัติ

กฎ C++ ในตัวมีความซับซ้อนมากกว่า "เรียกใช้คอมไพเลอร์ใน กฎ" มาก เพื่อให้รองรับโหมดการคอมไพล์ที่หลากหลาย เช่น *SAN, ThinLTO, with/without modules และไบนารีที่ปรับให้เหมาะสมอย่างระมัดระวัง รวมถึงการเรียกใช้การทดสอบอย่างรวดเร็วในหลายแพลตฟอร์มพร้อมกัน กฎในตัวจึงพยายามอย่างเต็มที่เพื่อให้แน่ใจว่าได้ตั้งค่าอินพุต เอาต์พุต และแฟล็กบรรทัดคำสั่งที่ถูกต้องในการดำเนินการที่สร้างขึ้นภายในซึ่งอาจมีหลายรายการ

ตัวแปรเหล่านี้เป็นกลไกการทำงานแบบย้อนกลับที่ผู้เชี่ยวชาญด้านภาษาใช้ใน กรณีที่พบได้ยาก หากคุณต้องการใช้ตัวแปรเหล่านี้ โปรด ติดต่อทีมพัฒนา Bazel ก่อน

  • ABI: เวอร์ชัน ABI ของ C++
  • AR: คำสั่ง "ar" จาก crosstool
  • C_COMPILER: ตัวระบุคอมไพเลอร์ C/C++ เช่น llvm
  • CC: คำสั่งคอมไพเลอร์ C และ C++

    เราขอแนะนำอย่างยิ่งให้ใช้ CC_FLAGS ร่วมกับ CC เสมอ หากไม่ทำเช่นนั้น คุณต้องยอมรับความเสี่ยงเอง

  • CC_FLAGS: ชุดแฟล็กขั้นต่ำสำหรับคอมไพเลอร์ C/C++ ที่ genrule ใช้ได้ โดยเฉพาะอย่างยิ่ง ตัวแปรนี้มีแฟล็กสำหรับ เลือกสถาปัตยกรรมที่ถูกต้องหาก CC รองรับหลาย สถาปัตยกรรม
  • NM: คำสั่ง "nm" จาก crosstool
  • OBJCOPY: คำสั่ง objcopy จากชุดเดียวกับคอมไพเลอร์ C/C++
  • STRIP: คำสั่ง 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 ซึ่งเครื่องมือต้นน้ำไม่สามารถแสดงได้ เช่น อินเทอร์เฟซ Jar, อินเทอร์เฟซส่วนหัว Jar รวมถึงการใช้งานการสร้างแพ็กเกจและการผสาน Jar ที่ปรับให้เหมาะสมอย่างมาก

ตัวแปรเหล่านี้เป็นกลไกการทำงานแบบย้อนกลับที่ผู้เชี่ยวชาญด้านภาษาใช้ใน กรณีที่พบได้ยาก หากคุณต้องการใช้ตัวแปรเหล่านี้ โปรด ติดต่อทีมพัฒนา Bazel ก่อน

  • JAVA: คำสั่ง "java" (Java Virtual machine) หลีกเลี่ยงการใช้คำสั่งนี้และใช้กฎ java_binary แทนหากเป็นไปได้ อาจเป็นเส้นทางที่สัมพันธ์กัน หากต้องเปลี่ยน ไดเรกทอรีก่อนเรียกใช้ java คุณจะต้องบันทึก ไดเรกทอรีการทำงานก่อนที่จะเปลี่ยน
  • JAVABASE: ไดเรกทอรีฐานที่มียูทิลิตี Java อาจเป็นเส้นทางที่สัมพันธ์กัน โดยจะมีไดเรกทอรีย่อย "bin" subdirectory.

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

ผู้เขียนกฎและ Toolchain สามารถกำหนดตัวแปรที่กำหนดเองได้อย่างสมบูรณ์โดยการแสดงผลผู้ให้บริการ TemplateVariableInfo กฎใดก็ตามที่ขึ้นต่อกันกับตัวแปรเหล่านี้ผ่านแอตทริบิวต์ toolchains จะอ่านค่าของตัวแปรได้ดังนี้

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