การกำหนดค่าเชนเครื่องมือ C++

รายงานปัญหา ดูแหล่งข้อมูล ดูแหล่งข้อมูล 7.3 · 7.2 · 7.1 · 7.0 · 6.5

ภาพรวม

หากต้องการเรียกใช้คอมไพเลอร์ด้วยตัวเลือกที่เหมาะสม Bazel ต้องมีข้อมูลบางอย่างเกี่ยวกับส่วนภายในของคอมไพเลอร์ เช่น ไดเรกทอรีรวมและ Flag ที่สำคัญ กล่าวคือ Bazel ต้องใช้รูปแบบคอมไพเลอร์ที่เข้าใจง่ายเพื่อทำความเข้าใจการทํางาน

Bazel จำเป็นต้องทราบข้อมูลต่อไปนี้

  • คอมไพเลอร์รองรับ thinLTO, โมดูล, การลิงก์แบบไดนามิก หรือ PIC (โค้ดที่ไม่ขึ้นกับตำแหน่ง) หรือไม่
  • เส้นทางไปยังเครื่องมือที่จำเป็น เช่น gcc, ld, ar, objcopy และอื่นๆ
  • ระบบในตัวจะมีไดเรกทอรี Bazel ต้องการข้อมูลเหล่านี้เพื่อตรวจสอบว่าส่วนหัวทั้งหมดที่รวมอยู่ในไฟล์ต้นฉบับได้รับการประกาศอย่างถูกต้องในไฟล์ BUILD
  • sysroot เริ่มต้น
  • Flag ที่จะใช้ในการคอมไพล์ การลิงก์ การเก็บถาวร
  • Flag ที่จะใช้สําหรับโหมดการคอมไพล์ที่รองรับ (opt, dbg, fastbuild)
  • สร้างตัวแปรที่จําเป็นโดยคอมไพเลอร์

หากคอมไพเลอร์รองรับหลายสถาปัตยกรรม Bazel จะต้องกำหนดค่าแยกกัน

CcToolchainConfigInfo เป็นผู้ให้บริการที่ระบุระดับรายละเอียดที่จำเป็นสำหรับการกำหนดค่าลักษณะการทำงานของกฎ C++ ของ Bazel โดยค่าเริ่มต้นแล้ว Bazel จะกําหนดค่า CcToolchainConfigInfo สําหรับบิลด์โดยอัตโนมัติ แต่คุณมีตัวเลือกในการกําหนดค่าด้วยตนเอง โดยคุณจะต้องมีกฎ Starlark ที่ระบุ CcToolchainConfigInfo และต้องชี้แอตทริบิวต์ toolchain_config ของ cc_toolchain ไปยังกฎ คุณสร้าง CcToolchainConfigInfo ได้โดยโทรไปที่ cc_common.create_cc_toolchain_config_info() คุณดูตัวสร้าง Starlark สำหรับโครงสร้างทั้งหมดที่ต้องใช้ในระหว่างกระบวนการได้ใน @rules_cc//cc:cc_toolchain_config_lib.bzl

เมื่อเป้าหมาย C++ เข้าสู่ช่วงการวิเคราะห์ Bazel จะเลือกเป้าหมาย cc_toolchain ที่เหมาะสมโดยอิงตามไฟล์ BUILD และรับผู้ให้บริการ CcToolchainConfigInfo จากเป้าหมายที่ระบุไว้ในแอตทริบิวต์ cc_toolchain.toolchain_config เป้าหมาย cc_toolchain จะส่งข้อมูลนี้ไปยังเป้าหมาย C++ ผ่าน CcToolchainProvider

ตัวอย่างเช่น การดำเนินการคอมไพล์หรือลิงก์ซึ่งสร้างอินสแตนซ์โดยกฎ เช่น cc_binary หรือ cc_library ต้องใช้ข้อมูลต่อไปนี้

  • คอมไพเลอร์หรือ Linker ที่จะใช้
  • Flag บรรทัดคำสั่งสําหรับคอมไพเลอร์/โปรแกรมลิงก์
  • Flag การกําหนดค่าที่ส่งผ่านตัวเลือก --copt/--linkopt
  • ตัวแปรสภาพแวดล้อม
  • อาร์ติแฟกต์ที่จําเป็นในแซนด์บ็อกซ์ที่ดําเนินการ

ข้อมูลทั้งหมดข้างต้นยกเว้นอาร์ติแฟกต์ที่จําเป็นสําหรับแซนด์บ็อกซ์จะระบุไว้ในเป้าหมาย Starlark ที่ cc_toolchain ชี้ไป

ประกาศอาร์ติแฟกต์ที่จะส่งไปยังแซนด์บ็อกซ์ใน cc_toolchain target ตัวอย่างเช่น เมื่อใช้แอตทริบิวต์ cc_toolchain.linker_files คุณสามารถระบุลิงเกอร์ไบนารีและไลบรารีเครื่องมือเพื่อนำไปไว้ในแซนด์บ็อกซ์

การเลือกชุดเครื่องมือ

