สร้างตัวแปร

รายงานปัญหา ดูแหล่งที่มา

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

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

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

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

ใช้

แอตทริบิวต์ที่ทําเครื่องหมายเป็น "ขึ้นอยู่กับการแทนที่ 'สร้างตัวแปร'" จะอ้างอิงตัวแปร "Make" FOO ได้ดังต่อไปนี้

my_attr = "prefix $(FOO) suffix"

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

my_attr = "prefix bar suffix"

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

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

my_attr = "prefix $@ suffix"

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

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

แอตทริบิวต์ที่ทำเครื่องหมายเป็น "ขึ้นอยู่กับการแทนที่ 'Makeตัวแปร'" ในเป้าหมายใดก็ได้อ้างอิงตัวแปร "Make" ที่กำหนดไว้ล่วงหน้า

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

bazel info --show_make_env [build options]

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

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

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

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

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

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

    หากต้องการเรียกใช้เครื่องมือจากภายใน genrule วิธีที่แนะนำในการรับเส้นทางคือ $(execpath toolname) โดยที่ 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 มีความหมายที่ง่ายกว่าและทํางานในลักษณะเดียวกันไม่ว่าจะมีไฟล์เอาต์พุตกี่รายการ

    หาก 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 ดังนั้นเส้นทางปฏิบัติการ (ซึ่งเป็นเส้นทางย่อยด้านล่างรูท) คือ 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 ตัวที่แตกต่างกันในบิลด์เดียวกันได้โดยที่ผลลัพธ์จะไม่ซ้อนทับกัน

    ป้ายกำกับที่ส่งไปยังตัวแปรนี้ต้องแสดงถึงไฟล์เพียง 1 ไฟล์เท่านั้น สำหรับป้ายกำกับที่แสดงไฟล์แหล่งที่มา จะเป็นเช่นนี้โดยอัตโนมัติ สำหรับป้ายกำกับที่แสดงถึงกฎ กฎจะต้องสร้างเอาต์พุตเพียง 1 รายการ หากนี่เป็น "เท็จ" หรือป้ายกำกับผิดรูปแบบ บิลด์จะล้มเหลวโดยมีข้อผิดพลาด

  • rootpath: หมายถึงเส้นทางที่ไบนารีที่สร้างขึ้นสามารถใช้ค้นหาทรัพยากร Dependency ขณะรันไทม์ซึ่งสัมพันธ์กับไดเรกทอรีย่อยของไดเรกทอรี Runfile ที่สอดคล้องกับที่เก็บหลัก หมายเหตุ: การดำเนินการนี้จะทำงานหากเปิดใช้ --enable_runfiles เท่านั้น ซึ่งจะไม่เป็นกรณีใน Windows โดยค่าเริ่มต้น โปรดใช้ rlocationpath แทนสำหรับการสนับสนุนข้ามแพลตฟอร์ม

    ค่านี้คล้ายกับ execpath แต่จะนำคำนำหน้าการกำหนดค่าที่อธิบายไว้ข้างต้นออก ในตัวอย่างด้านบน ค่านี้หมายความว่าทั้ง empty.source และ app ใช้เส้นทางที่สัมพันธ์กับพื้นที่ทำงานโดยสมบูรณ์ ซึ่งได้แก่ testapp/empty.source และ testapp/app

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • CC_FLAGS: ชุดแฟล็กขั้นต่ำสำหรับคอมไพเลอร์ C/C++ ที่ genrule ใช้งานได้ โดยเฉพาะอย่างยิ่ง ค่านี้มี Flag สำหรับเลือกสถาปัตยกรรมที่ถูกต้องหาก CC รองรับหลายสถาปัตยกรรม
  • NM: คำสั่ง "nm" จาก Crosstool
  • OBJCOPY: คำสั่ง objcopy จากชุดโปรแกรมเดียวกันกับคอมไพเลอร์ C/C++
  • STRIP: คำสั่ง Strip จากชุดโปรแกรมเดียวกันกับคอมไพเลอร์ C/C++

ตัวแปร Toolchain ของ Java

ข้อมูลต่อไปนี้กำหนดไว้ในกฎเครื่องมือเชนของ Java และกฎพร้อมใช้งานสำหรับกฎใดๆ ที่ตั้งค่า toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"] (หรือ "@bazel_tools//tools/jdk:current_host_java_runtime" สำหรับเครื่องมือเชนของโฮสต์ที่เทียบเท่า)

ไม่ควรใช้เครื่องมือส่วนใหญ่ใน JDK โดยตรง กฎ Java ในตัวใช้วิธีที่ซับซ้อนกว่าในการคอมไพล์และการสร้าง Java มากกว่าที่เครื่องมืออัปสตรีมจะแสดงได้ เช่น Jars ของอินเทอร์เฟซ, Jars ของส่วนหัว และแพ็กเกจ Jar ที่เพิ่มประสิทธิภาพอย่างมากและการติดตั้งใช้งานการผสานรวม

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

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

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

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

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