2016-03-03 3 views
5

के साथ संकलन करते समय मुझे कोई समस्या नहीं है कि मुझे यकीन नहीं है कि कैसे हल किया जाए।संकलन चेतावनी नहीं जब स्थानीय मशीन पर ONLY_ACTIVE_ARCH = NO

हमारी कई परियोजनाओं में हम "उपचार चेतावनियों के रूप में त्रुटियों" (GCC_TREAT_WARNINGS_AS_ERRORS) को YES में बदलना चाहते हैं।

हम भी की Xcode डिफ़ॉल्ट परियोजना स्थापित करने बाहर जाना चाहते हैं डिबग के लिए YES और NO रिलीज के लिए करने के लिए "सक्रिय वास्तुकला केवल बनाएँ" (ONLY_ACTIVE_ARCH)।

हालांकि इसमें एक बड़ी कमी है। संहिता जैसे ...

NSUInteger bob = 12234; 
NSLog(@"bob %lu", bob); 

चेतावनी निम्न प्रकार है (और इसलिए हमारे मामले में त्रुटि) का उत्पादन करना चाहिए:

प्रकार 'NSUInteger' के मान प्रारूप तर्कों के रूप में इस्तेमाल नहीं किया जाना चाहिए, 'अहस्ताक्षरित लंबी' का सुस्पष्ट वर्णक जोड़ने के बजाय

लेकिन जब डेवलपर्स निर्माण कर रहे हैं और स्थानीय स्तर पर परीक्षण वे इस चेतावनी/त्रुटि का सामना करना नहीं है, लेकिन जब वे हमारे भंडार के लिए प्रतिबद्ध है और हमारे सतत एकीकरण कमांड लाइन से xcodebuild चलाता है चेतावनी का सामना करना पड़ रहा है और उनका निर्माण विफल रहता है। यह स्पष्ट रूप से निराशाजनक है।

मुझे लगता है कि एक्सकोड का उपयोग करते समय आर्किटेक्चर के निर्माण के दौरान और कमांड लाइन से xcodebuild का उपयोग करते समय इस अंतर के साथ कुछ करने के लिए कुछ है।

मैं एक नमूना परियोजना यहाँ अपलोड कर दिया है ...

https://github.com/OliverPearmain/ArchitectureDependantCompileWarning

2 योजनाओं को शामिल किया है। यदि आप "आर्किटेक्चर पर निर्भर कॉम्पाइल वार्निंग" का उपयोग करते हुए एक आईफोन 6 एस सिम्युलेटर के लिए संकलित करते हैं (जो डीबग बिल्ड कॉन्फ़िगरेशन का उपयोग करता है और इस प्रकार ONLY_ACTIVE_ARCH==YES) आपको कोई चेतावनी नहीं मिलती है और चीजें ठीक संकलित होती हैं। यदि आप "आर्किटेक्चर पर निर्भर कॉम्पाइल वार्निंग-फेल्स" योजना का उपयोग करते हैं (जो रिलीज बिल्ड कॉन्फ़िगरेशन का उपयोग करता है और इस प्रकार ONLY_ACTIVE_ARCH==NO) तो चेतावनी का सामना करना पड़ता है और संकलन विफल हो जाता है।

मैं किसी भी तरह यह सुनिश्चित करना चाहता हूं कि ONLY_ACTIVE_ARCH==NO के साथ सिम्युलेटर के निर्माण के दौरान यह चेतावनी हमेशा सामने आती है। क्या यह संभव है?

+0

मुझे लगता है कि यह संभव नहीं है, लेकिन मैं गलत हो सकता हूं। चेतावनी होती है, क्योंकि 'हस्ताक्षरित लंबी' की अपेक्षा होने पर एक 'हस्ताक्षरित int' पारित किया जाता है। तो जब 'NSUInteger'' लंबे समय तक हस्ताक्षरित 'होता है तो यह सब अच्छा लगता है। मैं कल्पना कर सकता हूं कि कोई भी सफल निर्माण के अंत में प्रत्येक आवश्यक आर्किटेक्चर के लिए किसी प्रकार की टैग फ़ाइल बनाने के लिए बिल्ड प्रक्रिया को समायोजित कर सकता है और संस्करण नियंत्रण प्रतिबद्धता को अस्वीकार कर देता है, अगर टैग फाइल मान्य नहीं है (जो भी इसका विस्तार हो सकता है - शायद टैग फ़ाइल वैध है अगर यह सभी स्रोत फ़ाइलों से नई है?)। –

+0