ตรรกะการเลือกเครื่องมือจะทํางานดังนี้

  1. ผู้ใช้ระบุเป้าหมาย cc_toolchain_suite ในไฟล์ BUILD และชี้ Bazel ไปยังเป้าหมายโดยใช้ตัวเลือก --crosstool_top

  2. เป้าหมาย cc_toolchain_suite อ้างอิงเครื่องมือทางเทคนิคหลายรายการ ค่าของ Flag --cpu และ --compiler จะกำหนดว่าจะใช้ Toolchain ใด โดยอิงตามค่า Flag --cpu เท่านั้น หรืออิงตามค่า --cpu | --compiler ร่วม ขั้นตอนการคัดเลือกมีดังนี้

    • หากระบุตัวเลือก --compiler แล้ว Bazel จะเลือกรายการที่เกี่ยวข้องจากแอตทริบิวต์ cc_toolchain_suite.toolchains ด้วย --cpu | --compiler หากไม่พบรายการที่เกี่ยวข้อง Bazel จะแสดงข้อผิดพลาด

    • หากไม่ได้ระบุตัวเลือก --compiler ไว้ Bazel จะเลือกรายการที่เกี่ยวข้องจากแอตทริบิวต์ cc_toolchain_suite.toolchains ด้วย --cpu เพียงอย่างเดียว

    • หากไม่ได้ระบุ Flag ใดๆ Bazel จะตรวจสอบระบบโฮสต์และเลือกค่า --cpu ตามสิ่งที่พบ ดูโค้ดกลไกการตรวจสอบ

เมื่อเลือกเครื่องมือเชนแล้ว ออบเจ็กต์ feature และ action_config ที่เกี่ยวข้องในกฎ Starlark จะควบคุมการกำหนดค่าของบิลด์ (นั่นคือ รายการที่อธิบายไว้ภายหลัง) ข้อความเหล่านี้ช่วยให้คุณใช้ฟีเจอร์ C++ แบบเต็มรูปแบบใน Bazel ได้โดยไม่ต้องแก้ไขไฟล์ไบนารีของ Bazel กฎ C++ รองรับการดำเนินการที่ไม่ซ้ำหลายรายการตามรายละเอียดที่บันทึกไว้ในซอร์สโค้ด Bazel

ฟีเจอร์

ฟีเจอร์คือเอนทิตีที่ต้องใช้ Flag บรรทัดคำสั่ง การดำเนินการ ข้อจำกัดในสภาพแวดล้อมการเรียกใช้ หรือการเปลี่ยนแปลงทรัพยากร Dependency ฟีเจอร์อาจเป็นอะไรที่เรียบง่าย เช่น อนุญาตให้ไฟล์ BUILD เลือกการกำหนดค่าของ Flag เช่น treat_warnings_as_errors หรือโต้ตอบกับกฎ C++ และรวมการดำเนินการและอินพุตการคอมไพล์ใหม่ในการคอมไพล์ เช่น header_modules หรือ thin_lto

โดยหลักการแล้ว CcToolchainConfigInfo ควรมีรายการฟีเจอร์ โดยแต่ละฟีเจอร์ประกอบด้วยกลุ่ม Flag อย่างน้อย 1 กลุ่ม โดยแต่ละกลุ่มจะกำหนดรายการ Flag ที่มีผลกับการดำเนินการ Bazel ที่เฉพาะเจาะจง

ฟีเจอร์จะระบุตามชื่อ ซึ่งช่วยให้แยกการกำหนดค่ากฎ Starlark ออกจากรุ่น Bazel ได้อย่างเต็มที่ กล่าวคือ 릴리스 Bazel จะไม่ส่งผลต่อลักษณะการทํางานของการกำหนดค่า CcToolchainConfigInfo ตราบใดที่การกำหนดค่าเหล่านั้นไม่จําเป็นต้องใช้ฟีเจอร์ใหม่

ฟีเจอร์จะเปิดใช้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  • ช่อง enabled ของฟีเจอร์ตั้งค่าเป็น true
  • Bazel หรือเจ้าของกฎเปิดใช้อย่างชัดเจน
  • ผู้ใช้เปิดใช้ผ่านแอตทริบิวต์ตัวเลือก --feature Bazel หรือกฎ features

ฟีเจอร์อาจมีความเกี่ยวข้องกัน ขึ้นอยู่กับ Flag บรรทัดคำสั่ง BUILDการตั้งค่าไฟล์ และตัวแปรอื่นๆ

ความสัมพันธ์ของฟีเจอร์

โดยทั่วไปแล้ว Dependency จะจัดการกับ Bazel โดยตรง ซึ่งจะบังคับใช้ข้อกําหนดและจัดการความขัดแย้งที่เกิดจากลักษณะของฟีเจอร์ที่กําหนดไว้ในบิลด์ ข้อมูลจำเพาะของ Toolchain ทำให้มีข้อจํากัดที่ละเอียดยิ่งขึ้นสำหรับใช้ในกฎ Starlark ที่ควบคุมการรองรับและการขยายฟีเจอร์โดยตรง ได้แก่

ข้อจำกัด คำอธิบาย
requires = [
   feature_set (features = [
       'feature-name-1',
       'feature-name-2'
   ]),
]
ระดับฟีเจอร์ ระบบจะรองรับฟีเจอร์นี้เฉพาะในกรณีที่เปิดใช้ฟีเจอร์ที่จำเป็นที่ระบุไว้เท่านั้น เช่น เมื่อระบบรองรับฟีเจอร์ในโหมดการสร้างบางโหมดเท่านั้น (opt, dbg หรือfastbuild) หาก "requires" มี "feature_set" หลายรายการ ระบบจะรองรับฟีเจอร์ดังกล่าวหาก "feature_set" รายการใดรายการหนึ่งตรงตามข้อกำหนด (เมื่อเปิดใช้ฟีเจอร์ที่ระบุไว้ทั้งหมด)
implies = ['feature']

