निर्भरताएं

संग्रह की मदद से व्यवस्थित रहें अपनी प्राथमिकताओं के आधार पर, कॉन्टेंट को सेव करें और कैटगरी में बांटें.
किसी समस्या की शिकायत करें स्रोत देखें

अगर A को बिल्ड या एक्ज़ीक्यूशन के समय A की ज़रूरत होती है, तो टारगेट A, टारगेट B पर निर्भर करता है. यह इस पर निर्भर करता है कि संबंध, किस तरह टारगेट के ऊपर निर्देश वाले असाइकलिक ग्राफ़ (डीएजी) को बढ़ावा देता है. इसे डिपेंडेंसी ग्राफ़ कहा जाता है.

टारगेट की डायरेक्ट डिपेंडेंसी, वे दूसरे टारगेट हैं जिन पर डिपेंडेंसी ग्राफ़ में लंबाई 1 का पाथ देखा जा सकता है. टारगेट की ट्रांज़िशनल डिपेंडेंसी वे टारगेट होती हैं जिन पर ग्राफ़ के ज़रिए किसी भी लंबाई वाले पाथ से तय किया जाता है.

असल में, बिल्ड के मामले में, दो डिपेंडेंसी ग्राफ़ होते हैं. असल डिपेंडेंसी का ग्राफ़ और एलान की गई डिपेंडेंसी का ग्राफ़. ज़्यादातर मामलों में, दोनों ग्राफ़ एक-दूसरे से मिलते-जुलते होते हैं और इनमें अंतर करने की ज़रूरत नहीं पड़ती. हालांकि, इनके बारे में नीचे चर्चा की जा सकती है.

असल और तय डिपेंडेंसी

अगर X सही तरीके से बनाया जा सके, तो X, टारगेट Y पर असल में निर्भर होता है. बनाए गए टैग का मतलब हो सकता है कि किसी बिल्ड के दौरान जनरेट होने वाले, प्रोसेस किए गए, इकट्ठा किए गए, संग्रहित किए गए, कंप्रेस किए गए या इस्तेमाल किए गए या किसी भी दूसरी तरह के कामों को कर सकते हैं.

अगर टारगेट X के लिए, Y के टारगेट में डिपेंडेंसी तय की गई है, तो X के पैकेज में, X से लेकर Y तक डिपेंडेंसी होती है.

सही बिल्ड के लिए, असल डिपेंडेंसी का ग्राफ़ A, डिपेंडेंसी के ग्राफ़ का सबग्राफ़ होना चाहिए. इसका मतलब है कि सीधे कनेक्ट किए गए नोड x --> y के हर जोड़े को A में सीधे तौर पर D में भी जोड़ा जाना चाहिए. कहा जा सकता है कि D, A का बहुत ज़्यादा अनुमान है.

BUILD फ़ाइल लेखकों को सीधे तौर पर, बिल्ड सिस्टम पर लागू होने वाले हर नियम की सभी डिपेंडेंसी के बारे में साफ़ तौर पर बताना चाहिए.

इस सिद्धांत का पालन न कर पाने की वजह यह है: तय की गई कार्रवाई असफल हो सकती है, लेकिन बिल्ड काम नहीं कर पाएगा, लेकिन कुछ कार्रवाइयों पर निर्भर हो सकता है. इसके अलावा, यह उन ट्रांज़िटिव इंडिपेंडेंसी पर भी निर्भर हो सकता है जिसका लक्ष्य टारगेट करता है. बेज़ेल, निर्भरता और रिपोर्ट में गड़बड़ियों की जांच करता है, लेकिन सभी मामलों में इस जांच की प्रोसेस पूरी करना संभव नहीं है.

आपको उन सभी चीज़ों को सूची में डालने की कोशिश करने की ज़रूरत नहीं है (जो नहीं होनी चाहिए) भले ही उन्हें एक्ज़ीक्यूशन के समय ज़रूरी A की ज़रूरत हो.

X टारगेट बनाने के दौरान, बिल्ड टूल Xपर निर्भरता की पूरी तरह से बंद होने की जांच करता है, ताकि यह पक्का किया जा सके कि आखिरी टारगेट में कोई बदलाव हो रहा है या नहीं. साथ ही, ज़रूरत के मुताबिक इंटरमीडिएट बनाए जा सकते हैं.

