इस पेज पर, Bazel की मदद से प्रोग्राम बनाने, बिल्ड कमांड सिंटैक्स, और टारगेट पैटर्न सिंटैक्स के बारे में बताया गया है.
क्विकस्टार्ट
Bazel को चलाने के लिए, अपनी बेस workspace डायरेक्ट्री या उसकी किसी भी सब-डायरेक्ट्री पर जाएं और bazel
टाइप करें. अगर आपको नया फ़ाइल फ़ोल्डर बनाना है, तो build देखें.
bazel help
[Bazel release bazel version]
Usage: bazel command options ...
उपलब्ध निर्देश
analyze-profile
: बिल्ड प्रोफ़ाइल के डेटा का विश्लेषण करता है.aquery
: विश्लेषण के बाद ऐक्शन ग्राफ़ पर क्वेरी लागू करता है.build
: तय किए गए टारगेट बनाता है.canonicalize-flags
: 'बेज़ल' फ़्लैग को कैननिकल के तौर पर मंज़ूरी दें.clean
: आउटपुट फ़ाइलें हटाता है और सर्वर को बंद कर देता है.cquery
: डिपेंडेंसी ग्राफ़ की विश्लेषण के बाद की जाने वाली क्वेरी को लागू करता है.dump
: Bazel सर्वर प्रोसेस की इंटरनल स्टेटस को डंप करता है.help
: निर्देशों या इंडेक्स के लिए सहायता प्रिंट करता है.info
: bazel सर्वर के बारे में रनटाइम की जानकारी दिखाता है.fetch
: किसी टारगेट की सभी बाहरी डिपेंडेंसी फ़ेच करता है.mobile-install
: मोबाइल डिवाइसों पर ऐप्लिकेशन इंस्टॉल करता है.query
: यह एक डिपेंडेंसी ग्राफ़ क्वेरी लागू करता है.run
: तय किए गए टारगेट को चलाता है.shutdown
: Bazel सर्वर को बंद करता है.test
: यह टूल, तय किए गए टेस्ट टारगेट को बनाता और चलाता है.version
: Basel के वर्शन की जानकारी प्रिंट करता है.
सहायता पाना
bazel help command
:command
के लिए प्रिंट करने से जुड़ी मदद और विकल्प.bazel help
startup_options
: Bazel को होस्ट करने वाले JVM के विकल्प.bazel help
target-syntax
: टारगेट तय करने के सिंटैक्स के बारे में बताता है.bazel help info-keys
: यह जानकारी कमांड में इस्तेमाल की गई कुंजियों की सूची दिखाता है.
bazel
टूल कई फ़ंक्शन करता है. इन्हें निर्देश कहा जाता है. आम तौर पर,
bazel build
और bazel test
इस्तेमाल होते हैं. bazel help
का इस्तेमाल करके, ऑनलाइन सहायता के मैसेज ब्राउज़ किए जा सकते हैं.
एक टारगेट बनाया जा रहा है
कोई बिल्ड शुरू करने से पहले, आपके पास वर्कस्पेस होना चाहिए. वर्कस्पेस एक डायरेक्ट्री ट्री होता है. इसमें आपके ऐप्लिकेशन को बनाने के लिए ज़रूरी सभी सोर्स फ़ाइलें होती हैं. Bazel की मदद से, पूरी तरह रीड-ओनली वाले वॉल्यूम से भी बिल्ड किया जा सकता है.
Bazel की मदद से प्रोग्राम बनाने के लिए, bazel build
टाइप करें. इसके बाद, वह टारगेट टाइप करें जिसे आपको बनाना है.
bazel build //foo
//foo
बनाने का निर्देश देने के बाद, आपको इससे मिलता-जुलता आउटपुट दिखेगा:
INFO: Analyzed target //foo:foo (14 packages loaded, 48 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
bazel-bin/foo/foo
INFO: Elapsed time: 9.905s, Critical Path: 3.25s
INFO: Build completed successfully, 6 total actions
सबसे पहले, Bazel आपके टारगेट के डिपेंडेंसी ग्राफ़ में सभी पैकेज लोड करता है. इसमें एलान की गई डिपेंडेंसी शामिल हैं. ये फ़ाइलें, टारगेट की BUILD
फ़ाइल में सीधे तौर पर शामिल होती हैं. साथ ही, इसमें ट्रांज़िशन डिपेंडेंसी भी शामिल हैं. ये फ़ाइलें, टारगेट की डिपेंडेंसी की BUILD
फ़ाइलों में शामिल होती हैं. सभी डिपेंडेंसी की पहचान करने के बाद, BaZ चैनल उनका विश्लेषण
करते हैं और उनके सही होने की जांच करते हैं. साथ ही, बिल्ड ऐक्शन बनाते हैं. आखिर में, Basel, बिल्ड के कंपाइलर और अन्य टूल
को इस्तेमाल करता है.
बिल्ड को एक्ज़ीक्यूट करने के दौरान, Basel, प्रोग्रेस मैसेज को प्रिंट करता है. प्रोग्रेस मैसेज में, बने प्रोग्राम के मौजूदा चरण (जैसे, कंपाइलर या लिंकर) के शुरू होने की जानकारी शामिल होती है. साथ ही, बने प्रोग्राम की कुल कार्रवाइयों में से पूरी की गई कार्रवाइयों की संख्या भी शामिल होती है. बिल्ड शुरू होते ही, कुल कार्रवाइयों की संख्या अक्सर बढ़ जाती है क्योंकि बेज़ल पूरा ऐक्शन ग्राफ़ खोजते हैं, लेकिन कुछ ही सेकंड में ये संख्या स्थिर हो जाती है.
बिल्ड के आखिर में, Bazel यह जानकारी दिखाता है कि किन टारगेट का अनुरोध किया गया था, वे बिल्ड हुए या नहीं, और अगर बिल्ड हुए हैं, तो आउटपुट फ़ाइलें कहां मिल सकती हैं. बिल्ड चलाने वाली स्क्रिप्ट, इस आउटपुट को भरोसेमंद तरीके से पार्स कर सकती हैं. ज़्यादा जानकारी के लिए, --show_result
देखें.
अगर एक ही कमांड को फिर से टाइप किया जाता है, तो बिल्ड बहुत तेज़ी से पूरा हो जाता है.
bazel build //foo
INFO: Analyzed target //foo:foo (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
bazel-bin/foo/foo
INFO: Elapsed time: 0.144s, Critical Path: 0.00s
INFO: Build completed successfully, 1 total action
यह शून्य बिल्ड है. कोई बदलाव न होने की वजह से, रीफ़्रेश करने के लिए कोई पैकेज नहीं है और न ही कोई बिल्ड चरण है. अगर 'foo' या इसकी डिपेंडेंसी में कोई बदलाव होता है, तो Basel, बिल्ड से जुड़ी कुछ कार्रवाइयों को फिर से लागू करेगा या इंक्रीमेंटल बिल्ड पूरा करेगा.
कई लक्ष्य बनाना
Bazel में, बिल्ड किए जाने वाले टारगेट की जानकारी देने के कई तरीके हैं. इन्हें एक साथ, टारगेट पैटर्न कहा जाता है. इस सिंटैक्स का इस्तेमाल build
, test
या query
जैसे निर्देशों में किया जाता है.
जहां लेबल का इस्तेमाल अलग-अलग टारगेट की जानकारी देने के लिए किया जाता है, जैसे कि BUILD
फ़ाइलों में डिपेंडेंसी का एलान करने के लिए, वहीं बेज़ल के टारगेट पैटर्न एक से ज़्यादा टारगेट के बारे में बताते हैं. टारगेट पैटर्न, वाइल्डकार्ड का इस्तेमाल करके, टारगेट के सेट के लिए लेबल सिंटैक्स को सामान्य बनाते हैं. सबसे आसान मामले में, कोई भी मान्य लेबल एक मान्य टारगेट पैटर्न भी होता है. यह सिर्फ़ एक टारगेट के सेट की पहचान करता है.
//
से शुरू होने वाले सभी टारगेट पैटर्न का समाधान, मौजूदा फ़ाइल फ़ोल्डर के हिसाब से किया जाता है.
//foo/bar:wiz |
सिर्फ़ एक टारगेट //foo/bar:wiz . |
//foo/bar |
//foo/bar:bar के बराबर. |
//foo/bar:all |
पैकेज foo/bar में मौजूद सभी नियम टारगेट. |
//foo/... |
डायरेक्ट्री foo के नीचे मौजूद सभी पैकेज में मौजूद सभी नियम टारगेट. |
//foo/...:all |
foo डायरेक्ट्री के नीचे मौजूद सभी पैकेज में, सभी नियम टारगेट किए जाते हैं. |
//foo/...:* |
डायरेक्ट्री foo के नीचे मौजूद सभी पैकेज के सभी टारगेट (नियम और फ़ाइलें). |
//foo/...:all-targets |
डायरेक्ट्री foo के नीचे मौजूद सभी पैकेज के सभी टारगेट (नियम और फ़ाइलें). |
//... |
डेटा स्टोर करने की मुख्य जगह में मौजूद पैकेज में मौजूद सभी नियम टारगेट. इसमें बाहरी रिपॉज़िटरी के टारगेट शामिल नहीं होते. |
//:all |
अगर वर्कस्पेस के रूट में `BUILD` फ़ाइल है, तो टॉप-लेवल पैकेज में मौजूद सभी नियम के टारगेट. |
//
से शुरू न होने वाले टारगेट पैटर्न, मौजूदा वर्किंग डायरेक्ट्री के हिसाब से हल किए जाते हैं. इन उदाहरणों में, foo
की ऐक्टिव डायरेक्ट्री के बारे में बताया गया है:
:foo |
//foo:foo के बराबर. |
bar:wiz |
//foo/bar:wiz के बराबर. |
bar/wiz |
इनके बराबर है:
|
bar:all |
//foo/bar:all के बराबर. |
:all |
//foo:all की तरह काम करता है. |
...:all |
//foo/...:all की तरह काम करता है. |
... |
//foo/...:all के बराबर. |
bar/...:all |
//foo/bar/...:all के बराबर. |
डिफ़ॉल्ट रूप से, बार-बार इस्तेमाल होने वाले टारगेट पैटर्न के लिए, डायरेक्ट्री के सिमलिंक का इस्तेमाल किया जाता है. हालांकि, उन सिमलिंक के लिए ऐसा नहीं किया जाता जो आउटपुट बेस में मौजूद होते हैं. जैसे, Workspace की रूट डायरेक्ट्री में बनाए गए सिमलिंक.
इसके अलावा, Bazel किसी भी डायरेक्ट्री में, बार-बार इस्तेमाल होने वाले टारगेट पैटर्न का आकलन करते समय, सिमलिंक का इस्तेमाल नहीं करता. इस डायरेक्ट्री में, इस तरह का नाम वाली फ़ाइल होनी चाहिए:
DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN
foo/...
, पैकेज के लिए वाइल्डकार्ड है. यह डायरेक्ट्री foo
के नीचे मौजूद सभी पैकेज के बारे में बताता है. यह पैकेज पाथ के सभी रूट के लिए होता है. :all
, टारगेट के लिए वाइल्डकार्ड है. यह किसी पैकेज में मौजूद सभी नियमों से मैच करता है. इन दोनों को एक साथ इस्तेमाल किया जा सकता है, जैसे कि foo/...:all
में. दोनों वाइल्डकार्ड का इस्तेमाल करने पर, इसे foo/...
के तौर पर छोटा किया जा सकता है.
इसके अलावा, :*
(या :all-targets
) एक वाइल्डकार्ड है, जो मैच किए गए पैकेज में हर टारगेट से मैच करता है. इसमें ऐसी फ़ाइलें भी शामिल हैं जो आम तौर पर किसी नियम के हिसाब से नहीं बनाई जाती हैं. जैसे, java_binary
नियमों से जुड़ी _deploy.jar
फ़ाइलें.
इसका मतलब है कि :*
, :all
के सुपरसेट को दिखाता है. हालांकि, यह सिंटैक्स कुछ हद तक भ्रमित करता है. हालांकि, यह सिंटैक्स सामान्य :all
वाइल्डकार्ड का इस्तेमाल सामान्य बिल्ड के लिए करता है, जहां _deploy.jar
जैसे बिल्डिंग टारगेट की ज़रूरत नहीं होती.
इसके अलावा, लेबल सिंटैक्स के लिए ज़रूरी कोलन के बजाय, स्लैश का इस्तेमाल किया जा सकता है. Bash फ़ाइल नाम को बड़ा करने की सुविधा का इस्तेमाल करते समय, यह अक्सर सुविधाजनक होता है.
उदाहरण के लिए, अगर कोई पैकेज foo/bar
है, तो foo/bar/wiz
वैल्यू //foo/bar:wiz
के बराबर होगी. अगर कोई पैकेज foo
है, तो foo/bar/wiz
वैल्यू //foo:bar/wiz
के बराबर होगी.
कई Baज़ल कमांड, टारगेट पैटर्न की सूची को आर्ग्युमेंट के तौर पर स्वीकार करते हैं. साथ ही, वे सभी प्रीफ़िक्स निगेशन ऑपरेटर -
का पालन करते हैं. इसका इस्तेमाल, पिछले आर्ग्युमेंट से तय किए गए सेट से, टारगेट के किसी सेट को घटाने के लिए किया जा सकता है. ध्यान दें कि इसका मतलब है कि क्रम का ध्यान रखना ज़रूरी है. उदाहरण के लिए,
bazel build foo/... bar/...
का मतलब है कि "foo
और bar
के नीचे मौजूद सभी टारगेट बनाएं", जबकि
bazel build -- foo/... -foo/bar/...
का मतलब है कि "foo/bar
के नीचे मौजूद टारगेट को छोड़कर, foo
के नीचे मौजूद सभी टारगेट बनाएं". (-
से शुरू होने वाले बाद के आर्ग्युमेंट को अतिरिक्त विकल्पों के तौर पर समझने से रोकने के लिए, --
आर्ग्युमेंट ज़रूरी है.)
हालांकि, यह बताना ज़रूरी है कि इस तरह से टारगेट घटाने से, यह गारंटी नहीं मिलेगी कि वे बिल्ट नहीं किए गए हैं. ऐसा इसलिए, क्योंकि वे उन टारगेट की डिपेंडेंसी हो सकते हैं जिन्हें घटाया नहीं गया था. उदाहरण के लिए, अगर कोई टारगेट //foo:all-apis
था, जो //foo/bar:api
पर निर्भर था, तो //foo/bar:api
को //foo:all-apis
बनाने के हिस्से के तौर पर बनाया जाएगा.
tags = ["manual"]
वाले टारगेट, वाइल्डकार्ड टारगेट पैटर्न (...
, :*
, :all
वगैरह) में शामिल नहीं किए जाते, जब उन्हें bazel build
और bazel test
जैसे निर्देशों में बताया जाता है. हालांकि, उन्हें नेगेटिव वाइल्डकार्ड टारगेट पैटर्न में शामिल किया जाता है, यानी उनसे घटाया जाएगा. अगर आपको Bazel से इन टेस्ट टारगेट को बनाने/जांच करने के लिए कहना है, तो आपको कमांड लाइन पर साफ़ तौर पर टारगेट पैटर्न के साथ इन टारगेट की जानकारी देनी चाहिए. वहीं दूसरी ओर, bazel query
अपने-आप इस तरह की कोई फ़िल्टर लागू नहीं करता (इससे bazel query
का मकसद खत्म हो जाएगा).
बाहरी डिपेंडेंसी फ़ेच करना
डिफ़ॉल्ट रूप से, Bazel, बिल्ड के दौरान बाहरी डिपेंडेंसी डाउनलोड और लिंक करेगा. हालांकि, ऐसा करने की ज़रूरत नहीं हो सकती, क्योंकि आपको यह जानना है कि नई बाहरी डिपेंडेंसी कब जोड़ी जाती हैं या आपको "प्रीफ़ेच" डिपेंडेंसी कब करनी हैं (जैसे, किसी ऐसी फ़्लाइट से पहले जहां आप ऑफ़लाइन होंगे). अगर आपको बिल्ड के दौरान नई डिपेंडेंसी जोड़ने से रोकना है, तो --fetch=false
फ़्लैग का इस्तेमाल करें. ध्यान दें कि यह फ़्लैग सिर्फ़ उन रिपॉज़िटरी नियमों पर लागू होता है जो लोकल फ़ाइल सिस्टम में किसी डायरेक्ट्री पर ले जाते हैं. उदाहरण के लिए, local_repository
,
new_local_repository
, और Android SDK टूल और NDK रिपॉज़िटरी के नियमों में किए गए बदलाव, --fetch
की वैल्यू के बावजूद हमेशा लागू होंगे .
अगर आप बिल्ड के दौरान फ़ेच करने की अनुमति नहीं देते और Basel को नई बाहरी डिपेंडेंसी मिलती है, तो आपका बिल्ड फ़ेल हो जाएगा.
bazel fetch
चलाकर, डिपेंडेंसी को मैन्युअल तरीके से फ़ेच किया जा सकता है. अगर
बिल्ड फ़ेच करने के दौरान अनुमति नहीं दी जाती है, तो आपको bazel fetch
चलाना होगा:
- पहली बार बनाने से पहले.
- नई बाहरी डिपेंडेंसी जोड़ने के बाद.
इसे एक बार चलाने के बाद, जब तक MODULE.bazel फ़ाइल में बदलाव नहीं होता, तब तक आपको इसे फिर से चलाने की ज़रूरत नहीं होगी.
fetch
, डिपेंडेंसी फ़ेच करने के लिए टारगेट की सूची लेता है. उदाहरण के लिए, इससे //foo:bar
और //bar:baz
को बनाने के लिए ज़रूरी डिपेंडेंसी फ़ेच होंगी:
bazel fetch //foo:bar //bar:baz
किसी वर्कस्पेस की सभी बाहरी डिपेंडेंसी फ़ेच करने के लिए, इसे चलाएं:
bazel fetch //...
Bazel 7 या उसके बाद के वर्शन में, अगर आपने Bzlmod चालू किया है, तो सभी बाहरी डिपेंडेंसी को फ़ेच करने के लिए,
bazel fetch
अगर आपके पास अपने फ़ाइल फ़ोल्डर के रूट में, इस्तेमाल किए जा रहे सभी टूल (लाइब्रेरी जार से लेकर JDK तक) हैं, तो आपको बेज़ल फ़ेच चलाने की ज़रूरत नहीं है.
हालांकि, अगर Workspace डायरेक्ट्री के बाहर की किसी चीज़ का इस्तेमाल किया जा रहा है, तो Bazel, bazel build
को चलाने से पहले bazel fetch
को अपने-आप चला देगा.
रिपॉज़िटरी कैश मेमोरी
Bazel, एक ही फ़ाइल को कई बार फ़ेच करने से बचने की कोशिश करता है. भले ही, अलग-अलग वर्कस्पेस में एक ही फ़ाइल की ज़रूरत हो या किसी बाहरी रिपॉज़िटरी की परिभाषा बदल गई हो, लेकिन उसे डाउनलोड करने के लिए अब भी उसी फ़ाइल की ज़रूरत हो. ऐसा करने के लिए,
bazel, डाउनलोड की गई सभी फ़ाइलों को रिपॉज़िटरी कैश में कैश मेमोरी में सेव करता है. यह कैश मेमोरी डिफ़ॉल्ट रूप से ~/.cache/bazel/_bazel_$USER/cache/repos/v1/
में मौजूद होती है. --repository_cache
विकल्प की मदद से, जगह बदली जा सकती है. कैश मेमोरी को सभी फ़ाइल फ़ोल्डर और बेज़ल के इंस्टॉल किए गए वर्शन के बीच शेयर किया जाता है.
कैश मेमोरी से कोई एंट्री तब ली जाती है, जब Bazel को पता हो कि उसके पास सही फ़ाइल की कॉपी है. इसका मतलब है कि अगर डाउनलोड अनुरोध में, बताई गई फ़ाइल का SHA256 योग है और उस हैश वाली फ़ाइल कैश मेमोरी में मौजूद है. इसलिए, हर बाहरी फ़ाइल के लिए हैश तय करना, सुरक्षा के लिहाज़ से ही नहीं, बल्कि ग़ैर-ज़रूरी डाउनलोड से बचने के लिए भी एक अच्छा आइडिया है.
कैश मेमोरी में हर बार हिट होने पर, कैश मेमोरी में मौजूद फ़ाइल में किए गए बदलाव का समय अपडेट हो जाता है. इस तरह, कैश मेमोरी की डायरेक्ट्री में मौजूद किसी फ़ाइल के आखिरी इस्तेमाल का पता आसानी से लगाया जा सकता है. उदाहरण के लिए, कैश मेमोरी को मैन्युअल तरीके से खाली करने के लिए. कैश मेमोरी कभी भी अपने-आप नहीं मिटती, क्योंकि इसमें ऐसी फ़ाइल की कॉपी हो सकती है जो अब अपस्ट्रीम में उपलब्ध नहीं है.
[अब काम नहीं करती] डिस्ट्रिब्यूशन फ़ाइलों की डायरेक्ट्री
अब काम नहीं करता: ऑफ़लाइन बिल्ड पाने के लिए, रिपॉज़िटरी कैश मेमोरी का इस्तेमाल करना बेहतर माना जाता है.
डिस्ट्रिब्यूशन डायरेक्ट्री, Bazel का एक और तरीका है. इसका इस्तेमाल, ग़ैर-ज़रूरी डाउनलोड से बचने के लिए किया जाता है. Bazel, रिपॉज़िटरी कैश से पहले डिस्ट्रिब्यूशन डायरेक्ट्री खोजता है. मुख्य अंतर यह है कि डिस्ट्रिब्यूशन डायरेक्ट्री को मैन्युअल तरीके से तैयार करना पड़ता है.
--distdir=/path/to-directory
विकल्प का इस्तेमाल करके, फ़ाइलों को खोजने के लिए उन्हें फ़ेच करने के बजाय, रीड-ओनली ऐक्सेस वाली अतिरिक्त डायरेक्ट्री तय की जा सकती है. किसी फ़ाइल को ऐसी डायरेक्ट्री से तब लिया जाता है, जब फ़ाइल का नाम यूआरएल के बेस नेम से मेल खाता हो. साथ ही, फ़ाइल का हैश, डाउनलोड के अनुरोध में बताए गए हैश से मेल खाता हो. यह सिर्फ़ तब काम करता है, जब फ़ाइल हैश को रिपॉज़िटरी के नियम के एलान में बताया गया हो.
फ़ाइल के नाम की शर्त को सही बनाने के लिए ज़रूरी नहीं है. हालांकि, इससे हर डायरेक्ट्री के लिए, फ़ाइलों की संख्या एक हो जाती है. इस तरह, डिस्ट्रिब्यूशन फ़ाइलों की डायरेक्ट्री तय करना कारगर रहता है. भले ही, ऐसी डायरेक्ट्री में फ़ाइलों की संख्या ज़्यादा हो.
एयरगैप वाले एनवायरमेंट में Bazel को चलाना
Baze की बाइनरी साइज़ को छोटा रखने के लिए, पहली बार चलते समय Baज़ल की इंप्लिसिट डिपेंडेंसी को नेटवर्क पर फ़ेच किया जाता है. इन डिपेंडेंसी में ऐसे टूलचेन और नियम शामिल होते हैं जो शायद सभी के लिए ज़रूरी न हों. उदाहरण के लिए, Android टूल सिर्फ़ तब अनबंड किए जाते हैं और फ़ेच किए जाते हैं, जब Android प्रोजेक्ट बनाए जाते हैं.
हालांकि, इन छिपी हुई डिपेंडेंसी की वजह से, एयरगैप वाले एनवायरमेंट में Bazel को चलाने में समस्याएं आ सकती हैं. भले ही, आपने अपनी सभी बाहरी डिपेंडेंसी को वेंडर के तौर पर जोड़ लिया हो. इस समस्या को हल करने के लिए, नेटवर्क ऐक्सेस वाली मशीन पर, इन डिपेंडेंसी वाली कोई रिपॉज़िटरी कैश (Bazel 7 या उसके बाद के वर्शन के साथ) या डिस्ट्रिब्यूशन डायरेक्ट्री (Bazel 7 से पहले के वर्शन के साथ) तैयार की जा सकती है. इसके बाद, उन्हें ऑफ़लाइन तरीके से, एयरगैप वाले एनवायरमेंट में ट्रांसफ़र किया जा सकता है.
रिपॉज़िटरी कैश मेमोरी (Bazel 7 या उसके बाद के वर्शन के साथ)
रिपॉज़िटरी कैश मेमोरी तैयार करने के लिए, --repository_cache
फ़्लैग का इस्तेमाल करें. आपको हर नए Basel बाइनरी वर्शन के लिए ऐसा एक बार करना होगा, क्योंकि
हर रिलीज़ के लिए इंप्लिसिट डिपेंडेंसी अलग-अलग हो सकती हैं.
एयरगैप किए गए एनवायरमेंट से बाहर उन डिपेंडेंसी को फ़ेच करने के लिए, पहले एक खाली फ़ाइल फ़ोल्डर बनाएं:
mkdir empty_workspace && cd empty_workspace
touch MODULE.bazel
Bzlmod की पहले से मौजूद डिपेंडेंसी फ़ेच करने के लिए, यह चलाएं
bazel fetch --repository_cache="path/to/repository/cache"
अगर अब भी लेगसी WORKSPACE फ़ाइल का इस्तेमाल किया जा रहा है, तो पहले से मौजूद WORKSPACE डिपेंडेंसी फ़ेच करने के लिए,
bazel sync --repository_cache="path/to/repository/cache"
आखिर में, अपने एयरगेप किए गए एनवायरमेंट में Basel का इस्तेमाल करते समय, वही
--repository_cache
फ़्लैग पास करें. आसानी के लिए, इसे .bazelrc
एंट्री के तौर पर जोड़ा जा सकता है:
common --repository_cache="path/to/repository/cache"
इसके अलावा, आपको BCR को स्थानीय तौर पर क्लोन करना पड़ सकता है. साथ ही, अपनी स्थानीय कॉपी को इंगित करने के लिए --registry
फ़्लैग का इस्तेमाल करना पड़ सकता है, ताकि Bazel इंटरनेट के ज़रिए बीसीआर को ऐक्सेस न कर सके. अपने .bazelrc
में यह लाइन जोड़ें:
common --registry="path/to/local/bcr/registry"
डिस्ट्रिब्यूशन डायरेक्ट्री (7 से पहले के Bazel के साथ)
डिस्ट्रिब्यूशन डायरेक्ट्री बनाने के लिए, --distdir
फ़्लैग का इस्तेमाल करें. आपको हर नए Basel बाइनरी वर्शन के लिए ऐसा एक बार करना होगा, क्योंकि
हर रिलीज़ के लिए इंप्लिसिट डिपेंडेंसी अलग-अलग हो सकती हैं.
अपने एयरगैप किए गए एनवायरमेंट के बाहर इन डिपेंडेंसी को बनाने के लिए, सबसे पहले सही वर्शन में Bazel सोर्स ट्री को चेक आउट करें:
git clone https://github.com/bazelbuild/bazel "$BAZEL_DIR"
cd "$BAZEL_DIR"
git checkout "$BAZEL_VERSION"
इसके बाद, उस खास Bazel वर्शन के लिए, रनटाइम की लागू डिपेंडेंसी वाला टार्बॉल बनाएं:
bazel build @additional_distfiles//:archives.tar
इस टार्बॉल को ऐसी डायरेक्ट्री में एक्सपोर्ट करें जिसे आपके एयरगैप किए गए एनवायरमेंट में कॉपी किया जा सके. --strip-components
फ़्लैग पर ध्यान दें, क्योंकि --distdir
डायरेक्ट्री नेस्टिंग लेवल के साथ काफ़ी मुश्किल हो सकता है:
tar xvf bazel-bin/external/additional_distfiles/archives.tar \
-C "$NEW_DIRECTORY" --strip-components=3
आखिर में, अपने एयरगेप किए गए एनवायरमेंट में Basel का इस्तेमाल करते समय, डायरेक्ट्री की ओर इशारा करने वाला --distdir
फ़्लैग पास करें. आसानी के लिए, इसे .bazelrc
एंट्री के तौर पर जोड़ा जा सकता है:
build --distdir=path/to/directory
बिल्ड कॉन्फ़िगरेशन और क्रॉस-कंपाइलेशन
किसी खास बिल्ड के व्यवहार और नतीजे की जानकारी देने वाले सभी इनपुट को दो अलग-अलग कैटगरी में बांटा जा सकता है. पहली तरह की जानकारी, आपके प्रोजेक्ट की BUILD
फ़ाइलों में सेव की गई खास जानकारी होती है: बिल्ड नियम, उसके एट्रिब्यूट की वैल्यू, और ट्रांज़िशन डेपेंडेंसी का पूरा सेट.
दूसरा टाइप, बाहरी या पर्यावरण से जुड़ा डेटा है, जो उपयोगकर्ता या बिल्ड टूल से मिलता है: टारगेट आर्किटेक्चर, कंपाइलेशन और लिंकिंग
के विकल्प, और टूलचेन कॉन्फ़िगरेशन के अन्य विकल्प. हम पर्यावरण से जुड़े डेटा के पूरे सेट को कॉन्फ़िगरेशन कहते हैं.
किसी भी बिल्ड में, एक से ज़्यादा कॉन्फ़िगरेशन हो सकते हैं. क्रॉस-कंपाइल करने के बारे में सोचें. इसमें, 64-बिट आर्किटेक्चर के लिए //foo:bin
एक्ज़ीक्यूटेबल बनाया जाता है, लेकिन आपका वर्कस्टेशन 32-बिट मशीन है. साफ़ तौर पर, बिल्ड के लिए //foo:bin
को ऐसे टूलचेन का इस्तेमाल करके बनाना होगा जो 64-बिट के रन किए जा सकने वाले प्रोग्राम बना सके. हालांकि, बिल्ड सिस्टम को बिल्ड के दौरान इस्तेमाल किए जाने वाले अलग-अलग टूल भी बनाने होंगे. उदाहरण के लिए, ऐसे टूल जिन्हें सोर्स से बनाया जाता है और फिर किसी genrule में इस्तेमाल किया जाता है. साथ ही, इन्हें आपके वर्कस्टेशन पर चलाने के लिए बनाना होगा. इस तरह हम दो कॉन्फ़िगरेशन की पहचान कर सकते हैं: एक्ज़िक कॉन्फ़िगरेशन, जिसका इस्तेमाल बिल्ड के दौरान चलने वाले टूल बनाने में किया जाता है और टारगेट कॉन्फ़िगरेशन (या कॉन्फ़िगरेशन का अनुरोध करें, लेकिन हम "टारगेट कॉन्फ़िगरेशन" को ज़्यादा कहते हैं. भले ही, उस शब्द के पहले से ही कई मतलब हों) जिसका इस्तेमाल आपने असल में अनुरोध की गई बाइनरी बनाने के लिए किया है.
आम तौर पर, ऐसी कई लाइब्रेरी होती हैं जो अनुरोध किए गए बिल्ड टारगेट (//foo:bin
) और एक या उससे ज़्यादा एक्सेक्यूट टूल, दोनों के लिए ज़रूरी होती हैं. उदाहरण के लिए, कुछ बेस लाइब्रेरी. ऐसी लाइब्रेरी को दो बार बनाया जाना चाहिए. एक बार, एक्सीक्यूट करने के लिए कॉन्फ़िगरेशन के लिए और एक बार, टारगेट कॉन्फ़िगरेशन के लिए. Bazel यह पक्का करता है कि दोनों वैरिएंट बनाए जाएं और इंटरफ़ियरेंस से बचने के लिए, डेरिव्ड फ़ाइलों को अलग रखा जाए. आम तौर पर, ऐसे टारगेट एक साथ बनाए जा सकते हैं, क्योंकि वे एक-दूसरे से अलग होते हैं. अगर आपको प्रोग्रेस मैसेज दिखते हैं, जिनसे पता चलता है कि किसी टारगेट को दो बार बनाया जा रहा है, तो इसकी वजह यह हो सकती है.
निष्पादन कॉन्फ़िगरेशन को लक्ष्य कॉन्फ़िगरेशन से इस प्रकार प्राप्त किया जाता है:
- अनुरोध कॉन्फ़िगरेशन में बताए गए Crosstool (
--crosstool_top
) के उसी वर्शन का इस्तेमाल करें, जब तक कि--host_crosstool_top
की जानकारी न दी गई हो. --cpu
के लिए--host_cpu
के मान का इस्तेमाल करें (डिफ़ॉल्ट:k8
).- इन विकल्पों की वैल्यू, अनुरोध के कॉन्फ़िगरेशन में बताई गई वैल्यू जैसी ही होनी चाहिए:
--compiler
,--use_ijars
. अगर--host_crosstool_top
का इस्तेमाल किया जाता है, तो--host_cpu
की वैल्यू का इस्तेमाल, exec कॉन्फ़िगरेशन के लिए Crosstool मेंdefault_toolchain
को खोजने के लिए किया जाता है (--compiler
को अनदेखा किया जाता है). --javabase
के लिए--host_javabase
की वैल्यू का इस्तेमाल करें--java_toolchain
के लिए--host_java_toolchain
की वैल्यू का इस्तेमाल करें- C++ कोड (
-c opt
) के लिए ऑप्टिमाइज़ किए गए बिल्ड का इस्तेमाल करें. - डीबग करने से जुड़ी कोई जानकारी जनरेट न करें (
--copt=-g0
). - एक्ज़ीक्यूटेबल और शेयर की गई लाइब्रेरी से डीबग जानकारी को निकालें
(
--strip=always
). - सभी डेरिव्ड फ़ाइलों को किसी खास जगह पर रखें. यह जगह, अनुरोध के किसी भी संभावित कॉन्फ़िगरेशन से अलग होनी चाहिए.
- बिल्डर डेटा के साथ बाइनरी को स्टैंप करने की सुविधा बंद करें (
--embed_*
विकल्प देखें). - अन्य सभी वैल्यू अपनी डिफ़ॉल्ट वैल्यू पर सेट रहती हैं.
अनुरोध कॉन्फ़िगरेशन से अलग, कोई दूसरा एक्सीक्यूट कॉन्फ़िगरेशन चुनने की कई वजहें हो सकती हैं. सबसे ज़रूरी बात:
सबसे पहले, हटाई गई और ऑप्टिमाइज़ की गई बाइनरी का इस्तेमाल करके, टूल को लिंक करने और चलाने में लगने वाला समय कम किया जा सकता है. साथ ही, टूल के लिए डिस्क का इस्तेमाल कम किया जा सकता है और डिस्ट्रिब्यूट किए गए बिल्ड में नेटवर्क I/O का समय कम किया जा सकता है.
दूसरी बात, सभी बिल्ड में exec को डीकोड करके और कॉन्फ़िगरेशन के लिए अनुरोध करके, रीबिल्ड से बचा जा सकता है. इसकी वजह यह है कि अनुरोध कॉन्फ़िगरेशन में मामूली बदलाव (जैसे कि लिंकर के विकल्पों में बदलाव करना) की वजह से हो सकता है, जैसा कि पहले बताया गया है.
इंक्रीमेंटल रीबिल्ड को ठीक करना
Bazel प्रोजेक्ट का एक मुख्य लक्ष्य, यह पक्का करना है कि इंक्रीमेंटल रीबिल्ड सही तरीके से हो. पिछले बिल्ड टूल, खास तौर पर Make पर आधारित टूल, इंक्रीमेंटल बिल्ड लागू करने के दौरान कई गलत अनुमान लगाते हैं.
पहला, फ़ाइलों के टाइमस्टैंप लगातार बढ़ते जाते हैं. हालांकि, यह आम तौर पर होता है, लेकिन इस धारणा को गलत साबित करना बहुत आसान है. किसी फ़ाइल के पुराने वर्शन के साथ सिंक करने पर, उस फ़ाइल में बदलाव करने में लगने वाला समय कम हो जाता है. साथ ही, Make पर आधारित सिस्टम, फ़ाइल को फिर से नहीं बनाएंगे.
आम तौर पर, Make फ़ाइलों में हुए बदलावों का पता लगाता है, लेकिन निर्देशों में हुए बदलावों का पता नहीं लगाता. अगर किसी बिल्ड चरण में, कंपाइलर को पास किए गए विकल्पों में बदलाव किया जाता है, तो Make कंपाइलर को फिर से नहीं चलाएगा. साथ ही, make clean
का इस्तेमाल करके, पिछले बिल्ड के अमान्य आउटपुट को मैन्युअल तरीके से खारिज करना ज़रूरी है.
साथ ही, Make किसी सब-प्रोसेस के आउटपुट फ़ाइल में लिखना शुरू करने के बाद, उस सब-प्रोसेस को बंद नहीं कर पाता. Make का मौजूदा वर्शन काम नहीं करेगा. हालांकि, Make का अगला वर्शन, काट-छांट की गई आउटपुट फ़ाइल को मान्य मान लेगा, क्योंकि यह अपने इनपुट से नई है. साथ ही, इसे फिर से नहीं बनाया जाएगा. इसी तरह, अगर 'बनाएं' प्रोसेस खत्म हो जाती है, तो ऐसी ही स्थिति पैदा हो सकती है.
Bazel, इन और अन्य अनुमान से बचता है. Bazel, पहले किए गए सभी काम का डेटाबेस बनाए रखता है. यह किसी बिल्ड चरण को सिर्फ़ तब छोड़ेगा, जब उसे पता चलेगा कि उस बिल्ड चरण के इनपुट फ़ाइलों (और उनके टाइमस्टैंप) का सेट और उस बिल्ड चरण के कंपाइलेशन कमांड, डेटाबेस में मौजूद किसी एक से पूरी तरह मैच करते हैं. साथ ही, डेटाबेस एंट्री के आउटपुट फ़ाइलों (और उनके टाइमस्टैंप) का सेट, डिस्क पर मौजूद फ़ाइलों के टाइमस्टैंप से पूरी तरह मैच करता है. इनपुट फ़ाइलों या आउटपुट फ़ाइलों में या कमांड में किए जाने वाले किसी भी बदलाव की वजह से, बिल्ड चरण फिर से लागू होगा.
सही इंक्रीमेंटल बिल्ड का इस्तेमाल करने से, उपयोगकर्ताओं को ये फ़ायदे मिलते हैं: भ्रम की वजह से कम समय बर्बाद होता है. (इसके अलावा, make
clean
का इस्तेमाल करने पर, रीबिल्ड होने में लगने वाला समय भी कम हो जाता है. भले ही, रीबिल्ड करना ज़रूरी हो या पहले से तय किया गया हो.)
एक जैसी सुविधाएं और इंंक्रीमेंटल बिल्ड बनाना
आम तौर पर, हम किसी बिल्ड की स्थिति को एक जैसा तब तय करते हैं, जब उम्मीद के मुताबिक सभी आउटपुट फ़ाइलें मौजूद हों और उनका कॉन्टेंट सही हो. यह कॉन्टेंट, उन्हें बनाने के लिए ज़रूरी चरणों या नियमों के मुताबिक होना चाहिए. किसी सोर्स फ़ाइल में बदलाव करने पर, बिल्ड की स्थिति असमान हो जाती है. यह स्थिति तब तक बनी रहती है, जब तक कि बिल्ड टूल को फिर से चलाकर बिल्ड पूरा नहीं हो जाता. हम इस स्थिति को असमानता मानते हैं, क्योंकि यह सिर्फ़ कुछ समय के लिए होती है और बिल्ड टूल चलाकर पहले की तुलना में एक जैसे नतीजे बनाए जा सकते हैं.
एक और तरह की गड़बड़ी भी होती है, जो नुकसान पहुंचा सकती है: लगातार एक जैसी गड़बड़ी. अगर बिल्ड, एक जैसी स्थिति में नहीं रहता है, तो बिल्ड टूल को बार-बार इस्तेमाल करने से भी बिल्ड एक जैसा नहीं रहता: बिल्ड "स्टक" हो जाता है और आउटपुट गलत रहते हैं. स्थिर और अलग-अलग स्थितियां, Make (और अन्य बिल्ड टूल) के उपयोगकर्ताओं को make clean
टाइप करने की मुख्य वजह हैं.
यह पता लगाना कि बिल्ड टूल इस तरह से काम नहीं कर रहा है और फिर उससे ठीक होना, समय लेने वाला और बहुत परेशान करने वाला हो सकता है.
कॉन्सेप्ट के हिसाब से, एक जैसा बिल्ड पाने का सबसे आसान तरीका यह है कि पिछले सभी बिल्ड आउटपुट को हटाकर, फिर से शुरू करें: हर बिल्ड को क्लीन बिल्ड बनाएं. यह तरीका, शायद रिलीज़ इंजीनियर के अलावा, किसी और के लिए काम का नहीं है. ऐसा इसलिए है, क्योंकि इसमें काफ़ी समय लगता है. इसलिए, यह ज़रूरी है कि बिल्ड टूल, एक जैसी परफ़ॉर्मेंस बनाए रखते हुए, इंक्रीमेंटल बिल्ड कर सके.
इंक्रीमेंटल डिपेंडेंसी का सही विश्लेषण करना मुश्किल है. जैसा कि ऊपर बताया गया है, कई अन्य बिल्ड टूल, इंक्रीमेंटल बिल्ड के दौरान स्थिर और गलत स्टेटस से बचने के लिए खराब तरीके से काम करते हैं. इसके उलट, Bazel इस बात की गारंटी देता है: बगैर किसी बदलाव के, बाइल्ड टूल को इस्तेमाल करने के बाद, बाइल्ड एक जैसा रहेगा. (अगर किसी बिल्ड के दौरान सोर्स फ़ाइलों में बदलाव किया जाता है, तो Bazel इस बात की कोई गारंटी नहीं देता कि मौजूदा बिल्ड का नतीजा एक जैसा होगा. हालांकि, इससे यह गारंटी मिलती है कि अगले बिल्ड के नतीजों से, एक जैसी परफ़ॉर्मेंस वापस आ जाएगी.)
सभी गारंटी की तरह ही, इसमें भी कुछ शर्तें होती हैं: Bazel के साथ, स्टेबल और गैर-स्टेबल स्थिति में जाने के कुछ तरीके हैं. हम इस बात की गारंटी नहीं देते कि हम उन समस्याओं की जांच करेंगे जो जान-बूझकर, इंक्रीमेंटल डिपेंडेंसी विश्लेषण में गड़बड़ियां ढूंढने की कोशिश करने से होती हैं. हालांकि, हम बिल्ड टूल के सामान्य या "उचित" इस्तेमाल से होने वाली सभी समस्याओं की जांच करेंगे और उन्हें ठीक करने की पूरी कोशिश करेंगे.
अगर आपको कभी Bazel में स्टेबल स्टेटस में कोई गड़बड़ी दिखती है, तो कृपया गड़बड़ी की शिकायत करें.
सैंडबॉक्स में चलाने की सुविधा
बेज़ल, सैंडबॉक्स का इस्तेमाल करके यह गारंटी देते हैं कि कार्रवाइयां सही तरीके से और सही तरीके से की जाएं. Baज़ल, सैंडबॉक्स में spawns (कम शब्दों में जानकारी देने वाली: कार्रवाइयां) चलाता है. इसमें सिर्फ़ उन फ़ाइलों का कम सेट होता है जिनकी ज़रूरत टूल को अपना काम करने के लिए होती है. फ़िलहाल, सैंडबॉक्स, Linux 3.12 या इसके बाद के वर्शन पर काम करता है. हालांकि, इसमें CONFIG_USER_NS
विकल्प चालू है. यह macOS 10.11 या इसके बाद के वर्शन पर भी काम करती है.
अगर आपका सिस्टम सैंडबॉक्सिंग की सुविधा के साथ काम नहीं करता है, तो Bazel आपको चेतावनी देगा. इससे आपको यह पता चलेगा कि बिल्ड के पूरी तरह से सुरक्षित होने की कोई गारंटी नहीं है और होस्ट सिस्टम पर इनका असर पड़ सकता है. इस चेतावनी को बंद करने के लिए, Bazel को --ignore_unsupported_sandboxing
फ़्लैग पास किया जा सकता है.
Google Kubernetes Engine क्लस्टर नोड या Debian जैसे कुछ प्लैटफ़ॉर्म पर, उपयोगकर्ता नेमस्पेस डिफ़ॉल्ट रूप से बंद रहते हैं. ऐसा सुरक्षा से जुड़ी चिंताओं की वजह से किया जाता है. इसकी जांच /proc/sys/kernel/unprivileged_userns_clone
फ़ाइल को देखकर की जा सकती है: अगर यह मौजूद है और इसमें 0 है, तो उपयोगकर्ता नेमस्पेस को sudo sysctl kernel.unprivileged_userns_clone=1
की मदद से चालू किया जा सकता है.
कुछ मामलों में, सिस्टम सेटअप की वजह से Bazel सैंडबॉक्स, नियमों को लागू नहीं कर पाता. आम तौर पर, इस समस्या का लक्षण तब दिखता है, जब हमें namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory
जैसा मैसेज मिलता है.
ऐसे में, --strategy=Genrule=standalone
वाले जनरेटिव नियमों और --spawn_strategy=standalone
वाले अन्य नियमों के लिए, सैंडबॉक्स को बंद करने की कोशिश करें. कृपया हमारे समस्या ट्रैकर पर भी गड़बड़ी की शिकायत करें. साथ ही, यह भी बताएं कि आपने कौनसा Linux डिस्ट्रिब्यूशन इस्तेमाल किया है, ताकि हम इसकी जांच कर सकें और अगली रिलीज़ में इसे ठीक कर सकें.
बिल्ड के चरण
Bazel में, बिल्ड तीन अलग-अलग चरणों में होता है. उपयोगकर्ता के तौर पर, इनके बीच के अंतर को समझने से, बिल्ड को कंट्रोल करने वाले विकल्पों के बारे में अहम जानकारी मिलती है (नीचे देखें).
लोडिंग का चरण
पहला चरण लोड करना है. इस दौरान, शुरुआती टारगेट और उनकी डिपेंडेंसी के ट्रांज़िशन क्लोज़र के लिए, सभी ज़रूरी BUILD फ़ाइलें लोड की जाती हैं, पार्स की जाती हैं, उनका आकलन किया जाता है, और उन्हें कैश मेमोरी में सेव किया जाता है.
Bazel सर्वर के शुरू होने के बाद, पहले बिल्ड के लिए लोडिंग चरण में आम तौर पर कई सेकंड लगते हैं. ऐसा इसलिए होता है, क्योंकि फ़ाइल सिस्टम से कई BUILD फ़ाइलें लोड की जाती हैं. इसके बाद के बिल्ड में, खास तौर पर अगर कोई BUILD फ़ाइल नहीं बदली है, तो लोडिंग बहुत तेज़ी से होती है.
इस चरण के दौरान रिपोर्ट की गई गड़बड़ियों में ये शामिल हैं: पैकेज नहीं मिला, टारगेट नहीं मिला, बिल्ड फ़ाइल में लेक्सी और व्याकरण से जुड़ी गड़बड़ियां, और आकलन से जुड़ी गड़बड़ियां.
विश्लेषण का फ़ेज़
दूसरा चरण, विश्लेषण है. इसमें हर बिल्ड नियम का सेमेटिक विश्लेषण और पुष्टि की जाती है. साथ ही, बिल्ड डिपेंडेंसी ग्राफ़ बनाया जाता है और यह तय किया जाता है कि बिल्ड के हर चरण में क्या काम करना है.
लोड होने की तरह ही, पूरी तरह से विश्लेषण करने में भी कुछ सेकंड लगते हैं. हालांकि, Bazel एक बिल्ड से अगले बिल्ड तक डिपेंडेंसी ग्राफ़ को कैश मेमोरी में सेव करता है और सिर्फ़ ज़रूरी चीज़ों का फिर से विश्लेषण करता है. इससे, अगर पिछले बिल्ड के बाद पैकेज में कोई बदलाव नहीं हुआ है, तो इंक्रीमेंटल बिल्ड बहुत तेज़ी से हो सकते हैं.
इस चरण में रिपोर्ट की गई गड़बड़ियों में ये शामिल हैं: डिपेंडेंसी गलत है, नियम के लिए अमान्य इनपुट, और नियम से जुड़ी गड़बड़ी के सभी मैसेज.
लोड होने और विश्लेषण करने की प्रोसेस तेज़ी से होती है, क्योंकि Bazel इस चरण में फ़ाइल के ग़ैर-ज़रूरी I/O से बचता है. साथ ही, यह सिर्फ़ BUILD फ़ाइलों को पढ़ता है, ताकि यह तय किया जा सके कि क्या करना है. यह डिज़ाइन के हिसाब से है. इससे Bazel, विश्लेषण टूल के लिए एक अच्छा फ़ाउंडेशन बन जाता है. जैसे, Bazel का क्वेरी कमांड, जो लोड करने के फ़ेज़ के ऊपर लागू किया जाता है.
लागू करने का फ़ेज़
बिल्ड का तीसरा और आखिरी चरण, एक्सीक्यूशन है. इस चरण से यह पक्का होता है कि बिल्ड के हर चरण के आउटपुट, उसके इनपुट से मेल खाते हों. साथ ही, ज़रूरत के मुताबिक कंपाइलेशन/लिंक करने/वगैरह. इस चरण में, बिल्ड का ज़्यादातर समय बीतता है. बड़े बिल्ड के लिए, इसमें कुछ सेकंड से लेकर एक घंटे से ज़्यादा समय लग सकता है. इस चरण के दौरान, सोर्स फ़ाइलें मौजूद न होना, किसी बिल्ड ऐक्शन से चलाए गए टूल में गड़बड़ियां होना या किसी टूल से आउटपुट का उम्मीद के मुताबिक सेट न बनना जैसी गड़बड़ियां रिपोर्ट की जाती हैं.