ระดับฟีเจอร์ ฟีเจอร์นี้หมายถึงฟีเจอร์ที่ระบุ การเปิดใช้ฟีเจอร์หนึ่งๆ จะเป็นการเปิดใช้ฟีเจอร์ทั้งหมดที่ฟีเจอร์นั้นนัยถึงโดยปริยายด้วย (กล่าวคือ ฟีเจอร์จะทํางานแบบซ้ำซ้อน)

และยังช่วยให้คุณแยกฟังก์ชันการทำงานย่อยทั่วไปออกจากชุดฟีเจอร์ได้ เช่น ชิ้นส่วนทั่วไปของน้ำยาฆ่าเชื้อ ปิดใช้ฟีเจอร์ที่นัยไม่ได้

provides = ['feature']

ระดับฟีเจอร์ บ่งบอกว่าฟีเจอร์นี้เป็นหนึ่งในฟีเจอร์ทางเลือกที่ใช้ไม่ได้เหมือนกันหลายประการ เช่น น้ำยาฆ่าเชื้อทั้งหมดอาจระบุ provides = ["sanitizer"]

ซึ่งจะช่วยปรับปรุงการจัดการข้อผิดพลาดด้วยการแสดงทางเลือกอื่นๆ หากผู้ใช้ขอฟีเจอร์ที่เลือกได้เพียงอย่างใดอย่างหนึ่งพร้อมกัน 2 รายการขึ้นไป

with_features = [
  with_feature_set(
    features = ['feature-1'],
    not_features = ['feature-2'],
  ),
]
ระดับชุด Flag ฟีเจอร์หนึ่งๆ สามารถระบุชุด Flag หลายชุดได้ เมื่อระบุ with_features ชุด Flag จะขยายไปยังคําสั่งบิลด์ก็ต่อเมื่อมี with_feature_set อย่างน้อย 1 รายการที่เปิดใช้ฟีเจอร์ทั้งหมดในชุด features ที่ระบุ และปิดใช้ฟีเจอร์ทั้งหมดที่ระบุไว้ในชุด not_features หากไม่ได้ระบุ with_features ระบบจะนำชุดแฟล็กไปใช้โดยไม่มีเงื่อนไขสำหรับการดำเนินการทั้งหมดที่ระบุ

การทำงาน

การดำเนินการมีความยืดหยุ่นในการแก้ไขสถานการณ์ที่การดำเนินการจะทำงานโดยไม่ต้องคาดเดาวิธีเรียกใช้การดำเนินการ action_config จะระบุไบนารีของเครื่องมือที่การดําเนินการเรียกใช้ ขณะที่ feature จะระบุการกําหนดค่า (Flag) ที่กําหนดลักษณะการทํางานของเครื่องมือนั้นเมื่อมีการเรียกใช้การดําเนินการ

ฟีเจอร์จะอ้างอิงการดำเนินการเพื่อระบุการดำเนินการของ Bazel ที่ได้รับผลกระทบ เนื่องจากการดำเนินการสามารถแก้ไขกราฟการดำเนินการของ Bazel ได้ ผู้ให้บริการ CcToolchainConfigInfo มีการดำเนินการที่มี Flag และเครื่องมือที่เชื่อมโยงกับผู้ให้บริการ เช่น c++-compile ระบบจะกำหนดธงให้กับการดำเนินการ แต่ละรายการโดยการเชื่อมโยงกับฟีเจอร์

ชื่อการดำเนินการแต่ละรายการแสดงการดำเนินการประเภทเดียวที่ Bazel ดำเนินการ เช่น การคอมไพล์หรือการลิงก์ อย่างไรก็ตาม การดำเนินการและประเภทการดำเนินการของ Bazel นั้นมีความเกี่ยวข้องแบบหลายต่อ 1 โดยประเภทการดำเนินการของ Bazel จะอ้างอิงถึงคลาส Java ที่ใช้การดำเนินการ (เช่น CppCompileAction) โดยเฉพาะอย่างยิ่ง "การดำเนินการของ assembler" และ "การดำเนินการของคอมไพเลอร์" ในตารางด้านล่างคือ CppCompileAction ส่วนการดำเนินการลิงก์คือ CppLinkAction

การดำเนินการของโปรแกรมประกอบ

การดำเนินการ คำอธิบาย
preprocess-assemble ประกอบกับการประมวลผลข้อมูลล่วงหน้า โดยปกติมีไว้สำหรับ .S ไฟล์
assemble ประกอบโดยไม่ประมวลผลก่อน โดยปกติแล้วจะใช้กับไฟล์ .s

การทำงานของคอมไพเลอร์

