"Make" ตัวแปร

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

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

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

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

เหตุผลของคําว่า "ผู้ผลิต" นั้นย้อนหลัง กล่าวคือไวยากรณ์และความหมายของตัวแปรเหล่านี้มีวัตถุประสงค์เพื่อจับคู่กับ 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]

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

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

ตัวแปรตัวเลือกเครื่องมือเชน

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

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

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

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

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

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

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

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

แอตทริบิวต์ cmd ของ genrule มีคุณสมบัติพิเศษต่อไปนี้และจะมีผลทั่วไปในการทําให้แอตทริบิวต์ดังกล่าวใช้งานได้

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

  • 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 มีความหมายที่เรียบง่ายขึ้นและทํางานในลักษณะเดียวกัน โดยไม่คํานึงถึงจํานวนไฟล์เอาต์พุต

    หากพันธุกรรมจําเป็นต้องสร้างไฟล์ชั่วคราว (อาจเป็นผลมาจากการใช้เครื่องมืออื่น เช่น คอมไพเลอร์) ก็ควรพยายามเขียนไปยัง @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 รายการได้โดยไม่ต้องให้ผลการค้นหามาซ้อนทับกัน

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ตัวแปร "ผลิต" ที่กําหนดเองจะอ้างอิงได้ด้วยแอตทริบิวต์ที่ทําเครื่องหมายว่า "อยู่ภายใต้การแทนที่ "สร้างตัวแปร"" แต่อิงตามเป้าหมายที่อิงตามเป้าหมายอื่นๆ ที่กําหนดตัวแปรเหล่านี้เท่านั้น

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

ตัวแปรสําหรับเครื่องมือ C++

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

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

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

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

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

  • CC_FLAGS: ชุดแฟล็กขั้นต่ําสําหรับคอมไพเลอร์ C/C++ ที่ Gengen จะใช้ได้ โดยเฉพาะจะมีแฟล็กเพื่อเลือกสถาปัตยกรรมที่ถูกต้องหาก CC รองรับสถาปัตยกรรมหลายรายการ
  • NM: คําสั่ง "nm" จากข้ามเครื่องมือ
  • OBJCOPY: คําสั่ง Objcopy จากชุดเดียวกันกับคอมไพเลอร์ C/C++
  • 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) ให้หลีกเลี่ยงกฎนี้และใช้กฎ java_binary แทนหากเป็นไปได้ อาจเป็นเส้นทางแบบสัมพัทธ์ หากคุณจําเป็นต้องเปลี่ยนไดเรกทอรีก่อนเรียกใช้ java คุณต้องบันทึกไดเรกทอรีที่ใช้งานได้ก่อนเปลี่ยน
  • JAVABASE: ไดเรกทอรีฐานที่มียูทิลิตี Java อาจเป็นเส้นทางแบบสัมพัทธ์ ซึ่งจะมีไดเรกทอรีย่อย "bin"

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

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

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