2012-08-07 23 views
11

मुझे पता है कि निम्नलिखित मेकफ़ाइल में प्री-प्रोसेसर स्वचालित रूप से निर्भरता उत्पन्न करेगा (.d फ़ाइलों में) और उन्हें मेकफ़ाइल में शामिल करें (क्योंकि मेरे पाठ्यक्रम नोट्स ऐसा कहते हैं), इसलिए कि उन्हें स्वचालित रूप से बनाए रखने की आवश्यकता नहीं है। -MMD ध्वज इसके लिए ज़िम्मेदार है। मुझे जो नहीं मिलता है वह है: डीडी फाइलें किस बिंदु पर उत्पन्न होती हैं? यहां तक ​​कि कोई भी आदेश नहीं है जहां ${CXXFLAGS} का उपयोग किया जाता है। संभवतः, ${CXX} ${CXXFLAGS} -c x.C -o x.o जैसे कमांड ऑब्जेक्ट फ़ाइलों में से प्रत्येक के लिए स्वचालित रूप से घटाए जाएंगे, लेकिन यदि ये आदेश हैं जो .d फ़ाइलों को उत्पन्न करते हैं, तो क्या हम पहले से ही उस बिंदु को पार नहीं कर पाएंगे जहां xo, yo और zo की निर्भरताएं जानना प्रासंगिक हो सकता है, अगर हम उन्हें केवल उन फ़ाइलों को निष्पादित करके जानते हैं जो इन .o फाइलें उत्पन्न करते हैं? (कहते हैं वहाँ ज फ़ाइलों को makefile यदि अपने स्वयं के या कुछ और पर नियमों अनुमान के लिए छोड़ दिया उपेक्षा होता है।)स्वचालित रूप से निर्भरताओं को उत्पन्न करने के लिए मेकफ़ाइल में -एमएमडी के साथ जी ++ का उपयोग करना

CXX = g++      # compiler 
CXXFLAGS = -g -Wall -MMD  # compiler flags 
OBJECTS = x.o y.o z.o   # object files forming executable 
DEPENDS = ${OBJECTS:.o=.d} # substitutes ".o" with ".d" 
EXEC = a.out     # executable name 

${EXEC} : ${OBJECTS}   # link step 
    ${CXX} ${OBJECTS} -o ${EXEC} 

-include ${DEPENDS}   # copies files x.d, y.d, z.d (if they exist) 

उत्तर

8

मुमकिन है, ${CXX} ${CXXFLAGS} -c x.C -o x.o की तरह आदेश स्वचालित रूप से वस्तु से प्रत्येक के लिए बनाने के द्वारा निष्कर्ष निकाला की जाएगी फ़ाइलें, लेकिन यदि ये आदेश हैं जो .d फ़ाइलों को उत्पन्न करते हैं, तो क्या हम पहले से ही उस बिंदु को पार नहीं कर पाएंगे जहां xo, yo और zo की निर्भरता जानना प्रासंगिक हो सकता है, अगर हम केवल उन आदेशों को निष्पादित करके जानते हैं इन .o फाइलें उत्पन्न करें?

आप यहां सही हैं। मेकफ़ाइल चलाने पर पहली बार निर्भरता मौजूद नहीं होती है।

लेकिन इससे कोई फर्क नहीं पड़ता - निर्भरता की जानकारी केवल तभी जरूरी है जब .o फ़ाइलें पहले से मौजूद हों, और आपने एक .h फ़ाइल बदल दी है। पहली बार जब आप मेक चलाते हैं, तो सभी .o फ़ाइलों को वैसे भी बनाया जाना चाहिए, और .d फाइलें एक ही समय में उत्पन्न होती हैं।

उसके बाद, .d फ़ाइलें निर्भरता जानकारी देगी। यदि कोई हेडर बदल जाता है, निर्भरता की जानकारी बताएगी कि कौन सी फाइलों को पुनर्निर्माण की आवश्यकता है। यदि कोई स्रोत फ़ाइल बदल दी जाती है, तो .o को हमेशा पुनर्निर्मित करने की आवश्यकता होगी, और अद्यतन निर्भरता जानकारी एक ही समय में उत्पन्न की जाएगी।

1

यदि आपने कभी सोचा है कि आपकी पीठ के पीछे मेकफ़ाइल द्वारा क्या किया जा रहा है, तो -p ध्वज का उपयोग करें, और आउटपुट को फ़ाइल में रीडायरेक्ट करें क्योंकि यह सामान का एक टन है।

make -p foo > barmake foo के लिए सभी परिवर्तनीय मानों और नियमों को डंप करेगा, फिर bar में आपको दिखाएगा कि निहित नियमों के लिए कौन से आदेश चल रहे हैं। आपके मामले में यह आपको दिखाएगा कि .cpp.o या %.o: %.cpp (अजीब तरह से वे दोनों हैं) नियम $(COMPILE.cpp) पर कॉल करेगा जो $(COMPILE.cc) को हल करता है जो $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c पर हल करता है। जिसमें एक दिलचस्प संपत्ति है जिसे आप अपने .cpp.o संकलन में लाने के लिए या तो CXXFLAGS या CPPFLAGS में चीजें जोड़ सकते हैं, लेकिन CFLAGS नहीं, जिसका उपयोग केवल .c.o नियमों द्वारा किया जाता है, जो थोड़ा सा समझता है क्योंकि आप शायद अपने सी चाहते हैं फाइलें और सी ++ फाइलें अलग-अलग निपटाई जाती हैं (सीसी और सीईओसी आमतौर पर विभिन्न कंपाइलरों पर भी सेट होती हैं)।

0

हां, आप सही हैं कि यदि आप निर्भरता फ़ाइलों को हटाते हैं, लेकिन ऑब्जेक्ट फ़ाइलों को जगह में छोड़ दें, तो अपूर्ण निर्भरता जानकारी के साथ चलाएंगे, और ऑब्जेक्ट फ़ाइल को फिर से बनाने में असफल हो सकते हैं जिनके शीर्षलेख बदल गए हैं।

मेक भी निर्माण करने से इंकार कर सकता है - ऐसा तब होता है जब एक निर्भरता फ़ाइल आपके द्वारा हटाए गए हेडर का संदर्भ देती है (और स्पष्ट रूप से अब किसी अन्य स्रोत से संदर्भ नहीं है)। जैसा कि मेक संकलन से पहले निर्भरता फ़ाइल को पुनर्निर्माण करने के बारे में नहीं जानता है, यह सब एक लापता निर्भरता की रिपोर्ट कर सकता है (और फिर स्पष्ट कार्रवाई निर्भरता फ़ाइलों को हटाने के लिए है, जो ऊपर की पहली स्थिति को जन्म देती है)।

इसका एकमात्र उत्तर अनुशासन है: निर्भरता फ़ाइलों को हटाते समय, हमेशा ऑब्जेक्ट फ़ाइलों को हटा दें। आप इसके साथ मदद करने के लिए clean लक्ष्य का उपयोग कर सकते हैं।

clean:: 
     $(RM) *.o *.d 

वैकल्पिक रूप से साथ ही, बता निर्भरता फ़ाइलें बनाने के लिए कैसे करें:

%.dep: %.cc 
     $(CXX) -MM $(CPPFLAGS) $< | sed -e 's,\($*\)\.o[ :]*,\1.o [email protected]: ,g' > [email protected] 

(sed आदेश सुनिश्चित करें कि निर्भरता ही एक ही स्रोत के रूप में वस्तु फ़ाइल करता है पर निर्भर करता है बनाता है)।