การดำเนินการ คำอธิบาย
cc-flags-make-variable เผยแพร่ CC_FLAGS ไปยัง Genrule
c-compile คอมไพล์เป็น C
c++-compile คอมไพล์เป็น C++
c++-header-parsing เรียกใช้โปรแกรมแยกวิเคราะห์ของคอมไพเลอร์ในไฟล์ส่วนหัวเพื่อให้แน่ใจว่าส่วนหัวนั้นสมบูรณ์ในตัว ไม่เช่นนั้นจะเกิดข้อผิดพลาดในการคอมไพล์ มีผลกับเครื่องมือทางเทคนิคที่รองรับโมดูลเท่านั้น
การดำเนินการ คำอธิบาย
c++-link-dynamic-library ลิงก์ไลบรารีที่ใช้ร่วมกันซึ่งมีทรัพยากร Dependency ทั้งหมด
c++-link-nodeps-dynamic-library ลิงก์ไลบรารีที่ใช้ร่วมกันซึ่งมีแหล่งที่มา cc_library รายการเท่านั้น
c++-link-executable ลิงก์ไลบรารีสุดท้ายที่พร้อมใช้งาน

การดำเนินการ AR

การดำเนินการ AR จะรวมไฟล์ออบเจ็กต์ลงในไลบรารีที่เก็บถาวร (.a ไฟล์) ผ่าน ar และเข้ารหัสความหมายบางอย่างลงในชื่อ

การดำเนินการ คำอธิบาย
c++-link-static-library สร้างไลบรารีแบบคงที่ (ที่เก็บถาวร)

การดำเนินการ LTO

การดำเนินการ คำอธิบาย
lto-backend การดำเนินการ ThinLTO ที่คอมไพล์บิตโค้ดให้เป็นออบเจ็กต์แบบเนทีฟ
lto-index การดำเนินการ ThinLTO ที่สร้างดัชนีทั่วโลก

การใช้ action_config

action_config คือสตรูคเจอร์ Starlark ที่อธิบายการดำเนินการของ Bazel โดยระบุเครื่องมือ (ไบนารี) ที่จะเรียกใช้ในระหว่างการดำเนินการและชุด Flag ที่กําหนดโดยฟีเจอร์ Flag เหล่านี้ใช้ข้อจำกัดกับการดำเนินการของการดำเนินการ

ตัวสร้าง action_config() มีพารามิเตอร์ต่อไปนี้

แอตทริบิวต์ คำอธิบาย
action_name การดำเนินการ Bazel ที่การดำเนินการนี้สอดคล้องกับ Bazel ใช้แอตทริบิวต์นี้เพื่อสำรวจเครื่องมือต่อการดำเนินการและข้อกำหนดการดำเนินการ
tools ไฟล์ปฏิบัติการที่จะเรียกใช้ เครื่องมือที่ใช้กับการดำเนินการดังกล่าวจะเป็นเครื่องมือแรกในลิสต์ที่มีชุดฟีเจอร์ที่ตรงกับการกำหนดค่าฟีเจอร์ ต้องระบุค่าเริ่มต้น
flag_sets รายการ Flag ที่ใช้กับกลุ่มการดําเนินการ เหมือนกับสำหรับฟีเจอร์
env_sets รายการข้อจำกัดของสภาพแวดล้อมที่ใช้กับกลุ่มการดำเนินการ เหมือนกับสำหรับฟีเจอร์

action_config สามารถกำหนดและบอกเป็นนัยถึงฟีเจอร์และ action_config อื่นๆ ตามความสัมพันธ์ของฟีเจอร์ที่อธิบายไว้ก่อนหน้านี้ ลักษณะการทํางานนี้คล้ายกับฟีเจอร์

แอตทริบิวต์ 2 รายการสุดท้ายซ้ำซ้อนกับแอตทริบิวต์ที่สอดคล้องกันในฟีเจอร์ และรวมอยู่ด้วยเนื่องจากการดำเนินการบางอย่างของ Bazel ต้องใช้ Flag หรือตัวแปรสภาพแวดล้อมบางอย่าง และเป้าหมายคือหลีกเลี่ยงคู่ action_config+feature ที่ไม่จำเป็น โดยทั่วไปแล้ว เราขอแนะนำให้แชร์ฟีเจอร์เดียวใน action_config หลายรายการ

คุณกำหนด action_config ได้ไม่เกิน 1 รายการที่มี action_name เดียวกันภายในเครื่องมือทางเทคนิคชุดเดียวกัน วิธีนี้จะช่วยป้องกันความคลุมเครือในเส้นทางเครื่องมือ และบังคับใช้เจตนาที่อยู่เบื้องหลัง action_config นั่นคือการอธิบายพร็อพเพอร์ตี้ของการดำเนินการอย่างชัดเจนในที่เดียวในชุดเครื่องมือ

การใช้เครื่องมือสร้างเครื่องมือ

action_config สามารถระบุชุดเครื่องมือผ่านพารามิเตอร์ tools ตัวสร้าง tool() จะรับพารามิเตอร์ต่อไปนี้

ฟิลด์ คำอธิบาย
path เส้นทางไปยังเครื่องมือที่เป็นปัญหา (สัมพันธ์กับตำแหน่งปัจจุบัน)
with_features รายการชุดฟีเจอร์ที่ต้องมีอย่างน้อย 1 ชุดจึงจะใช้เครื่องมือนี้ได้