डिपेंडेंसी किस तरह की होती है, यह आम तौर पर होने वाली गलतियों के बारे में है. कभी-कभी, एक फ़ाइल में मौजूद कोड, इनडायरेक्ट डिपेंडेंसी से मिले कोड का इस्तेमाल कर सकता है — यह ट्रांज़िट समय का होता है, लेकिन इसका एलान किए गए डिपेंडेंसी ग्राफ़ में सीधे तौर पर नहीं होता. इनडायरेक्ट डिपेंडेंसी BUILD फ़ाइल में नहीं दिखती हैं. यह नियम सीधे तौर पर सेवा देने वाली कंपनी पर निर्भर नहीं करता है, इसलिए बदलावों को ट्रैक करने का कोई तरीका नहीं है, जैसा कि नीचे दी गई उदाहरण की टाइमलाइन में दिखाया गया है:

1. बताई गई डिपेंडेंसी असल डिपेंडेंसी से मेल खाती हैं

सबसे पहले, सब कुछ काम करता है. पैकेज a के कोड, b पैकेज में दिए गए कोड का इस्तेमाल करते हैं. पैकेज b में कोड c में कोड का उपयोग करता है और इस तरह a ट्रांज़िटल रूप से c पर निर्भर करता है.

a/BUILD b/BUILD
rule(
    name = "a",
    srcs = "a.in",
    deps = "//b:b",
)
      
rule(
    name = "b",
    srcs = "b.in",
    deps = "//c:c",
)
      
a / a.in b / b.in
import b;
b.foo();
    
import c;
function foo() {
  c.bar();
}
      
a, b, और c को कनेक्ट करने वाले ऐरो के साथ एलान किया गया डिपेंडेंसी ग्राफ़
एलान किया गया डिपेंडेंसी ग्राफ़
असल डिपेंडेंसी ग्राफ़, जो तय किए गए डिपेंडेंसी ग्राफ़ से मेल खाता है. यह ग्राफ़, a, b, और c को कनेक्ट करता है
असल डिपेंडेंसी ग्राफ़

तय की गई डिपेंडेंसी, असल डिपेंडेंसी से ज़्यादा सटीक होती हैं. सब ठीक है.

2. तय नहीं की गई डिपेंडेंसी जोड़ना

जब कोई व्यक्ति a में ऐसा कोड जोड़ता है जो c पर डायरेक्ट असल डिपेंडेंसी बनाता है, लेकिन बिल्ड फ़ाइल में इसका एलान करना भूल जाता है, तो इंतज़ार का खतरा होता है a/BUILD.

a / a.in  
        import b;
        import c;
        b.foo();
        c.garply();
      
 
a, b, और c को कनेक्ट करने वाले ऐरो के साथ एलान किया गया डिपेंडेंसी ग्राफ़
एलान किया गया डिपेंडेंसी ग्राफ़
a, b, और c को जोड़ने वाले तीर के निशान पर आधारित असल डिपेंडेंसी ग्राफ़. एक तीर अब A से C तक भी कनेक्ट करता है. यह एलान किए गए डिपेंडेंसी ग्राफ़ से मेल नहीं खाता
असल डिपेंडेंसी ग्राफ़

तय की गई डिपेंडेंसी अब असल डिपेंडेंसी से ज़्यादा असरदार नहीं हैं. यह ठीक लग सकता है, क्योंकि दो ग्राफ़ के अस्थायी ट्रांज़िट एक समान होते हैं, लेकिन मास्क एक समस्या होती है: a की वास्तविक, लेकिन अघोषित निर्भरता c पर है.

3. एलान किए गए और असल डिपेंडेंसी ग्राफ़ के बीच का अंतर

खतरा होने का पता तब चलता है, जब कोई व्यक्ति b को मना कर देता है, ताकि अब वह c पर निर्भर न रहे. यह गलती से a को अपनी गलती से टूटने पर तोड़ देता है.

  b/BUILD
 
