สร้างตัวแปร

รายงานปัญหา ดูซอร์สโค้ด รุ่น Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

ตัวอย่างเช่น คุณอาจใช้เพื่อแทรกเส้นทางเครื่องมือทางเทคนิคที่เฉพาะเจาะจงลงในการดำเนินการสร้างที่ผู้ใช้สร้างขึ้น

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 ในรูทเวิร์กสเปซ ไฟล์ต้นฉบับ 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 ตัวที่แตกต่างกันในบิลด์เดียวกันได้โดยไม่ทำให้ผลลัพธ์ทับซ้อนกัน

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

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

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

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

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

  • rlocationpath: เส้นทางที่ไบนารีที่คอมไพล์แล้วสามารถส่งไปยังฟังก์ชัน Rlocation ของไลบรารี runfiles เพื่อค้นหาทรัพยากรที่ต้องพึ่งพาที่รันไทม์ ไม่ว่าจะในไดเรกทอรี 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 โดยขึ้นอยู่กับแอตทริบิวต์ที่ขยาย ลักษณะการทำงานนี้เป็นลักษณะการทำงานเดิมก่อน Starlark และไม่แนะนําให้ใช้ เว้นแต่คุณจะทราบดีว่าลักษณะการทำงานนี้ทําอะไรกับกฎหนึ่งๆ ดูรายละเอียดได้ที่ #2475

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

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

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

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

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

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

ตัวแปรในชุดเครื่องมือ C++

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

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

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

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

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

  • CC_FLAGS: ชุดแฟล็กขั้นต่ำสำหรับคอมไพเลอร์ C/C++ ที่ genrules ใช้ได้ โดยเฉพาะอย่างยิ่ง ไฟล์นี้จะมี Flag เพื่อเลือกสถาปัตยกรรมที่ถูกต้องหาก CC รองรับสถาปัตยกรรมหลายแบบ
  • DUMPBIN: เครื่องมือแสดงข้อมูลไฟล์ไบนารี COFF ของ Microsoft (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 กำหนด