สร้างตัวแปร

รายงานปัญหา ดูแหล่งที่มา รุ่น Nightly · 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

ใช้

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

my_attr = "prefix $(FOO) suffix"

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

my_attr = "prefix bar suffix"

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

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

my_attr = "prefix $@ suffix"

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

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

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

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

bazel info --show_make_env [build options]

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

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

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

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

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

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

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

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

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

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

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

รายการต่อไปนี้มีให้บริการแก่ธุรกิจ genrule cmd และต่อไปนี้ มักสำคัญในการช่วยให้แอตทริบิวต์นั้นใช้งานได้

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

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

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

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

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

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

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

ตัวแปรเครื่องมือ 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++ ที่ genrules ใช้ได้ กล่าวอย่างเจาะจงคือ เลือกสถาปัตยกรรมที่ถูกต้องหาก CC รองรับหลายเวอร์ชัน สถาปัตยกรรม
  • NM: คำสั่ง "nm" จาก Crosstool
  • OBJCOPY: คำสั่ง objcopy จากชุดเดียวกับคอมไพเลอร์ C/C++
  • STRIP: คำสั่ง Strip จากชุดโปรแกรมเดียวกันกับ C/C++ คอมไพเลอร์

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

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

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

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

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

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

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

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