rule(
    name = "b",
    srcs = "b.in",
    deps = "//d:d",
)
      
  b / b.in
 
      import d;
      function foo() {
        d.baz();
      }
      
a और b को कनेक्ट करने वाले ऐरो के साथ, एलान किया गया डिपेंडेंसी ग्राफ़.
                  b अब c से कनेक्ट नहीं हो रहा है, जो c से कनेक्शन टूट जाता है
एलान किया गया डिपेंडेंसी ग्राफ़
असल डिपेंडेंसी ग्राफ़, जो b और c को कनेक्ट करता है. हालांकि, b अब c से कनेक्ट नहीं है
असल डिपेंडेंसी ग्राफ़

तय डिपेंडेंसी ग्राफ़ अब असली डिपेंडेंसी से कम है. भले ही, यह ट्रांज़िट समय में बंद हो; लेकिन हो सकता है कि बिल्ड काम न करे.

यह पक्का करने के लिए कि चरण 2 में a से c पर असल डिपेंडेंसी को BUILD फ़ाइल में सही तरीके से बताया गया था, हो सकता है कि समस्या को हटा दिया गया हो.

डिपेंडेंसी के टाइप

ज़्यादातर बिल्ड नियमों में तीन तरह की विशेषताएं होती हैं, जो उनके बारे में अलग-अलग तरह से बताती हैं: srcs, deps, और data. इनके बारे में नीचे बताया गया है. ज़्यादा जानकारी के लिए, सभी नियमों में लागू होने वाली विशेषताएं देखें.

कई नियमों में, खास तौर पर नियम के हिसाब से दूसरी विशेषताएं भी होती हैं, जैसे कि compiler या resources. इन सुविधाओं के बारे में बिल्ड एन्साइक्लोपीडिया में बताया गया है.

srcs डिपेंडेंसी

सीधे नियम के ज़रिए इस्तेमाल की गई फ़ाइलें या आउटपुट सोर्स वाली फ़ाइलें.

deps डिपेंडेंसी

हेडर फ़ाइलें, सिम्बॉल, लाइब्रेरी, डेटा वगैरह उपलब्ध कराने वाले अलग-अलग कंपाइल किए गए मॉड्यूल की ओर इशारा करने वाला नियम.

data डिपेंडेंसी

बिल्ड टारगेट को ठीक से चलाने के लिए, कुछ डेटा फ़ाइलों की ज़रूरत पड़ सकती है. ये डेटा फ़ाइलें सोर्स कोड नहीं हैं: उनका असर टारगेट के बनाने के तरीके पर नहीं पड़ता. उदाहरण के लिए, इकाई जांच किसी फ़ंक्शन के आउटपुट की तुलना फ़ाइल की सामग्री से कर सकती है. इकाई जांच बनाते समय, आपको फ़ाइल की ज़रूरत नहीं होती है. हालांकि, जांच करते समय आपको इसकी ज़रूरत होती है. ये बातें उन टूल पर भी लागू होती हैं जो एक्ज़ीक्यूशन के दौरान लॉन्च किए जाते हैं.

बिल्ड सिस्टम एक अलग डायरेक्ट्री में जांच करता है, जहां सिर्फ़ data के तौर पर सूची में दी गई फ़ाइलें उपलब्ध होती हैं. इसलिए, अगर बाइनरी/लाइब्रेरी/टेस्ट के लिए कुछ फ़ाइलों की ज़रूरत होती है, तो data में उनके बारे में बताएं. उदाहरण के लिए:

# I need a config file from a directory named env:
java_binary(
    name = "setenv",
    ...
    data = [":env/default_env.txt"],
)

# I need test data from another directory
sh_test(
    name = "regtest",
    srcs = ["regtest.sh"],
    data = [
        "//data:file1.txt",
        "//data:file2.txt",
        ...
    ],
)

ये फ़ाइलें, रिलेटिव पाथ path/to/data/file का इस्तेमाल करके उपलब्ध हैं. जांच में, आप टेस्ट की सोर्स डायरेक्ट्री और फ़ाइल फ़ोल्डर से जुड़े पाथ के पाथ में शामिल होकर, ये फ़ाइलें देख सकते हैं. उदाहरण के लिए,${TEST_SRCDIR}/workspace/path/to/data/file.

