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

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

ภาพรวม

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

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

  • ดูว่าคอมไพเลอร์รองรับ ThinLTO, โมดูล, การลิงก์แบบไดนามิก หรือ PIC หรือไม่ (โค้ดอิสระตามตำแหน่ง)
  • เส้นทางไปยังเครื่องมือที่จำเป็น เช่น gcc, ld, ar, objcopy และอื่นๆ
  • ระบบในตัวจะมีไดเรกทอรี Bazel ต้องใช้ตัวระบุเหล่านี้เพื่อตรวจสอบว่าส่วนหัวทั้งหมดที่รวมอยู่ในไฟล์ต้นฉบับมีการประกาศอย่างถูกต้องในไฟล์ BUILD
  • Syรูท ที่เป็นค่าเริ่มต้น
  • แฟล็กที่ใช้ในการรวบรวม ลิงก์ และเก็บถาวร
  • แฟล็กที่จะใช้สำหรับโหมดการคอมไพล์ที่รองรับ (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 ที่จะใช้
  • แฟล็กบรรทัดคำสั่งสำหรับคอมไพเลอร์/linker
  • แฟล็กการกำหนดค่าที่ส่งผ่านตัวเลือก --copt/--linkopt
  • ตัวแปรสภาพแวดล้อม
  • อาร์ติแฟกต์ที่จำเป็นในแซนด์บ็อกซ์ที่มีการดำเนินการดังกล่าว

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

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

การเลือก Toolchain

ตรรกะการเลือก Toolchain ทํางานดังนี้

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

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

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

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

    • หากไม่ได้ระบุแฟล็ก Bazel จะตรวจสอบระบบโฮสต์และเลือกค่า --cpu ตามผลการสืบค้น โปรดดูรหัสกลไกการตรวจสอบ

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

ฟีเจอร์

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

ตามหลักการแล้ว CcToolchainConfigInfo มีรายการฟีเจอร์ ซึ่งแต่ละฟีเจอร์ประกอบด้วยกลุ่มแฟล็กอย่างน้อย 1 กลุ่ม โดยแต่ละรายการจะกำหนดรายการแฟล็กที่ใช้กับการดำเนินการของ Bazel ที่เฉพาะเจาะจง

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

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

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

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

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

โดยปกติแล้ว การขึ้นต่อกันจะได้รับการจัดการโดยตรงกับ Bazel ซึ่งจะบังคับใช้ข้อกำหนดและจัดการความขัดแย้งตามลักษณะของฟีเจอร์ที่กำหนดไว้ในบิลด์ ข้อกำหนดของชุดเครื่องมือจะช่วยให้มีข้อจำกัดที่ละเอียดยิ่งขึ้นสำหรับการใช้งานโดยตรงภายในกฎ 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'],
  ),
]
ระดับชุดการแจ้งเตือน ฟีเจอร์หนึ่งสามารถระบุชุดแฟล็กหลายชุดที่มีหลายชุด เมื่อระบุ with_features ชุดแฟล็กจะขยายเป็นคำสั่งบิลด์ก็ต่อเมื่อมี with_feature_set อย่างน้อย 1 รายการซึ่งเปิดใช้ฟีเจอร์ทั้งหมดในชุด features ที่ระบุ และปิดใช้ฟีเจอร์ทั้งหมดที่ระบุในชุด not_features หากไม่ได้ระบุ with_features จะมีการใช้ชุดแฟล็กอย่างไม่มีเงื่อนไขสำหรับการดำเนินการทั้งหมดที่ระบุ

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

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

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

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

การทำงานของ Assembler

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

การดำเนินการกับคอมไพเลอร์

การดำเนินการ คำอธิบาย
cc-flags-make-variable เผยแพร่ CC_FLAGS ไปยัง Genrules
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 โดยระบุเครื่องมือ (ไบนารี) ที่จะเรียกใช้ระหว่างการดำเนินการและชุดธงซึ่งกำหนดโดยฟีเจอร์ แฟล็กเหล่านี้มีข้อจำกัดในการสั่งการ

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

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

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

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

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

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

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

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

