สร้างตัวแปร

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

ซึ่งใช้เพื่อแทรกเส้นทางของ 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"

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

Predefined variables

Predefined "Make" variables can be referenced by any attribute marked as "Subject to 'Make variable' substitution" on any target.

To see the list of these variables and their values for a given set of build options, run

bazel info --show_make_env [build options]

and look at the top output lines with capital letters.

See an example of predefined variables.

Toolchain option variables

Path variables

  • BINDIR: The base of the generated binary tree for the target architecture.

    Note that a different tree may be used for programs that run during the build on the host architecture, to support cross-compiling.

    If you want to run a tool from within a genrule, the recommended way to get its path is $(execpath toolname), where toolname must be listed in the genrule's tools attribute.

  • GENDIR: The base of the generated code tree for the target architecture.

Machine architecture variables

  • TARGET_CPU: The target architecture's CPU, e.g. k8.

Predefined genrule variables

The following are specially available to genrule's cmd attribute and are generally important for making that attribute work.

See an example of predefined genrule variables.

  • OUTS: The genrule's outs list. If you have only one output file, you can also use $@.
  • SRCS: The genrule's srcs list (or more precisely: the path names of the files corresponding to labels in the srcs list). If you have only one source file, you can also use $<.
  • <: SRCS, if it is a single file. Else triggers a build error.
  • @: OUTS, if it is a single file. Else triggers a build error.
  • RULEDIR: The output directory of the target, that is, the directory corresponding to the name of the package containing the target under the genfiles or bin tree. For //my/pkg:my_genrule this always ends in my/pkg, even if //my/pkg:my_genrule's outputs are in subdirectories.

  • @D: The output directory. If outs has one entry, this expands to the directory containing that file. If it has multiple entries, this expands to the package's root directory in the genfiles tree, even if all output files are in the same subdirectory!

    Note: Use RULEDIR over @D because RULEDIR has simpler semantics and behaves the same way regardless of the number of output files.

    If the genrule needs to generate temporary intermediate files (perhaps as a result of using some other tool like a compiler), it should attempt to write them to @D (although /tmp will also be writable) and remove them before finishing.

    Especially avoid writing to directories containing inputs. They may be on read-only filesystems. Even if not, doing so would trash the source tree.

Note: If the filenames corresponding to the input labels or the output filenames contain spaces, ', or other special characters (or your genrule is part of a Starlark macro which downstream users may invoke on such files), then $(SRCS) and $(OUTS) are not suitable for interpolation into a command line, as they do not have the semantics that "${@}" would in Bash.

One workaround is to convert to a Bash array, with

mapfile SRCS <<< "$$(sed -e 's/ /\\n/g' <<'genrule_srcs_expansion'
$(SRC)
genrule_srcs_expansion
)
จากนั้นใช้ "$$\{SRCS[@]}" ในบรรทัดคำสั่งถัดไปแทน
$(SRCS) ตัวเลือกที่แข็งแกร่งกว่าคือการเขียนกฎ Starlark
แทน

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

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

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

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

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

    ในตัวอย่างข้างต้น Bazel จะเรียกใช้การดำเนินการบิลด์ทั้งหมดในไดเรกทอรีที่ลิงก์ โดยbazel-myproject Symlink ในรูทของ Workspace ระบบได้ลิงก์ ไฟล์ต้นฉบับ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 ตัวที่แตกต่างกันใน บิลด์เดียวกันได้โดยไม่ให้ผลลัพธ์ทับซ้อนกัน

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

  • rootpath: ระบุเส้นทางที่ไบนารีที่สร้างขึ้นใช้เพื่อ ค้นหาการขึ้นต่อกันที่รันไทม์ซึ่งสัมพันธ์กับไดเรกทอรีย่อยของไดเรกทอรี 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 แล้ว มีข้อดีคือทำงานได้ในทุกแพลตฟอร์มและแม้ว่าจะไม่มีไดเรกทอรีไฟล์ที่รันได้ก็ตาม

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

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

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

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

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

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

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

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

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

ต่อไปนี้เป็นสิ่งที่กำหนดไว้ในกฎของเครื่องมือ C++ และพร้อมใช้งานสำหรับกฎใดก็ตาม ที่ตั้งค่า toolchains = ["@bazel_tools//tools/cpp:toolchain_type"] กฎบางอย่าง เช่น 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 รองรับหลาย สถาปัตยกรรม
  • DUMPBIN: Microsoft COFF Binary File Dumper (dumpbin.exe) จาก จาก Microsoft Visual Studio
  • NM: คำสั่ง "nm" จาก crosstool
  • OBJCOPY: คำสั่ง objcopy จากชุดเดียวกันกับคอมไพเลอร์ C/C++
  • STRIP: คำสั่ง strip จากชุดเดียวกันกับคอมไพเลอร์ C/C++

ตัวแปรของชุดเครื่องมือ Java

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

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

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

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

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

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

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