สําหรับ action_config หนึ่งๆ จะมีเพียง tool รายการเดียวที่ใช้เส้นทางเครื่องมือและข้อกําหนดการดําเนินการกับการดำเนินการ Bazel มีการเลือกเครื่องมือโดยทำซ้ำผ่านแอตทริบิวต์ tools ใน action_config จนกว่าจะพบเครื่องมือที่มีชุด with_feature ตรงกับการกำหนดค่าฟีเจอร์ (ดูข้อมูลเพิ่มเติมได้ที่ความสัมพันธ์ของฟีเจอร์ก่อนหน้านี้ในหน้านี้) คุณควรปิดท้ายรายการเครื่องมือด้วยเครื่องมือเริ่มต้นที่สอดคล้องกับการกำหนดค่าฟีเจอร์ว่าง

ตัวอย่างการใช้

คุณสามารถใช้ฟีเจอร์และการดำเนินการร่วมกันเพื่อติดตั้งใช้งานการดำเนินการของ Bazel ที่มีความหมายแบบข้ามแพลตฟอร์มที่หลากหลาย ตัวอย่างเช่น การสร้างสัญลักษณ์การแก้ไขข้อบกพร่องใน macOS กำหนดให้ต้องสร้างสัญลักษณ์ในการดำเนินการคอมไพล์ จากนั้นเรียกใช้เครื่องมือเฉพาะในระหว่างการดำเนินการลิงก์เพื่อสร้างไฟล์เก็บถาวร dsym ที่บีบอัด และจากนั้นจึงคลายการบีบอัดไฟล์เก็บถาวรนั้นเพื่อสร้างกลุ่มแอปพลิเคชันและ.plistไฟล์ที่ Xcode ใช้ได้

เมื่อใช้ Bazel คุณจะติดตั้งใช้งานกระบวนการนี้ได้ดังนี้ โดยที่ unbundle-debuginfo คือการดำเนินการของ Bazel

load("@rules_cc//cc:defs.bzl", "ACTION_NAMES")

action_configs = [
    action_config (
        action_name = ACTION_NAMES.cpp_link_executable,
        tools = [
            tool(
                with_features = [
                    with_feature(features=["generate-debug-symbols"]),
                ],
                path = "toolchain/mac/ld-with-dsym-packaging",
            ),
            tool (path = "toolchain/mac/ld"),
        ],
    ),
]

features = [
    feature(
        name = "generate-debug-symbols",
        flag_sets = [
            flag_set (
                actions = [
                    ACTION_NAMES.c_compile,
                    ACTION_NAMES.cpp_compile
                ],
                flag_groups = [
                    flag_group(
                        flags = ["-g"],
                    ),
                ],
            )
        ],
        implies = ["unbundle-debuginfo"],
   ),
]

ฟีเจอร์เดียวกันนี้อาจใช้งานต่างออกไปโดยสิ้นเชิงสำหรับ Linux ที่ใช้ fission หรือสำหรับ Windows ซึ่งสร้างไฟล์ .pdb ตัวอย่างเช่น การใช้งานในการสร้างสัญลักษณ์การแก้ไขข้อบกพร่องตาม fission อาจมีลักษณะดังนี้

load("@rules_cc//cc:defs.bzl", "ACTION_NAMES")

action_configs = [
    action_config (
        name = ACTION_NAMES.cpp_compile,
        tools = [
            tool(
                path = "toolchain/bin/gcc",
            ),
        ],
    ),
]

features = [
    feature (
        name = "generate-debug-symbols",
        requires = [with_feature_set(features = ["dbg"])],
        flag_sets = [
            flag_set(
                actions = [ACTION_NAMES.cpp_compile],
                flag_groups = [
                    flag_group(
                        flags = ["-gsplit-dwarf"],
                    ),
                ],
            ),
            flag_set(
                actions = [ACTION_NAMES.cpp_link_executable],
                flag_groups = [
                    flag_group(
                        flags = ["-Wl", "--gdb-index"],
                    ),
                ],
            ),
      ],
    ),
]

กลุ่มการแจ้งว่าไม่เหมาะสม

CcToolchainConfigInfo ช่วยให้คุณรวม Flag เข้าเป็นกลุ่มเพื่อวัตถุประสงค์ที่เฉพาะเจาะจงได้ คุณระบุแฟล็กภายในได้โดยใช้ตัวแปรที่กำหนดไว้ล่วงหน้าภายในค่าแฟล็ก ซึ่งคอมไพเลอร์จะขยายเมื่อเพิ่มแฟล็กในคำสั่งบิลด์ เช่น

flag_group (
    flags = ["%{output_execpath}"],
)

ในกรณีนี้ เนื้อหาของ Flag จะถูกแทนที่ด้วยเส้นทางไฟล์เอาต์พุตของการดำเนินการ

กลุ่มแฟล็กจะขยายออกเป็นคำสั่งบิลด์ตามลําดับที่ปรากฏในรายการ ซึ่งก็คือจากบนลงล่าง ซ้ายไปขวา

สําหรับ Flag ที่ต้องแสดงซ้ำด้วยค่าที่ต่างกันเมื่อเพิ่มลงในคําสั่ง build กลุ่ม Flag จะทําซ้ำตัวแปรประเภท list ได้ เช่น ตัวแปร include_path ประเภท list

flag_group (
    iterate_over = "include_paths",
    flags = ["-I%{include_paths}"],
)

จะขยายเป็น -I<path> สำหรับองค์ประกอบเส้นทางแต่ละรายการในรายการ include_paths ระบบจะขยาย Flag (หรือ flag_group) ทั้งหมดในเนื้อหาของการประกาศกลุ่ม Flag เป็นหน่วย เช่น

