इस पेज पर, बिल्ड सिस्टम के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि बिल्ड सिस्टम क्या होते हैं, वे कैसे काम करते हैं, और आपको बिल्ड सिस्टम का इस्तेमाल क्यों करना चाहिए. इसके अलावा, यह भी बताया गया है कि जब आपका संगठन बढ़ने लगता है, तो कंपाइलर और बिल्ड स्क्रिप्ट, सबसे सही विकल्प क्यों नहीं होते. यह पेज, उन डेवलपर के लिए है जिनके पास बिल्ड सिस्टम का ज़्यादा अनुभव नहीं है.
बिल्ड सिस्टम क्या होता है?
असल में, सभी बिल्ड सिस्टम का एक ही मकसद होता है: वे इंजीनियरों के लिखे सोर्स कोड को, एक्ज़ीक्यूट किए जा सकने वाले बाइनरी में बदल देते हैं. इन्हें मशीनें पढ़ सकती हैं. बिल्ड सिस्टम, सिर्फ़ इंजीनियरों के लिखे कोड के लिए नहीं होते. इनकी मदद से, मशीनें अपने-आप बिल्ड बना सकती हैं. ये बिल्ड, टेस्टिंग या प्रोडक्शन के लिए रिलीज़ किए जा सकते हैं. हज़ारों इंजीनियरों वाले संगठन में, आम तौर पर ज़्यादातर बिल्ड, इंजीनियरों के सीधे तौर पर ट्रिगर करने के बजाय, अपने-आप ट्रिगर होते हैं.
क्या मैं सिर्फ़ कंपाइलर का इस्तेमाल नहीं कर सकता?
हो सकता है कि आपको बिल्ड सिस्टम की ज़रूरत तुरंत न दिखे. ज़्यादातर इंजीनियर, कोडिंग सीखते समय बिल्ड सिस्टम का इस्तेमाल नहीं करते. ज़्यादातर लोग, कमांड लाइन से सीधे तौर पर gcc या javac जैसे टूल का इस्तेमाल करते हैं. इसके अलावा, इंटिग्रेटेड डेवलपमेंट एनवायरमेंट (IDE) में भी इसी तरह के टूल का इस्तेमाल किया जाता है. जब तक सारा सोर्स कोड एक ही डायरेक्ट्री में होता है, तब तक इस तरह का कोई भी कमांड सही तरीके से काम करता है:
javac *.javaइससे Java कंपाइलर को, मौजूदा डायरेक्ट्री में मौजूद हर Java सोर्स फ़ाइल को लेकर, उसे बाइनरी क्लास फ़ाइल में बदलने का निर्देश मिलता है. सबसे आसान मामले में, आपको सिर्फ़ इसकी ज़रूरत होती है.
हालांकि, कोड बढ़ने पर समस्याएं शुरू हो जाती हैं. javac में, इंपोर्ट करने के लिए कोड ढूंढने के लिए, मौजूदा डायरेक्ट्री की सबडायरेक्ट्री में देखने की सुविधा होती है. हालांकि, इसके पास फ़ाइल सिस्टम के दूसरे हिस्सों में सेव किया गया कोड ढूंढने का कोई तरीका नहीं होता. जैसे, कई प्रोजेक्ट के साथ शेयर की गई कोई लाइब्रेरी. इसके अलावा, यह सिर्फ़ Java कोड को बिल्ड कर सकता है. बड़े सिस्टम में, अक्सर अलग-अलग प्रोग्रामिंग भाषाओं में लिखे गए अलग-अलग हिस्से शामिल होते हैं. इन हिस्सों के बीच, निर्भरताओं का जाल होता है. इसका मतलब है कि किसी एक भाषा के लिए कंपाइलर, पूरे सिस्टम को बिल्ड नहीं कर सकता.
जब आपको एक से ज़्यादा भाषाओं या एक से ज़्यादा कंपाइलेशन यूनिट के कोड से काम करना होता है, तो कोड को बिल्ड करना, एक चरण की प्रोसेस नहीं रह जाती. अब आपको यह देखना होगा कि आपका कोड किस पर निर्भर करता है. इसके बाद, उन हिस्सों को सही क्रम में बिल्ड करना होगा. इसके लिए, हर हिस्से के लिए अलग-अलग टूल का इस्तेमाल करना पड़ सकता है. अगर कोई निर्भरता बदलती है, तो आपको इस प्रोसेस को दोहराना होगा, ताकि पुराने बाइनरी पर निर्भर न रहना पड़े. यहां तक कि सामान्य साइज़ के कोडबेस के लिए भी, यह प्रोसेस जल्द ही मुश्किल और गड़बड़ियों वाली हो जाती है.
कंपाइलर को, बाहरी निर्भरताओं को मैनेज करने के तरीके के बारे में भी कोई जानकारी नहीं होती. जैसे, Java में तीसरे पक्ष की JAR फ़ाइलें. बिल्ड सिस्टम के बिना, इसे मैनेज करने के लिए, आपको इंटरनेट से निर्भरता डाउनलोड करनी होगी. इसके बाद, इसे हार्ड ड्राइव पर मौजूद lib फ़ोल्डर में सेव करना होगा. साथ ही, कंपाइलर को उस डायरेक्ट्री से लाइब्रेरी पढ़ने के लिए कॉन्फ़िगर करना होगा. समय के साथ, इन बाहरी निर्भरताओं के अपडेट, वर्शन, और सोर्स को बनाए रखना मुश्किल होता है.
शेल स्क्रिप्ट के बारे में क्या ख़याल है?
मान लें कि आपका हॉबी प्रोजेक्ट इतना आसान है कि उसे सिर्फ़ कंपाइलर का इस्तेमाल करके बिल्ड किया जा सकता है. हालांकि, आपको पहले बताई गई कुछ समस्याएं आने लगती हैं. हो सकता है कि आपको अब भी यह न लगे कि आपको बिल्ड सिस्टम की ज़रूरत है. साथ ही, आपको यह भी लग सकता है कि कुछ आसान शेल स्क्रिप्ट का इस्तेमाल करके, मुश्किल हिस्सों को ऑटोमेट किया जा सकता है. ये स्क्रिप्ट, चीज़ों को सही क्रम में बिल्ड करने का काम करती हैं. इससे कुछ समय के लिए मदद मिलती है. हालांकि, जल्द ही आपको और भी समस्याएं आने लगती हैं:
यह मुश्किल हो जाता है. आपका सिस्टम जितना ज़्यादा जटिल होता जाता है, उतना ही ज़्यादा समय आपको बिल्ड स्क्रिप्ट पर काम करने में लगता है. यह समय, असल कोड पर काम करने में लगने वाले समय के बराबर हो सकता है. शेल स्क्रिप्ट को डीबग करना मुश्किल होता है. ऐसा इसलिए, क्योंकि एक के ऊपर एक, कई हैक लेयर की जाती हैं.
यह धीमा होता है. यह पक्का करने के लिए कि आपने गलती से पुरानी लाइब्रेरी पर निर्भर न हों, आपकी बिल्ड स्क्रिप्ट, हर बार रन होने पर, हर निर्भरता को क्रम से बिल्ड करती है. आपको यह पता लगाने के लिए कुछ लॉजिक जोड़ने के बारे में सोचना होगा कि किन हिस्सों को फिर से बिल्ड करने की ज़रूरत है. हालांकि, यह स्क्रिप्ट के लिए बहुत जटिल और गड़बड़ियों वाला हो सकता है. इसके अलावा, आपको यह तय करना होगा कि हर बार किन हिस्सों को फिर से बिल्ड करने की ज़रूरत है. हालांकि, इससे आप फिर से पहले वाली स्थिति में पहुंच जाएंगे.
अच्छी खबर: अब रिलीज़ करने का समय आ गया है! अब आपको यह पता लगाना होगा कि फ़ाइनल बिल्ड बनाने के लिए, jar कमांड को कौनसे आर्ग्युमेंट पास करने होंगे. साथ ही, यह भी याद रखना होगा कि इसे अपलोड कैसे करना है और सेंट्रल रिपॉज़िटरी में कैसे पुश करना है. इसके अलावा, दस्तावेज़ों के अपडेट को बिल्ड और पुश करना होगा. साथ ही, उपयोगकर्ताओं को सूचना भेजनी होगी. शायद इसके लिए, आपको एक और स्क्रिप्ट की ज़रूरत होगी...
मुसीबत! आपकी हार्ड ड्राइव क्रैश हो गई है. अब आपको अपना पूरा सिस्टम फिर से बनाना होगा. आपने अपने सभी सोर्स फ़ाइलें, वर्शन कंट्रोल में सेव करके रखी हैं. हालांकि, डाउनलोड की गई लाइब्रेरी के बारे में क्या? क्या आपको वे सभी लाइब्रेरी फिर से मिल सकती हैं और क्या यह पक्का किया जा सकता है कि वे उसी वर्शन की हों जिस वर्शन में आपने उन्हें पहली बार डाउनलोड किया था? आपकी स्क्रिप्ट, शायद खास टूल के खास जगहों पर इंस्टॉल होने पर निर्भर करती हैं. क्या आप उसी एनवायरमेंट को वापस ला सकते हैं, ताकि स्क्रिप्ट फिर से काम कर सकें? उन सभी एनवायरमेंट वैरिएबल के बारे में क्या ख़याल है जिन्हें आपने कंपाइलर को सही तरीके से काम कराने के लिए, काफ़ी समय पहले सेट किया था और फिर भूल गए?
समस्याओं के बावजूद, आपका प्रोजेक्ट इतना सफल है कि अब आप ज़्यादा इंजीनियरों को काम पर रख सकते हैं. अब आपको पता चलता है कि पिछली समस्याएं आने के लिए, किसी मुसीबत का होना ज़रूरी नहीं है. जब भी कोई नया डेवलपर आपकी टीम में शामिल होता है, तो आपको वही मुश्किल बूटस्ट्रैपिंग प्रोसेस करनी पड़ती है. आपके सबसे अच्छे प्रयासों के बावजूद, हर व्यक्ति के सिस्टम में अब भी थोड़े-बहुत अंतर होते हैं. अक्सर, जो चीज़ किसी एक व्यक्ति की मशीन पर काम करती है वह दूसरे की मशीन पर काम नहीं करती. हर बार, यह पता लगाने में कुछ घंटे लगते हैं कि अंतर कहां है. इसके लिए, डीबग करने वाले टूल के पाथ या लाइब्रेरी के वर्शन की जांच करनी पड़ती है.
आपने तय किया है कि आपको अपने बिल्ड सिस्टम को ऑटोमेट करना होगा. सैद्धांतिक तौर पर, यह उतना ही आसान है जितना कि नया कंप्यूटर लेना और उसे हर रात cron का इस्तेमाल करके, अपनी बिल्ड स्क्रिप्ट को रन करने के लिए सेट अप करना. आपको अब भी मुश्किल सेट अप प्रोसेस करनी होगी. हालांकि, अब आपको किसी इंसान के दिमाग का फ़ायदा नहीं मिलेगा, जो छोटी-मोटी समस्याओं का पता लगा सकता है और उन्हें हल कर सकता है. अब, हर सुबह ऑफ़िस पहुंचने पर, आपको पता चलता है कि पिछली रात का बिल्ड फ़ेल हो गया, क्योंकि कल किसी डेवलपर ने एक ऐसा बदलाव किया था जो उसके सिस्टम पर काम करता था, लेकिन ऑटोमेटेड बिल्ड सिस्टम पर काम नहीं करता था. हर बार, इसे ठीक करना आसान होता है. हालांकि, यह इतनी बार होता है कि आपको हर दिन इन आसान फ़िक्स को ढूंढने और लागू करने में काफ़ी समय लगता है.
प्रोजेक्ट बढ़ने के साथ-साथ, बिल्ड धीमे होते जाते हैं. एक दिन, बिल्ड पूरा होने का इंतज़ार करते समय, आपने छुट्टी पर गए अपने सहकर्मी के डेस्कटॉप को दुख से देखा. आपको लगा कि काश, बर्बाद हो रही कंप्यूटेशनल पावर का फ़ायदा उठाया जा सकता.
आपको स्केल की एक क्लासिक समस्या हुई है. अगर कोई डेवलपर, ज़्यादा से ज़्यादा एक या दो हफ़्ते के लिए, ज़्यादा से ज़्यादा दो सौ लाइनों के कोड पर काम कर रहा है, तो आपको सिर्फ़ कंपाइलर की ज़रूरत होगी. हो सकता है कि यह, यूनिवर्सिटी से ग्रैजुएट हुए किसी जूनियर डेवलपर का अब तक का पूरा अनुभव हो. स्क्रिप्ट से शायद आपको थोड़ी ज़्यादा मदद मिल सकती है. हालांकि, जब आपको एक से ज़्यादा डेवलपर और उनकी मशीनों के बीच तालमेल बिठाना होता है, तो एक सही बिल्ड स्क्रिप्ट भी काफ़ी नहीं होती. ऐसा इसलिए, क्योंकि उन मशीनों में मौजूद छोटे-मोटे अंतरों को ध्यान में रखना बहुत मुश्किल हो जाता है. इस स्थिति में, यह आसान तरीका काम नहीं करता. अब आपको किसी असली बिल्ड सिस्टम में निवेश करना होगा.