प्लैटफ़ॉर्म पर माइग्रेट करना

Bazel में, मल्टी-आर्किटेक्चर और क्रॉस-कंपाइल किए गए बिल्ड के लिए, प्लैटफ़ॉर्म और टूलचेन को मॉडल करने की बेहतर सुविधा है.

इस पेज पर, इस सुविधा की स्थिति के बारे में बताया गया है.

यह भी देखें:

स्थिति

C++

C++ के नियम, प्लैटफ़ॉर्म का इस्तेमाल करके टूलचेन चुनते हैं. ऐसा तब होता है, जब --incompatible_enable_cc_toolchain_resolution सेट किया जाता है.

इसका मतलब है कि C++ प्रोजेक्ट को इनके साथ कॉन्फ़िगर किया जा सकता है:

bazel build //:my_cpp_project --platforms=//:myplatform

लेगसी के बजाय:

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

Bazel 7.0 (#7260) में, यह सुविधा डिफ़ॉल्ट रूप से चालू होगी.

प्लैटफ़ॉर्म के साथ अपने C++ प्रोजेक्ट की जांच करने के लिए, अपने प्रोजेक्ट को माइग्रेट करना और C++ टूलचेन कॉन्फ़िगर करना लेख देखें.

Java

Java के नियम, प्लैटफ़ॉर्म का इस्तेमाल करके टूलचेन चुनते हैं.

इससे लेगसी फ़्लैग --java_toolchain, --host_java_toolchain, --javabase, और --host_javabase बदल जाते हैं.

ज़्यादा जानकारी के लिए, Java और Bazel देखें.

Android

Android के नियम, प्लैटफ़ॉर्म का इस्तेमाल करके टूलचेन चुनते हैं. ऐसा तब होता है, जब --incompatible_enable_android_toolchain_resolution सेट किया जाता है.

इसका मतलब है कि Android प्रोजेक्ट को इनके साथ कॉन्फ़िगर किया जा सकता है:

bazel build //:my_android_project --android_platforms=//:my_android_platform

लेगसी फ़्लैग जैसे कि --android_crosstool_top, --android_cpu, और --fat_apk_cpu के बजाय.

Bazel 7.0 (#16285) में, यह सुविधा डिफ़ॉल्ट रूप से चालू होगी.

प्लैटफ़ॉर्म के साथ अपने Android प्रोजेक्ट की जांच करने के लिए, अपने प्रोजेक्ट को माइग्रेट करना लेख देखें.

Apple

Apple के नियम, प्लैटफ़ॉर्म के साथ काम नहीं करते. साथ ही, इन्हें प्लैटफ़ॉर्म के साथ काम करने के लिए शेड्यूल नहीं किया गया है .

Apple के बिल्ड के साथ प्लैटफ़ॉर्म एपीआई का इस्तेमाल अब भी किया जा सकता है. उदाहरण के लिए, Apple के नियमों और प्योर C++ के मिक्सचर के साथ बिल्ड करते समय, प्लैटफ़ॉर्म मैपिंग का इस्तेमाल किया जा सकता है.

अन्य भाषाएं

  • Go के नियम, प्लैटफ़ॉर्म के साथ पूरी तरह काम करते हैं
  • Rust के नियम, प्लैटफ़ॉर्म के साथ पूरी तरह काम करते हैं.

अगर आपके पास किसी भाषा के नियमों का सेट है, तो प्लैटफ़ॉर्म के साथ काम करने की सुविधा जोड़ने के लिए, अपने नियमों के सेट को माइग्रेट करना लेख देखें.

बैकग्राउंड

सॉफ़्टवेयर प्रोजेक्ट, अलग-अलग आर्किटेक्चर और क्रॉस-कंपाइल को कैसे टारगेट करते हैं, इसे स्टैंडर्ड बनाने के लिए प्लैटफ़ॉर्म और टूलचेन पेश किए गए थे.

ऐसा इसलिए किया गया, क्योंकि भाषा के रखरखाव करने वाले लोग, पहले से ही ऐसा कर रहे थे. हालांकि, वे अलग-अलग और असंगत तरीके अपना रहे थे. उदाहरण के लिए, C++ के नियम, टारगेट सीपीयू और टूलचेन का एलान करने के लिए --cpu और --crosstool_top का इस्तेमाल करते थे. इनमें से कोई भी, "प्लैटफ़ॉर्म" को सही तरीके से मॉडल नहीं करता. इस वजह से, बिल्ड में गड़बड़ियां होती थीं.

Java, Android, और अन्य भाषाओं ने भी इसी तरह के मकसद के लिए अपने फ़्लैग बनाए. हालांकि, इनमें से कोई भी एक-दूसरे के साथ काम नहीं करता था. इस वजह से, अलग-अलग भाषाओं के बिल्ड, उलझाने वाले और मुश्किल होते थे.

Bazel, बड़े, मल्टी-लैंग्वेज, मल्टी-प्लैटफ़ॉर्म प्रोजेक्ट के लिए बनाया गया है. इसके लिए, इन कॉन्सेप्ट के लिए ज़्यादा सिद्धांतों पर आधारित सहायता की ज़रूरत होती है. इसमें एक साफ़ स्टैंडर्ड एपीआई भी शामिल है.

माइग्रेशन की ज़रूरत

नए एपीआई पर अपग्रेड करने के लिए, दो काम करने होते हैं: एपीआई रिलीज़ करना और इसका इस्तेमाल करने के लिए, नियम के लॉजिक को अपग्रेड करना.

पहला काम पूरा हो गया है, लेकिन दूसरा काम जारी है. इसमें, भाषा के हिसाब से प्लैटफ़ॉर्म और टूलचेन तय करना, भाषा का लॉजिक, --crosstool_top जैसे पुराने फ़्लैग के बजाय नए एपीआई के ज़रिए टूलचेन पढ़ना, और config_settings, पुराने फ़्लैग के बजाय नए एपीआई पर चुनना शामिल है.

यह काम आसान है, लेकिन हर भाषा के लिए अलग से काम करना पड़ता है. साथ ही, प्रोजेक्ट के मालिकों को आने वाले बदलावों के हिसाब से जांच करने के लिए, पहले से चेतावनी देनी होती है.

इसलिए, यह माइग्रेशन जारी है.

लक्ष्य

यह माइग्रेशन तब पूरा होगा, जब सभी प्रोजेक्ट इस फ़ॉर्म में बिल्ड होंगे:

bazel build //:myproject --platforms=//:myplatform

इसका मतलब है कि:

  1. आपके प्रोजेक्ट के नियम, //:myplatform के लिए सही टूलचेन चुनते हैं.
  2. आपके प्रोजेक्ट की डिपेंडेंसी, //:myplatform के लिए सही टूलचेन चुनती हैं.
  3. //:myplatform रेफ़रंस देता है सामान्य एलान का, CPU, OS, और अन्य सामान्य, भाषा से जुड़ी प्रॉपर्टी का
  4. सभी काम के select()s, //:myplatform से सही तरीके से मैच होते हैं.
  5. //:myplatform को साफ़ तौर पर, आसानी से ऐक्सेस की जा सकने वाली जगह पर तय किया जाता है. जैसे, अगर प्लैटफ़ॉर्म आपके प्रोजेक्ट के लिए यूनीक है, तो आपके प्रोजेक्ट के रेपो में या किसी ऐसी सामान्य जगह पर जहां सभी इस्तेमाल करने वाले प्रोजेक्ट इसे ढूंढ सकें

--cpu, --crosstool_top, और --fat_apk_cpu जैसे पुराने फ़्लैग, बंद कर दिए जाएंगे और इन्हें हटा दिया जाएगा. ऐसा तब किया जाएगा, जब ऐसा करना सुरक्षित हो.

आखिरकार, आर्किटेक्चर को कॉन्फ़िगर करने का एकमात्र तरीका यही होगा.

अपने प्रोजेक्ट को माइग्रेट करना

अगर प्लैटफ़ॉर्म के साथ काम करने वाली भाषाओं का इस्तेमाल करके बिल्ड किया जाता है, तो आपका बिल्ड, इस तरह के इनवोकेशन के साथ पहले से ही काम करना चाहिए:

bazel build //:myproject --platforms=//:myplatform

ज़्यादा जानकारी के लिए, स्थिति और अपनी भाषा का दस्तावेज़ देखें.

अगर किसी भाषा के लिए, प्लैटफ़ॉर्म के साथ काम करने की सुविधा चालू करने के लिए किसी फ़्लैग की ज़रूरत होती है, तो आपको वह फ़्लैग भी सेट करना होगा. ज़्यादा जानकारी के लिए, स्थिति देखें.

अपने प्रोजेक्ट को बिल्ड करने के लिए, आपको यह देखना होगा कि:

  1. //:myplatform मौजूद होना चाहिए. प्लैटफ़ॉर्म तय करने की ज़िम्मेदारी आम तौर पर, प्रोजेक्ट के मालिक की होती है, क्योंकि अलग-अलग प्रोजेक्ट, अलग-अलग मशीनों को टारगेट करते हैं. डिफ़ॉल्ट प्लैटफ़ॉर्म देखें.

  2. जिन टूलचेन का इस्तेमाल करना है वे मौजूद होने चाहिए. अगर स्टॉक टूलचेन का इस्तेमाल किया जा रहा है, तो भाषा के मालिकों को उन्हें रजिस्टर करने के तरीके के बारे में निर्देश शामिल करने चाहिए. अगर अपने कस्टम टूलचेन लिखे जा रहे हैं, तो आपको उन्हें अपनी रजिस्टर फ़ाइल में या --extra_toolchains के साथ रजिस्टर करना होगा.MODULE.bazel

  3. select()s और कॉन्फ़िगरेशन ट्रांज़िशन, सही तरीके से रिज़ॉल्व होने चाहिए. select() और ट्रांज़िशन देखें.

  4. अगर आपके बिल्ड में ऐसी भाषाएं शामिल हैं जो प्लैटफ़ॉर्म के साथ काम करती हैं और ऐसी भाषाएं भी शामिल हैं जो प्लैटफ़ॉर्म के साथ काम नहीं करती हैं, तो आपको लेगसी भाषाओं को नए एपीआई के साथ काम करने में मदद करने के लिए, प्लैटफ़ॉर्म मैपिंग की ज़रूरत पड़ सकती है. ज़्यादा जानकारी के लिए, प्लैटफ़ॉर्म मैपिंग देखें.

अगर आपको अब भी समस्याएं आ रही हैं, तो सहायता के लिए संपर्क करें.

डिफ़ॉल्ट प्लैटफ़ॉर्म

प्रोजेक्ट के मालिकों को, उन आर्किटेक्चर के बारे में बताने के लिए साफ़ तौर पर प्लैटफ़ॉर्म तय करने चाहिए जिनके लिए वे बिल्ड करना चाहते हैं. इसके बाद, इन्हें --platforms के साथ ट्रिगर किया जाता है.

जब --platforms सेट नहीं किया जाता है, तो Bazel डिफ़ॉल्ट रूप से, platform को दिखाने वाले लोकल बिल्ड मशीन पर सेट हो जाता है. यह @platforms//host (जिसे @bazel_tools//tools:host_platform के तौर पर भी जाना जाता है) पर अपने-आप जनरेट होता है. इसलिए, इसे साफ़ तौर पर तय करने की ज़रूरत नहीं होती. यह लोकल मशीन के OS और CPU को constraint_values में तय किए गए @platforms के साथ मैप करता है.

select()

प्रोजेक्ट, select() पर constraint_value टारगेट कर सकते हैं, लेकिन पूरे प्लैटफ़ॉर्म पर नहीं. ऐसा इसलिए किया गया है, ताकि select() ज़्यादा से ज़्यादा मशीनों के साथ काम कर सके. ARM-खास सोर्स वाली लाइब्रेरी को सभी ARM-पावर वाली मशीनों के साथ काम करना चाहिए. हालांकि, अगर ज़्यादा जानकारी देने की कोई वजह हो, तो ऐसा नहीं करना चाहिए.

एक या उससे ज़्यादा constraint_values पर चुनने के लिए, इसका इस्तेमाल करें:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

यह पारंपरिक तौर पर --cpu पर चुनने के बराबर है:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

और डिटेल के लिए यहां जाएं.

selects, --cpu, --crosstool_top वगैरह पर --platforms को नहीं समझते. अपने प्रोजेक्ट को प्लैटफ़ॉर्म पर माइग्रेट करते समय, आपको या तो उन्हें constraint_values में बदलना होगा या माइग्रेशन के दौरान दोनों स्टाइल के साथ काम करने के लिए, प्लैटफ़ॉर्म मैपिंग का इस्तेमाल करना होगा.

ट्रांज़िशन

Starlark ट्रांज़िशन आपके बिल्ड ग्राफ़ के हिस्सों में फ़्लैग बदलते हैं. अगर आपका प्रोजेक्ट, ऐसे ट्रांज़िशन का इस्तेमाल करता है जो --cpu, --crossstool_top, या अन्य लेगसी फ़्लैग सेट करता है, तो --platforms पढ़ने वाले नियमों को ये बदलाव नहीं दिखेंगे.

अपने प्रोजेक्ट को प्लैटफ़ॉर्म पर माइग्रेट करते समय, आपको या तो return { "//command_line_option:cpu": "arm" } जैसे बदलावों को return { "//command_line_option:platforms": "//:my_arm_platform" } में बदलना होगा या माइग्रेशन के दौरान दोनों स्टाइल के साथ काम करने के लिए, प्लैटफ़ॉर्म मैपिंग का इस्तेमाल करना होगा. window.

अपने नियमों के सेट को माइग्रेट करना

अगर आपके पास नियमों का सेट है और आपको प्लैटफ़ॉर्म के साथ काम करने की सुविधा जोड़नी है, तो आपको ये काम करने होंगे:

  1. नियम के लॉजिक को टूलचेन एपीआई की मदद से टूलचेन रिज़ॉल्व करने की सुविधा दें. टूलचेन एपीआई (ctx.toolchains) देखें.

  2. ज़रूरी नहीं: --incompatible_enable_platforms_for_my_language फ़्लैग तय करें, ताकि नियम का लॉजिक, माइग्रेशन की जांच के दौरान, नए एपीआई या --crosstool_top जैसे पुराने फ़्लैग के ज़रिए टूलचेन रिज़ॉल्व करे.

  3. प्लैटफ़ॉर्म कॉम्पोनेंट बनाने वाली काम की प्रॉपर्टी तय करें. सामान्य प्लैटफ़ॉर्म प्रॉपर्टी देखें

  4. स्टैंडर्ड टूलचेन तय करें और उन्हें अपने नियम के रजिस्ट्रेशन के निर्देशों (ज़्यादा जानकारी) के ज़रिए उपयोगकर्ताओं के लिए उपलब्ध कराएं

  5. पक्का करें कि select()s और कॉन्फ़िगरेशन ट्रांज़िशन, प्लैटफ़ॉर्म के साथ काम करें. यह सबसे बड़ी चुनौती है. यह मल्टी-लैंग्वेज प्रोजेक्ट के लिए खास तौर पर मुश्किल है. ऐसा इसलिए, क्योंकि अगर सभी भाषाएं --platforms को नहीं पढ़ सकती हैं, तो ये प्रोजेक्ट काम नहीं करेंगे.

अगर आपको ऐसे नियमों के साथ मिक्स करना है जो प्लैटफ़ॉर्म के साथ काम नहीं करते हैं, तो आपको प्लैटफ़ॉर्म मैपिंग की ज़रूरत पड़ सकती है.

सामान्य प्लैटफ़ॉर्म प्रॉपर्टी

OS और CPU जैसी सामान्य, क्रॉस-लैंग्वेज प्लैटफ़ॉर्म प्रॉपर्टी को @platforms में तय किया जाना चाहिए. इससे शेयर करने, स्टैंडर्ड बनाने, और क्रॉस-लैंग्वेज के साथ काम करने की सुविधा मिलती है.

आपके नियमों के लिए यूनीक प्रॉपर्टी को आपके नियम के रेपो में तय किया जाना चाहिए. इससे, उन खास कॉन्सेप्ट पर आपका मालिकाना हक बना रहता है जिनके लिए आपके नियम ज़िम्मेदार हैं.

अगर आपके नियम, कस्टम-परपस ओएस या सीपीयू का इस्तेमाल करते हैं, तो इन्हें आपके नियम के रेपो में @platformsके बजाय तय किया जाना चाहिए.

प्लैटफ़ॉर्म मैपिंग

प्लैटफ़ॉर्म मैपिंग एक अस्थायी एपीआई है. इसकी मदद से, प्लैटफ़ॉर्म के साथ काम करने वाला लॉजिक, एक ही बिल्ड में लेगसी लॉजिक के साथ मिक्स हो सकता है. यह एक ऐसा टूल है जिसका इस्तेमाल सिर्फ़ अलग-अलग माइग्रेशन टाइमफ़्रेम के साथ होने वाली असंगतियों को कम करने के लिए किया जाता है.

प्लैटफ़ॉर्म मैपिंग, या तो platform() को लेगसी फ़्लैग के सेट से मैप करती है या इसके उलट. उदाहरण के लिए:

platforms:
  # Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
  //platforms:ios
    --ios_multi_cpus=x86_64
    --apple_platform_type=ios

flags:
  # Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --ios_multi_cpus=x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin_x86_64
  --apple_platform_type=macos
    //platforms:macos

Bazel इसका इस्तेमाल करके यह पक्का करता है कि प्लैटफ़ॉर्म पर आधारित और लेगसी, दोनों तरह की सभी सेटिंग, बिल्ड के दौरान एक जैसी हों. इसमें ट्रांज़िशनभी शामिल हैं.

डिफ़ॉल्ट रूप से, Bazel आपके वर्कस्पेस रूट में मौजूद platform_mappings फ़ाइल से मैपिंग पढ़ता है. --platform_mappings=//:my_custom_mapping भी सेट किया जा सकता है.

ज़्यादा जानकारी के लिए, प्लैटफ़ॉर्म मैपिंग का डिज़ाइन देखें.

एपीआई के ज़रिए समीक्षा करना

A platform कलेक्शन होता है constraint_value टारगेट का:

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

A constraint_value एक मशीन प्रॉपर्टी है. एक ही "तरह" की वैल्यू को, सामान्य constraint_setting के तहत ग्रुप किया जाता है:

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

एक toolchain एक Starlark नियम है. इसके एट्रिब्यूट, भाषा के टूल तय करते हैं. जैसे, compiler = "//mytoolchain:custom_gcc". इसके प्रोवाइडर, यह जानकारी उन नियमों को पास करते हैं जिन्हें इन टूल के साथ बिल्ड करना होता है.

टूलचेन, उन मशीनों के constraint_values तय करते हैं जिन्हें वे टारगेट (target_compatible_with = ["@platforms//os:linux"]) कर सकते हैं और उन मशीनों के constraint_values तय करते हैं जिन पर उनके टूल चल सकते हैं (exec_compatible_with = ["@platforms//os:mac"]).

जब $ bazel build //:myproject --platforms=//:myplatform बिल्ड किया जाता है, तो Bazel अपने-आप ऐसा टूलचेन चुनता है जो बिल्ड मशीन पर चल सकता है और //:myplatform के लिए बाइनरी बिल्ड कर सकता है. इसे टूलचेन रिज़ॉल्यूशन कहा जाता है.

उपलब्ध टूलचेन के सेट को MODULE.bazel फ़ाइल में register_toolchains के साथ या कमांड लाइन पर --extra_toolchains के साथ रजिस्टर किया जा सकता है.

ज़्यादा जानकारी के लिए, यहां देखें.

सवाल

सामान्य सहायता पाने और माइग्रेशन की समयसीमा के बारे में सवाल पूछने के लिए, bazel-discuss या सही नियमों के मालिकों से संपर्क करें.

प्लैटफ़ॉर्म/टूलचेन एपीआई के डिज़ाइन और डेवलपमेंट के बारे में चर्चा करने के लिए, bazel-dev से संपर्क करें.

इन्हें भी देखें