CFLAGS बनाम CPPFLAGS


104

मैं समझता हूं कि CFLAGS (या C ++ के लिए CXXFLAGS) कंपाइलर के लिए हैं, जबकि CPPFLAGS प्रीप्रोसेसर द्वारा उपयोग किया जाता है।

लेकिन मुझे अभी भी अंतर समझ में नहीं आया है।

मुझे एक हेडर फ़ाइल के लिए एक शामिल पथ निर्दिष्ट करने की आवश्यकता है जो #include के साथ शामिल है - क्योंकि #include एक प्रीप्रोसेसर निर्देश है, क्या प्रीप्रोसेसर (CPPFLAGS) केवल एक चीज है जिसकी मुझे परवाह है?

किन परिस्थितियों में मुझे कंपाइलर को अतिरिक्त शामिल पथ देना होगा?

सामान्य तौर पर, यदि प्रीप्रोसेसर को आवश्यकता होती है और इसमें हेडर फाइलें शामिल होती हैं, तो उसे अतिरिक्त शामिल निर्देशिकाओं के बारे में बताने की आवश्यकता क्यों होती है? CFLAGS का क्या उपयोग है?

(मेरे मामले में, मैं वास्तव में पाया गया कि दोनों इनमें से मुझे मेरे कार्यक्रम है, जो भ्रम को कहते हैं संकलित करने के लिए अनुमति देते हैं ... मैं CFLAGS उपयोग कर सकते हैं या अपने लक्ष्य (पूरा करने के लिए कम से कम autoconf संदर्भ) में CPPFLAGS। क्या देता है?)


2
के संभावित डुप्लिकेट stackoverflow.com/questions/495598/...
माइकल Mrozek

जवाबों:


154

C प्रोग्राम को संकलित करने के लिए निहितार्थ नियम है

%.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

जहाँ $()वाक्य-विन्यास चर का विस्तार करता है। दोनों के रूप में CPPFLAGSऔर CFLAGSसंकलक कॉल, जो आप पथ शामिल परिभाषित करने के लिए उपयोग करने में किया जाता है व्यक्तिगत स्वाद की बात है। उदाहरण के लिए यदि foo.cवर्तमान निर्देशिका में एक फ़ाइल है

make foo.o CPPFLAGS="-I/usr/include"
make foo.o CFLAGS="-I/usr/include"

क्या दोनों आपके कंपाइलर को ठीक उसी तरह से कॉल करेंगे, जैसे कि

gcc -I/usr/include -c -o foo.o foo.c

दोनों के बीच अंतर तब खेलने में आता है जब आपके पास कई भाषाएं होती हैं जिनमें समान पथ की आवश्यकता होती है, उदाहरण के लिए यदि आपके पास bar.cppकोशिश है

make bar.o CPPFLAGS="-I/usr/include"
make bar.o CFLAGS="-I/usr/include"

फिर संकलन होगा

g++ -I/usr/include -c -o bar.o bar.cpp
g++ -c -o bar.o bar.cpp

C ++ निहित नियम के रूप में भी CPPFLAGSचर का उपयोग करता है ।

यह अंतर आपको एक अच्छा मार्गदर्शक देता है जिसके लिए उपयोग करना है - यदि आप चाहते हैं कि ध्वज का उपयोग सभी भाषाओं के लिए किया जाए CPPFLAGS, अगर यह किसी विशिष्ट भाषा के लिए है, तो इसे डालें CFLAGS, CXXFLAGSआदि। बाद के प्रकार के उदाहरणों में मानक अनुपालन या चेतावनी झंडे शामिल हैं। - आप -std=c99अपने C ++ कंपाइलर को पास नहीं करना चाहेंगे !

फिर आप अपने मेकफाइल में ऐसा कुछ कर सकते हैं

CPPFLAGS=-I/usr/include
CFLAGS=-std=c99
CXXFLAGS=-Weffc++

1
ध्यान दें कि आप किसी भी उचित परिणाम cppका उपयोग करके स्टैंड-अलोन नहीं चला सकते हैं CPPFLAGSक्योंकि यह -std=c99प्रभावित करता है कि कौन से प्रतीक परिभाषित हैं (विशेष रूप से फीचर टेस्ट मैक्रोज़ के बदले)। इसके बजाय, आप की जरूरत है $(CC) $(CPPFLAGS) $(CFLAGS) -E
जेड