एकमात्र तरीका जिसे मैं पकड़ने में सक्षम हूं, हमेशा डीबग मोड में "जेनेरिक आईओएस डिवाइस" के लिए भी निर्माण करना है, जिसका एक ही व्यावहारिक प्रभाव है (जैसा कि मैं इसे समझता हूं) ONLY_ACTIVE_ARCH = NO के रूप में। लेकिन अगर आप ऐसा करने जा रहे हैं, तो बस डीबग मोड में भी सभी आर्कों के लिए इसे बना सकते हैं, जो असुविधाजनक है। शायद सभी आर्कों के निर्माण के लिए अपने स्थानीय यूनिट परीक्षण लक्ष्य को समायोजित करें (जो मुझे लगता है कि देवताओं को स्थानीय रूप से चलाने से पहले स्थानीय रूप से चलाया जाता है)? – Palpatim

+0

कुछ व्यावहारिक सलाह के रूप में,% zd किसी भी आर्किटेक्चर पर सही ढंग से और चेतावनी के बिना एनएसआईएनटेगर प्रिंट करेगा, इसलिए% zd का उपयोग करना एक अच्छी आदत होगी। – gnasher729

उत्तर

1

5s बाहर आने पर शब्द की लंबाई में बदलाव का कारण यह है। दूसरे शब्दों में, 5s और अधिक iPhones में 64-बिट प्रोसेसर है, जबकि पिछले सभी iPhones में 32-बिट प्रोसेसर था।

यहाँ वास्तव में के लिए NSUInteger

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 
typedef long NSInteger; 
typedef unsigned long NSUInteger; 
#else 
typedef int NSInteger; 
typedef unsigned int NSUInteger; 
#endif 

typedefs आप एक 32-बिट प्रोसेसर के लिए देख सकते हैं कि है, NSUInteger स्पष्ट रूप से एक 64-बिट प्रोसेसर के लिए एक unsigned int जबकि के रूप में परिभाषित किया गया है, NSUInteger स्पष्ट रूप से एक unsigned long के रूप में बचाव ।

तो, इस कोड को देखकर ...

NSUInteger bob = 12234; 
NSLog(@"bob %lu", bob); 

एक 4s के लिए, यह NSLog के बाद से NSUInteger स्पष्ट रूप से एक unsigned int के रूप में परिभाषित किया गया है और फॉर्मेट स्पेसिफायर %lu एक unsigned long है एक बेमेल है। यह बहुत स्पष्ट विसंगति यह कारण है कि 32-बिट प्रोसेसर के लिए चेतावनी मौजूद है। 64-बिट प्रोसेसर के लिए कोई मेल नहीं है और इस प्रकार कोई चेतावनी नहीं है।

चेतावनी में सुझाए गए फ़िक्स मानते हैं कि आप unsigned long का उपयोग करना चाहते हैं। हालांकि, यहां एक वैकल्पिक समाधान है।

NSUInteger bob = 12234; 
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 
NSLog(@"bob %lu", bob); 
#else 
NSLog(@"bob %u", bob); 
#endif 

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

संपादित करें:

यह एक चेतावनी/त्रुटि के रूप में प्रकट करने में नाकाम रहने के लिए एक बेमेल त्रुटि का मामला नहीं है। सचमुच एक मेल नहीं है। इस त्रुटि को दिखाने का एकमात्र तरीका वास्तव में एक मेल नहीं है। यदि आप आर्किटेक्चर के खिलाफ निर्माण कर रहे हैं, तो केवल एक विसंगति होगी जिसके लिए NSUInteger की परिभाषा आपके द्वारा उल्लिखित विशिष्ट कोड में मेल नहीं खाती है। ऐसा करने के लिए पहले से ही एक मानक तरीका है: अपनी सभी योजनाओं के लिए "केवल सक्रिय आर्किटेक्चर बनाएं" सेट करें

+0

ठीक है, लेकिन यह सभी प्लेटफार्मों के लिए हमेशा इन शब्द लंबाई चेतावनियों को चालू करने के सवाल का उत्तर नहीं देता है। – JAL

+0

मेरी कीबोर्ड बैटरी की मृत्यु हो गई और मेरा जवाब पूरा होने से पहले सबमिट हो गया। मैंने बैटरी बदल दी और मेरा जवाब समाप्त कर दिया। –

+0

मैं वास्तव में दूसरों के लाभ के लिए इस उत्तर को सही करने के लिए समय निकालने की सराहना करता हूं। हालांकि मैं वर्णित व्यवहार के पीछे कारणों और इतिहास से पूरी तरह से अवगत हूं। मैं अपने ओपी में जो विशिष्ट रूप से पूछ रहा हूं वह यह सुनिश्चित करने के लिए है कि यह त्रुटि उन लोगों के लिए प्रकट होती है जब वे कुछ सिमुलेटर के निर्माण करते हैं। –

संबंधित मुद्दे