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

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",
    },
)

ज़्यादा जानकारी यहां देखें.

--cpu, --crosstool_top वगैरह पर selects, --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"]) कर सकते हैं और उन मशीनों का एलान करते हैं जिन पर उनके टूल चल सकते हैं (exec_compatible_with = ["@platforms//os:mac"]).

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

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

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

सवाल

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

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

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