flag_group (
    iterate_over = "include_paths",
    flags = ["-I", "%{include_paths}"],
)

ขยายเป็น -I <path> สำหรับองค์ประกอบเส้นทางแต่ละรายการในรายการ include_paths

ตัวแปรใช้ซ้ำได้หลายครั้ง เช่น

flag_group (
    iterate_over = "include_paths",
    flags = ["-iprefix=%{include_paths}", "-isystem=%{include_paths}"],
)

ขยายเป็น

-iprefix=<inc0> -isystem=<inc0> -iprefix=<inc1> -isystem=<inc1>

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

flag_group (
    flags = ["-l%{libraries_to_link.name}"],
)

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

flag_group (
    iterate_over = "libraries_to_link",
    flag_groups = [
        flag_group (
            iterate_over = "libraries_to_link.shared_libraries",
            flags = ["-l%{libraries_to_link.shared_libraries.name}"],
        ),
    ],
)

การขยายแบบมีเงื่อนไข

กลุ่มที่มีการแจ้งจะรองรับการขยายแบบมีเงื่อนไขตามการมีอยู่ของตัวแปรหรือช่องของตัวแปรนั้นๆ โดยใช้แอตทริบิวต์ expand_if_available, expand_if_not_available, expand_if_true, expand_if_false หรือ expand_if_equal เช่น

flag_group (
    iterate_over = "libraries_to_link",
    flag_groups = [
        flag_group (
            iterate_over = "libraries_to_link.shared_libraries",
            flag_groups = [
                flag_group (
                    expand_if_available = "libraries_to_link.shared_libraries.is_whole_archive",
                    flags = ["--whole_archive"],
                ),
                flag_group (
                    flags = ["-l%{libraries_to_link.shared_libraries.name}"],
                ),
                flag_group (
                    expand_if_available = "libraries_to_link.shared_libraries.is_whole_archive",
                    flags = ["--no_whole_archive"],
                ),
            ],
        ),
    ],
)

ข้อมูลอ้างอิง CcToolchainConfigInfo

ส่วนนี้จะแสดงข้อมูลอ้างอิงเกี่ยวกับตัวแปรการสร้าง ฟีเจอร์ และข้อมูลอื่นๆ ที่จําเป็นในการกําหนดค่ากฎ C++ ให้สําเร็จ

ตัวแปร CcToolchainConfigInfo สำหรับบิลด์

ต่อไปนี้เป็นข้อมูลอ้างอิงเกี่ยวกับCcToolchainConfigInfoตัวแปรการสร้าง

