मैं एक makefile.am डीबग करने का प्रयास कर रहा हूं जो कभी-कभी निर्माण में विफलता का कारण बनता है। इस फ़ाइल में, स्रोत स्वतः उत्पन्न .c फ़ाइलें हैं और शीर्षलेख स्वतः उत्पन्न .h फ़ाइलें हैं।
..._SOURCES = @buildDirectory@/x.c
@buildDirectory@/y.c
@buildDirectory@/z.c
..._HEADERS = @buildDirectory@/x.h
@buildDirectory@/y.h
@buildDirectory@/z.h
विफलता इस तरह दिखती है
<failedproto>.proto: "symbol1" is not defined.
<failedproto>.proto: "symbol2" is not defined.
<failedproto>.proto: "symbol3" is not defined.
...
<failedproto>.proto: warning: Import <failedproto>.proto but not used.
make: *** [<failedproto>.c] Error 1
make: *** Waiting for unfinished jobs....
ये सभी प्रतीक संबंधित .h में दिखाई देते हैं। इससे मुझे लगता है कि .c .h से पहले उत्पन्न हो रहा है, और यह सिर्फ एक सीधी दौड़ है। मैंने ..._SOURCES और _HEADERS दोनों को BUILT_SOURCES में जोड़ा है, लेकिन मुझे अभी भी विफलता दिखाई दे रही है। तो मेरी अगली प्रवृत्ति .c के लिए .h पर निर्भरता बनाना है। मैं यह कैसे कर सकता हूं, क्योंकि वे दोनों स्वतः उत्पन्न होते हैं? साथ ही, किसी भी वैकल्पिक समाधान का भी स्वागत किया जाएगा।
उम्मीद है कि मेरा स्वरूपण भ्रमित नहीं कर रहा है।
कुछ और विवरण के साथ संपादित करें:
इन फ़ाइलों को प्रोटो-सी कंपाइलर द्वारा स्वतः उत्पन्न किया जा रहा है: https://github.com/protobuf -सी/प्रोटोबफ-सी प्रोटो-सी इन .proto फाइलों को लेता है और .pb-c.c और .pb-c.h फाइलें बनाता है, जिससे मुझे लगता है कि ये दोनों निर्भर नहीं हैं। कुछ इन हाउस कोड भी चलाया जाता है, जो अन्य .proto फ़ाइलें उत्पन्न करता है, मैं उन्हें nameX.proto और nameY.proto कहूंगा, जो बदले में nameX.pb-cc/nameX.pb-ch और nameY.pb-cc/nameY उत्पन्न करते हैं। .pb-ch Makefile.am का अधिक सटीक उदाहरण इस प्रकार है:
..._SOURCES = @buildDirectory@/name.pb-c.c
@buildDirectory@/nameX.pb-c.c
@buildDirectory@/nameY.pb-c.c
..._HEADERS = @buildDirectory@/name.pb-c.h
@buildDirectory@/nameX.pb-c.h
@buildDirectory@/nameY.pb-c.h
मैं इन निर्भरताओं को ट्रैक करने की कोशिश कर रहा हूं, और मैं कोशिश करूंगा और वर्णन करूंगा कि मैं किस निष्कर्ष पर पहुंचा हूं। nameX.pb-c.c में इसके संगत शीर्षलेख शामिल हैं nameX.pb-c.h. उस हेडर में nameY.pb-c.h शामिल है, जिससे मुझे लगता है कि nameX.proto को nameX.pb-c.c/nameX.pb-c.h में संकलित किया जा रहा है इससे पहले nameY.proto को संकलित किया जा सकता है। चूंकि nameX.pb-c.h और nameY.pb-c.h के बीच एक शामिल संबंध है, इसलिए बिल्ड विफल हो जाता है क्योंकि nameX.pb-c.h को nameY.pb-c.h की आवश्यकता होती है। यह मुझे दो नियमों की ओर ले जाता है जिन पर मुझे शुरू से ही संदेह रहा है। इन नियमों को इस प्रकार सामान्यीकृत किया गया है:
$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto $(SRC_DIRECTORY)/nameY.proto
command $(OUT_DIRECTORY) $(FLAGS) $<
$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto
command $(OUT_DIRECTORY) $(FLAGS) $<
क्या यह कोई मुद्दा हो सकता है? दूसरे नियम को चलने से क्या रोक रहा है यदि उसे वास्तव में पहले नियम की आवश्यकता है?
मामलों को बदतर बनाने के लिए, कई .proto फ़ाइलें इंटरमीडिएट फ़ाइलें हैं (वे उत्पन्न होती हैं और फिर पूरे निर्माण में छोड़ दी जाती हैं) इसलिए मैं उन्हें यह देखने के लिए नहीं देख सकता कि वे कैसा दिखते हैं।
1 उत्तर
अपने पूरे मेकफ़ाइल में इस तरह @...@
प्रतिस्थापन का उपयोग करना बहुत ही असामान्य है। आम तौर पर आप एक बार मेक वेरिएबल के लिए प्रतिस्थापन असाइन करेंगे, फिर इसके बजाय वेरिएबल का उपयोग करें ("पढ़ने के लिए अच्छा" होने के अलावा, यह किसी को make
कमांड लाइन पर इस मान को ओवरराइड करने की अनुमति देता है यदि वे चाहते हैं) :
BUILDDIR = @buildDirectory@
..._SOURCES = $(BUILDDIR)/x.c
$(BUILDDIR)/y.c
$(BUILDDIR)/z.c
..._HEADERS = $(BUILDDIR)/x.h
$(BUILDDIR)/y.h
$(BUILDDIR)/z.h
साथ ही, मुझे ऐसा लगता है कि मानक ऑटोमेक चर हैं जो पहले से ही इस मान को कवर कर सकते हैं; यदि ऐसा है तो नए का आविष्कार करने की तुलना में मानक का उपयोग करना बेहतर है ... लेकिन स्पष्ट रूप से यह जानने का कोई तरीका नहीं है कि आपके पर्यावरण के बारे में और जानने के बिना।
वैसे भी, आपके प्रश्न के लिए हमें इस ऑटोजेनरेशन ऑपरेशन के बारे में और जानने की जरूरत है। स्वत: जनरेट करने के लिए आपके नियम अब कैसे दिखते हैं? क्या वास्तव में ऐसा है कि .c फ़ाइल का निर्माण तब तक नहीं किया जा सकता जब तक कि .h फ़ाइल उत्पन्न नहीं हो जाती? यह असामान्य है।
यदि आप आउटपुट फ़ाइल, इनपुट फ़ाइलें और आवश्यक कमांड सूचीबद्ध करते हैं तो एक सही नियम लिखना बहुत आसान है।
संबंधित सवाल
नए सवाल
makefile
एक मेकफाइल बिल्ड कंट्रोल लैंग्वेज / टूल मेक के लिए एक इनपुट फाइल है। यह लक्ष्य को अद्यतन करने के लिए (a.k.a व्यंजनों) को करने के लिए संबद्ध आदेशों के साथ लक्ष्य और निर्भरता को निर्दिष्ट करता है।
$(OUT_DIRECTORY)/%nameX.proto
से मेल खाता हो, तो आप ऐसा कर सकते हैं यदि ये पूर्वापेक्षाएँ मौजूद हैं या बनाई जा सकती हैं"। लेकिन, यदि आप दो लक्ष्य बनाना चाहते हैं जो दोनों उस पैटर्न से मेल खाते हैं, तो मेक उस नियम को दो बार चलाएगा ... जो संभवतः एक ही आउटपुट उत्पन्न करेगा। आप यहां पैटर्न नियम का उपयोग क्यों करते हैं?make
निर्भरताओं के साथ नहीं है, बल्कि प्रोटो-सी में आपके इनपुट के साथ है।