डायरेक्ट्री को रेफ़र करने के लिए लेबल का इस्तेमाल करना

जब आप हमारी BUILD फ़ाइलें देखते हैं, तो हो सकता है कि आप देखें कि कुछ data लेबल निर्देशिकाओं के बारे में बताते हैं. ये लेबल, /. या / पर खत्म होते हैं. जैसे कि ये उदाहरण. इनका इस्तेमाल नहीं किया जाना चाहिए:

इसका सुझाव नहीं दिया जाता हैdata = ["//data/regression:unittest/."]

इसका सुझाव नहीं दिया जाता हैdata = ["testdata/."]

इसका सुझाव नहीं दिया जाता हैdata = ["testdata/"]

यह आसान लगता है, खास तौर पर जांच के लिए क्योंकि यह टेस्ट को डायरेक्ट्री में मौजूद सभी डेटा फ़ाइलों का इस्तेमाल करने देता है.

हालांकि, ऐसा करने से बचें. इंक्रीमेंटल (बढ़ने वाले) तरीके को फिर से बनाने और टेस्ट के बाद फिर से लागू करने के लिए, बिल्ड सिस्टम को उन फ़ाइलों के पूरे सेट की जानकारी होनी चाहिए जो बिल्ड और टेस्ट के लिए हैं. जब आप कोई डायरेक्ट्री बताते हैं, तो बिल्ड सिस्टम सिर्फ़ तब फिर से बिल्ड करता है जब डायरेक्ट्री अपने-आप बदल जाती है (फ़ाइलों को जोड़ने या मिटाने की वजह से), लेकिन वे अलग-अलग फ़ाइलों में किए गए बदलावों का पता नहीं लगा पातीं, क्योंकि इन बदलावों से एन्क्लोज़िंग डायरेक्ट्री पर असर नहीं पड़ता. डायरेक्ट्री को बिल्ड सिस्टम में इनपुट के तौर पर बताने के बजाय, आपको उनमें शामिल फ़ाइलों के सेट की साफ़ तौर पर या glob() फ़ंक्शन का इस्तेमाल करके, उनके बारे में जानकारी देनी चाहिए. glob() का इस्तेमाल फिर से करने के लिए, ** का इस्तेमाल करें.

इसका सुझाव दिया जाता हैdata = glob(["testdata/**"])

माफ़ करें, कुछ स्थितियों में डायरेक्ट्री के लेबल का इस्तेमाल किया जाना ज़रूरी है. उदाहरण के लिए, अगर testdata डायरेक्ट्री में ऐसी फ़ाइलें हैं जिनके नाम लेबल सिंटैक्स के मुताबिक नहीं हैं, तो फ़ाइलों के बारे में साफ़ तौर पर जानकारी दी गई हो या glob() फ़ंक्शन का इस्तेमाल किया गया हो, तो अमान्य लेबल गड़बड़ी मिलती है. इस मामले में, आपको डायरेक्ट्री लेबल का इस्तेमाल करना चाहिए. हालांकि, ऊपर बताई गई गलत रीबिल्डिंग से जुड़े जोखिम से सावधान रहें.

अगर आप डायरेक्ट्री लेबल का इस्तेमाल करना चाहें, तो ध्यान रखें कि आप रिलेटिव ../ पाथ वाले पैरंट पैकेज का रेफ़रंस न दे सकें; इसके बजाय, //data/regression:unittest/. जैसे ऐब्सलूट पाथ का इस्तेमाल करें.

टेस्ट जैसा कोई भी बाहरी नियम जिसे कई फ़ाइलों का इस्तेमाल करना है, साफ़ तौर पर बताना चाहिए कि उन पर निर्भर है. आप BUILD फ़ाइल में फ़ाइलों को एक साथ ग्रुप करने के लिए, filegroup() इस्तेमाल कर सकते हैं:

filegroup(
        name = 'my_data',
        srcs = glob(['my_unittest_data/*'])
)

इसके बाद, अपने टेस्ट में डेटा डिपेंडेंसी के तौर पर my_data लेबल का रेफ़रंस दिया जा सकता है.

बिल्ड फ़ाइलें किसको दिखे