ตัวแปร การดำเนินการ คำอธิบาย
source_file คอมไพล์ ไฟล์ต้นฉบับที่จะคอมไพล์
input_file แถบ อาร์ติแฟกต์ที่จะถอดออก
output_file คอมไพล์, ลบ เอาต์พุตการคอมไพล์
output_assembly_file คอมไพล์ ไฟล์การประกอบที่ดำเนินการแล้ว มีผลเฉพาะเมื่อการดำเนินการ compile ส่งออกข้อความแอสเซมบลี ซึ่งมักจะเป็นเมื่อใช้ Flag --save_temps เนื้อหาจะเหมือนกับของ output_file
output_preprocess_file คอมไพล์ เอาต์พุตที่ประมวลผลล่วงหน้า มีผลเฉพาะกับการดำเนินการคอมไพล์ที่ประมวลผลไฟล์ต้นทางก่อนเท่านั้น ซึ่งมักจะใช้เมื่อใช้แฟล็ก --save_temps เนื้อหาจะเหมือนกับของ output_file
includes คอมไพล์ ลำดับไฟล์ที่คอมไพเลอร์ต้องรวมไว้ในซอร์สที่คอมไพล์โดยไม่มีเงื่อนไข
include_paths คอมไพล์ ไดเรกทอรีลําดับที่คอมไพเลอร์ค้นหาส่วนหัวที่รวมอยู่โดยใช้ #include<foo.h> และ #include "foo.h"
quote_include_paths คอมไพล์ ลำดับ -iquote ประกอบด้วยไดเรกทอรีที่คอมไพเลอร์ค้นหาส่วนหัวที่รวมโดยใช้ #include "foo.h"
system_include_paths คอมไพล์ ลำดับ -isystem ประกอบด้วยไดเรกทอรีที่คอมไพเลอร์ค้นหาส่วนหัวที่รวมโดยใช้ #include <foo.h>
dependency_file คอมไพล์ ไฟล์ .d Dependency ที่คอมไพเลอร์สร้างขึ้น
preprocessor_defines คอมไพล์ ลำดับ defines เช่น --DDEBUG
pic คอมไพล์ คอมไพล์เอาต์พุตเป็นโค้ดที่ไม่ขึ้นกับตำแหน่ง
gcov_gcno_file คอมไพล์ ไฟล์ความครอบคลุม gcov
per_object_debug_info_file คอมไพล์ ไฟล์ข้อมูลการแก้ไขข้อบกพร่อง (.dwp) ของแต่ละออบเจ็กต์
stripopts แถบ ลำดับของ stripopts
legacy_compile_flags คอมไพล์ ลำดับ Flag จากช่อง CROSSTOOL รุ่นเดิม เช่น compiler_flag, optional_compiler_flag, cxx_flag และ optional_cxx_flag
user_compile_flags คอมไพล์ ลำดับของแฟล็กจากแอตทริบิวต์กฎ copt หรือแฟล็ก --copt, --cxxopt และ --conlyopt
unfiltered_compile_flags คอมไพล์ ลําดับสถานะจากช่องunfiltered_cxx_flagเดิมCROSSTOOLหรือฟีเจอร์unfiltered_compile_flags รายการเหล่านี้จะไม่ได้รับการกรองตามแอตทริบิวต์กฎ nocopts
sysroot sysroot
runtime_library_search_directories ลิงก์ รายการในเส้นทางการค้นหารันไทม์ของ linker (โดยปกติจะตั้งค่าด้วย Flag -rpath)
library_search_directories ลิงก์ รายการในเส้นทางการค้นหา Linker (โดยปกติจะตั้งค่าด้วยแฟล็ก -L)
libraries_to_link ลิงก์ Flag ที่ระบุไฟล์ที่จะลิงก์เป็นอินพุตในการเรียกใช้ linker
def_file_path ลิงก์ ตำแหน่งของไฟล์ def ที่ใช้ใน Windows กับ MSVC
linker_param_file ลิงก์ ตำแหน่งของไฟล์พารามิเตอร์ linker ที่ Bazel สร้างขึ้นเพื่อเอาชนะขีดจำกัดความยาวของบรรทัดคำสั่ง
output_execpath ลิงก์ Execpath ของเอาต์พุตของโปรแกรมลิงก์
generate_interface_library ลิงก์ "yes" หรือ "no" ทั้งนี้ขึ้นอยู่กับว่าควรสร้างไลบรารีอินเทอร์เฟซหรือไม่
interface_library_builder_path ลิงก์ เส้นทางไปยังเครื่องมือสร้างคลังอินเทอร์เฟซ
interface_library_input_path ลิงก์ อินพุตสําหรับเครื่องมือสร้างifsoคลังอินเทอร์เฟซ
interface_library_output_path ลิงก์ เส้นทางที่จะสร้างคลังอินเทอร์เฟซโดยใช้ifsoเครื่องมือสร้าง
legacy_link_flags ลิงก์ แฟล็ก Linker มาจากช่อง CROSSTOOL เดิม
user_link_flags ลิงก์ Flag ของ Linker ที่มาจากแอตทริบิวต์ --linkopt หรือ linkopts
linkstamp_paths ลิงก์ ตัวแปรบิลด์ที่มีเส้นทางลิงก์สแตมป์
force_pic ลิงก์ การมีตัวแปรนี้บ่งชี้ว่าควรสร้างโค้ด PIC/PIE (มีการส่งตัวเลือก Bazel `--force_pic`)
strip_debug_symbols ลิงก์ การมีอยู่ของตัวแปรนี้บ่งชี้ว่าควรนําสัญลักษณ์การแก้ไขข้อบกพร่องออก
is_cc_test ลิงก์ เป็นจริงเมื่อการดำเนินการปัจจุบันเป็นการดำเนินการลิงก์ cc_test มิเช่นนั้นจะเป็นเท็จ
is_using_fission คอมไพล์ ลิงก์ การมีตัวแปรนี้บ่งบอกว่า Fission (ข้อมูลการแก้ไขข้อบกพร่องต่อออบเจ็กต์) ทำงานอยู่ ข้อมูลการแก้ไขข้อบกพร่องจะอยู่ในไฟล์ .dwo แทนไฟล์ .o และคอมไพเลอร์และโปรแกรมลิงก์จำเป็นต้องทราบข้อมูลนี้
fdo_instrument_path คอมไพล์ ลิงก์ เส้นทางไปยังไดเรกทอรีที่เก็บโปรไฟล์การใช้เครื่องมือ FDO
fdo_profile_path คอมไพล์ เส้นทางไปยังโปรไฟล์ FDO
fdo_prefetch_hints_path คอมไพล์ เส้นทางไปยังโปรไฟล์การดึงข้อมูลแคชล่วงหน้า
cs_fdo_instrument_path คอมไพล์, ลิงก์ เส้นทางไปยังไดเรกทอรีที่เก็บโปรไฟล์การใช้เครื่องมือ FDO ที่ละเอียดอ่อนตามบริบท

ฟีเจอร์ที่รู้จักกันดี

ต่อไปนี้เป็นข้อมูลอ้างอิงเกี่ยวกับฟีเจอร์และเงื่อนไขการเปิดใช้งาน