10

CPPFLAGSमैक्रो निर्दिष्ट करने के लिए उपयोग करने के लिए एक है #includeनिर्देशिका।

दोनों CPPFLAGSऔर CFLAGSआपके मामले में काम करते हैं क्योंकि make(1) नियम एक कमांड में प्रीप्रोसेसिंग और संकलन दोनों को जोड़ता है (इसलिए कमांड में दोनों मैक्रोज़ का उपयोग किया जाता है)।

.यदि आप प्रपत्र का उपयोग करते हैं, तो आपको शामिल-निर्देशिका के रूप में निर्दिष्ट करने की आवश्यकता नहीं है #include "..."। आपको मानक संकलक में निर्देशिका शामिल करने की भी आवश्यकता नहीं है। आपको अन्य सभी शामिल-निर्देशिकाओं को निर्दिष्ट करने की आवश्यकता है।


यह अधिक समझ में आता है, लेकिन मैं अभी भी सीएफएलएजीएस क्या नहीं करता है। यदि, जैसा कि आप समझ रहे हैं, तो अधिक जटिल परियोजनाओं में संकलन प्रीप्रोसेसिंग से एक अलग चरण में किया जाता है, क्या प्रीप्रोसेसिंग सफल होगा लेकिन यदि सीएफएलएजीएस प्रीप्रोसेसर के लिए CPPFLAGS में वही पथ नहीं जोड़ता है तो संकलन विफल हो जाता है? मुझे लगता है कि मुझे समझ नहीं आ रहा है कि संकलक में पथ क्या शामिल हैं यदि प्रीप्रोसेसर ने पहले से ही # निर्देश को संसाधित किया है?
ईबीएम

4
@ ईबी यदि आप प्रीप्रोसेस की गई फ़ाइलों को संकलित कर रहे हैं, तो शामिल करें पथ अनावश्यक हैं - आवश्यक हेडर पहले से प्रीप्रोसेस किए गए स्रोत में जोड़ दिए गए हैं (जब आप gcc -Eकिसी फ़ाइल पर चलते हैं तो आउटपुट पर एक नज़र डालें - कोई #includes नहीं हैं)। अधिकांश आधुनिक संकलक पूर्व-प्रसंस्करण और संकलन चरणों को जोड़ते हैं, इसलिए आपको इस बारे में चिंता करने की आवश्यकता नहीं है।
स्कॉट वेल्स


0

उन लोगों को जोड़ने के लिए जिन्होंने निहित नियमों का उल्लेख किया है, यह देखना सबसे अच्छा है कि निहितार्थ ने क्या परिभाषित किया है और आपके env का उपयोग कर रहे हैं:

make -p

उदाहरण के लिए:

%.o: %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

जो फैलता है

COMPILE.c = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

इससे # environmentडेटा भी प्रिंट होगा । यहां, आपको अन्य उपयोगी जानकारी के बीच जीसीसी के शामिल पथ मिलेंगे।

C_INCLUDE_PATH=/usr/include

बनाने में, जब खोज करने की बात आती है, तो रास्ते कई हैं, प्रकाश एक है ... या उस प्रभाव के लिए कुछ है।

  1. C_INCLUDE_PATHसिस्टम-वाइड है, इसे अपने शेल में सेट करें *.rc
  2. $(CPPFLAGS) प्रीप्रोसेसर के लिए पथ शामिल है।
  3. यदि आपको बनाने, उपयोग करने के लिए एक सामान्य खोज पथ जोड़ने की आवश्यकता है:
VPATH = my_dir_to_search

... या इससे भी अधिक विशिष्ट

vpath %.c src
vpath %.h include

VPATH का उपयोग सामान्य खोज पथ के रूप में करें, इसलिए सावधानी से उपयोग करें। यदि कोई फ़ाइल VPATH में सूचीबद्ध एक से अधिक स्थानों में मौजूद है, तो सूची में पहली घटना होगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.