สำหรับ action_config หนึ่งๆ tool เพียงรายการเดียวจะนำเส้นทางเครื่องมือและข้อกำหนดการดำเนินการของ Bazel ไปใช้กับการดำเนินการของ 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}"],
)

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

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

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

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

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

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

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

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

ฟีเจอร์ เอกสารประกอบ
opt | dbg | fastbuild เปิดใช้โดยค่าเริ่มต้นในโหมดการรวบรวม
static_linking_mode | dynamic_linking_mode เปิดใช้โดยค่าเริ่มต้นตามโหมดการลิงก์
per_object_debug_info เปิดใช้หากมีการระบุและเปิดใช้ฟีเจอร์ supports_fission รวมถึงระบุโหมดการรวบรวมปัจจุบันในแฟล็ก --fission
supports_start_end_lib หากเปิดใช้ (และตั้งค่าตัวเลือก --start_end_lib) Bazel จะไม่ลิงก์กับไลบรารีแบบคงที่ แต่จะใช้ตัวเลือก --start-lib/--end-lib Linker เพื่อลิงก์กับออบเจ็กต์โดยตรงแทน วิธีนี้จะช่วยให้การสร้างเร็วขึ้นเนื่องจาก Bazel ไม่ต้องสร้างไลบรารีแบบคงที่
supports_interface_shared_libraries หากเปิดใช้ (และมีการตั้งค่าตัวเลือก --interface_shared_objects) Bazel จะลิงก์เป้าหมายที่มีการตั้งค่า linkstatic เป็น "เท็จ" (ค่าเริ่มต้นคือ cc_test) กับไลบรารีที่ใช้ร่วมกันของอินเทอร์เฟซ ทำให้การรีลิงก์เพิ่มขึ้นเร็วขึ้น
supports_dynamic_linker หากเปิดใช้ กฎ C++ จะรู้ว่า Toolchain สร้างไลบรารีที่ใช้ร่วมกันได้
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 ไปยังด้านบนของ Toolchain
  • ย้ายฟีเจอร์ default_compile_flags ไปยังด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ dependency_file (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ pic (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ per_object_debug_info (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ preprocessor_defines (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ includes (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ include_paths (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ fdo_instrument (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ fdo_optimize (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ cs_fdo_instrument (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ cs_fdo_optimize (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ fdo_prefetch_hints (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ autofdo (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ build_interface_libraries (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ dynamic_library_linker_tool (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ shared_flag (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ linkstamps (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ output_execpath_flags (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ runtime_library_search_directories (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ library_search_directories (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ archiver_flags (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ libraries_to_link (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ force_pic_flags (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ user_link_flags (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ legacy_link_flags (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ static_libgcc (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ fission_support (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ strip_debug_symbols (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ coverage (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ llvm_coverage_map_format (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ gcc_coverage_map_format (หากไม่มี) ที่ด้านบนของ Toolchain
  • เพิ่มฟีเจอร์ fully_static_link (หากไม่มี) ที่ด้านล่างของ Toolchain
  • เพิ่มฟีเจอร์ user_compile_flags (หากไม่มี) ที่ด้านล่างของ Toolchain
  • เพิ่มฟีเจอร์ sysroot (หากไม่มี) ที่ด้านล่างของ Toolchain
  • เพิ่มฟีเจอร์ unfiltered_compile_flags (หากไม่มี) ที่ด้านล่างของ Toolchain
  • เพิ่มฟีเจอร์ linker_param_file (หากไม่มี) ที่ด้านล่างของ Toolchain
  • เพิ่มฟีเจอร์ compiler_input_flags (หากไม่มี) ที่ด้านล่างของ Toolchain
  • เพิ่มฟีเจอร์ compiler_output_flags (หากไม่มี) ที่ด้านล่างของ Toolchain

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