ฟีเจอร์ เอกสารประกอบ
opt | dbg | fastbuild เปิดใช้โดยค่าเริ่มต้นตามโหมดการคอมไพล์
static_linking_mode | dynamic_linking_mode เปิดใช้โดยค่าเริ่มต้นตามโหมดการลิงก์
per_object_debug_info เปิดใช้หากมีการระบุและเปิดใช้ฟีเจอร์ supports_fission รวมถึงมีการระบุโหมดการคอมไพล์ปัจจุบันใน Flag --fission
supports_start_end_lib หากเปิดใช้ (และตั้งค่าตัวเลือก --start_end_lib) Bazel จะไม่ลิงก์กับไลบรารีแบบคงที่ แต่จะใช้ตัวเลือก linker --start-lib/--end-lib เพื่อลิงก์กับออบเจ็กต์โดยตรง วิธีนี้จะช่วยเร่งความเร็วการสร้างเนื่องจาก Bazel ไม่จำเป็นต้องสร้างไลบรารีแบบคงที่
supports_interface_shared_libraries หากเปิดใช้ (และตัวเลือก --interface_shared_objects ตั้งค่าไว้) Bazel จะลิงก์เป้าหมายที่ตั้งค่า linkstatic เป็น "เท็จ" (โดยค่าเริ่มต้น cc_test) กับไลบรารีที่แชร์อินเทอร์เฟซ ซึ่งจะทำให้การลิงก์เพิ่มเติมเร็วขึ้น
supports_dynamic_linker หากเปิดใช้ กฎ C++ จะทราบว่าเครื่องมือทางเทคนิคสามารถสร้างไลบรารีที่แชร์ได้
static_link_cpp_runtimes หากเปิดใช้ Bazel จะลิงก์รันไทม์ C++ แบบคงที่ในโหมดการลิงก์แบบคงที่ และแบบไดนามิกในโหมดการลิงก์แบบไดนามิก ระบบจะเพิ่มอาร์ติแฟกต์ที่ระบุไว้ในแอตทริบิวต์ cc_toolchain.static_runtime_lib หรือ cc_toolchain.dynamic_runtime_lib (ขึ้นอยู่กับโหมดการลิงก์) ลงในการดำเนินการลิงก์
supports_pic หากเปิดใช้ Toolchain จะทราบว่าใช้ออบเจ็กต์ PIC สำหรับไลบรารีแบบไดนามิก ตัวแปร `pic` จะปรากฏขึ้นเมื่อใดก็ตามที่จำเป็นต้องคอมไพล์ PIC หากไม่เปิดใช้โดยค่าเริ่มต้น และระบบส่ง "--force_pic" แล้ว Bazel จะส่งคำขอ "supports_pic" และตรวจสอบว่าฟีเจอร์ดังกล่าวเปิดใช้อยู่ หากฟีเจอร์นี้หายไปหรือ เปิดใช้ไม่ได้ คุณจะใช้ "--force_pic" ไม่ได้
static_linking_mode | dynamic_linking_mode เปิดใช้โดยค่าเริ่มต้นตามโหมดการลิงก์
no_legacy_features ป้องกันไม่ให้ Bazel เพิ่มฟีเจอร์เดิมในการกําหนดค่า C++ หากมี ดูรายการฟีเจอร์ทั้งหมดได้ที่ด้านล่าง

ตรรกะการแพตช์ฟีเจอร์เดิม

Bazel นำการเปลี่ยนแปลงต่อไปนี้ไปใช้กับฟีเจอร์ของ Toolchain เพื่อความเข้ากันได้แบบย้อนหลัง

  • ย้ายฟีเจอร์ legacy_compile_flags ไปไว้ที่ด้านบนของเครื่องมือ
  • ย้ายฟีเจอร์ default_compile_flags ไปไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ dependency_file (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ pic (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ per_object_debug_info (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ preprocessor_defines (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ includes (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ include_paths (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ fdo_instrument (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ fdo_optimize (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ cs_fdo_instrument (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ cs_fdo_optimize (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ fdo_prefetch_hints (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ autofdo (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ build_interface_libraries (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ dynamic_library_linker_tool (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ shared_flag (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ linkstamps (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ output_execpath_flags (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ runtime_library_search_directories (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ library_search_directories (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ archiver_flags (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ libraries_to_link (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ force_pic_flags (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ user_link_flags (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ legacy_link_flags (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ static_libgcc (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ fission_support (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ strip_debug_symbols (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ coverage (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ llvm_coverage_map_format (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ gcc_coverage_map_format (หากไม่มี) ไว้ที่ด้านบนของเครื่องมือ
  • เพิ่มฟีเจอร์ fully_static_link (หากไม่มี) ลงที่ด้านล่างของเครื่องมือ
  • เพิ่มฟีเจอร์ user_compile_flags (หากไม่มี) ลงที่ด้านล่างของเครื่องมือ
  • เพิ่มฟีเจอร์ sysroot (หากไม่มี) ลงที่ด้านล่างของเครื่องมือ
  • เพิ่มฟีเจอร์ unfiltered_compile_flags (หากไม่มี) ลงที่ด้านล่างของเครื่องมือ
  • เพิ่มฟีเจอร์ linker_param_file (หากไม่มี) ลงที่ด้านล่างของเครื่องมือ
  • เพิ่มฟีเจอร์ compiler_input_flags (หากไม่มี) ลงที่ด้านล่างของเครื่องมือ
  • เพิ่มฟีเจอร์ compiler_output_flags (หากไม่มี) ลงที่ด้านล่างของเครื่องมือ

นี่เป็นรายการฟีเจอร์ที่ยาวมาก แผนของเราคือการเลิกใช้เมื่อCrosstool ใน Starlark พร้อมใช้งาน สําหรับผู้อ่านที่อยากรู้ ให้ดูการใช้งานใน CppActionConfigs และสำหรับเครื่องมือทางเทคนิคเวอร์ชันที่ใช้งานจริง ให้พิจารณาเพิ่ม no_legacy_features เพื่อให้เครื่องมือทางเทคนิคเป็นแบบสแตนด์อโลนมากขึ้น