CMake में चेतावनी स्तर कैसे सेट करें?


116

CMake का उपयोग करके किसी प्रोजेक्ट के लिए चेतावनी स्तर (संपूर्ण समाधान नहीं) कैसे सेट करें ? विजुअल स्टूडियो और जीसीसी पर काम करना चाहिए ।

मुझे विभिन्न विकल्प मिले, लेकिन ज्यादातर यह लगता है कि या तो काम नहीं कर रहे हैं या दस्तावेज के अनुरूप नहीं हैं।

जवाबों:


96

अद्यतन: यह उत्तर आधुनिक सीएमके युग से पहले का है। हर समझदार सीएमके उपयोगकर्ता को CMAKE_CXX_FLAGSसीधे-सीधे फ़िज़लिंग से बचना चाहिए और target_compile_optionsइसके बजाय कमांड को कॉल करना चाहिए। चेक एमआरटीएस 'जवाब जो सिफारिश सबसे अच्छा अभ्यास प्रस्तुत करता है।

आप ऐसा ही कुछ कर सकते हैं:

if(MSVC)
  # Force to always compile with W4
  if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
  endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
  # Update if necessary
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()

ध्यान दें कि विज़ुअल स्टूडियो के नए संस्करण (कम से कम 2013) समर्थन /Wallध्वज (जिसे नाम दिया गया है EnableAllWarnings)। की तुलना में यह और भी अधिक चेतावनी उत्पन्न करता है /W4। हालांकि मेरे अनुभव से यह बहुत अधिक चेतावनी पैदा करता है।
एडम बदुरा

12
/Wallयदि आप चेतावनियों की तरह चेतावनियों के लिए 'घटाव' की रणनीति का पालन करना चाहते हैं, तो यह प्रयोग करने योग्य है -Weverything। सक्षम करने के लिए चेतावनियों का चयन करने के बजाय, आप सब कुछ सक्षम करते हैं और फिर अक्षम करने के लिए विशिष्ट चेतावनियों का चयन करते हैं।
bames53

86

आधुनिक सीएमके में, निम्नलिखित अच्छी तरह से काम करता है:

if(MSVC)
  target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
  target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()

मेरे सहयोगी ने एक वैकल्पिक संस्करण सुझाया:

target_compile_options(${TARGET_NAME} PRIVATE
  $<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
  $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)

${TARGET_NAME}वास्तविक लक्ष्य नाम से बदलें । -Werrorवैकल्पिक है, यह सभी चेतावनियों को त्रुटियों में बदल देता है।

या उपयोग करें add_compile_options(...)यदि आप इसे टिप्पणियों में @aldo द्वारा सुझाए गए सभी लक्ष्यों पर लागू करना चाहते हैं।

इसके अलावा, के बीच के अंतर को समझना सुनिश्चित करें PRIVATEऔर PUBLIC(सार्वजनिक विकल्प उन लक्ष्यों द्वारा विरासत में प्राप्त होंगे जो दिए गए लक्ष्य पर निर्भर करते हैं)।


19
या बस add_compile_options(...)अगर आप इसे सभी लक्ष्यों पर लागू करना चाहते हैं।
०18

1
FYI करें आधुनिक सीएमके में else()या हालत को दोहराने की आवश्यकता नहीं है endif()
टिमम्म

1
@Timmmm सिर के लिए धन्यवाद! क्या यह सिर्फ एक नोट है या आप मुझे शर्तों को हटाने के लिए पसंद करेंगे?
19

1
@helmesjo No, Timmmm CMake कोड का उल्लेख कर रहा था क्योंकि यह 9 अप्रैल के संपादन से पहले मौजूद था। आप हटाए गए बिट्स को देखने के लिए संपादित इतिहास पर एक नज़र डाल सकते हैं, जो वही चीजें हैं जो टिम्म्म इंगित कर रहे थे।
FeRD

2
@aldo के साथ समस्या add_compile_options()यह है कि चेतावनियों के माध्यम से जोड़े गए लक्ष्यों को प्रचारित किया जाएगा add_subdirectory()। यदि आप बाहरी पुस्तकालयों को इस तरह से शामिल करते हैं तो आपको बहुत सारी चेतावनियाँ मिल सकती हैं यदि उस पुस्तकालय को अलग-अलग चेतावनी स्तर के साथ डिज़ाइन किया गया हो।
ट्रोजन 10

24

मेरे द्वारा लिखे गए कुछ सीएमके मॉड्यूल में प्रायोगिक क्रॉस-प्लेटफ़ॉर्म चेतावनी दमन शामिल हैं :

sugar_generate_warning_flags(
    target_compile_options
    target_properties
    ENABLE conversion
    TREAT_AS_ERRORS ALL
)

set_target_properties(
    foo
    PROPERTIES
    ${target_properties}
    COMPILE_OPTIONS
    "${target_compile_options}"
)

Xcode के लिए परिणाम:

  • सेट CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSIONXcode विशेषता (उर्फ बिल्ड सेटिंग्स -> चेतावनियाँ -> संदिग्ध अंतर्निहित रूपांतरण -> हाँ )
  • संकलक ध्वज जोड़ें: -Werror

Makefile gcc और clang:

  • संकलक झंडे जोड़ें: -Wconversion,-Werror

दृश्य स्टूडियो:

  • संकलक झंडे जोड़ें: /WX,/w14244

लिंक


1
यह शर्म की बात है कि इस कार्यक्षमता को प्रदान नहीं करता है
स्लाव

3
खुशखबरी। इसे यहाँ पोस्ट करने के लिए क्षमा करें और cmake मेलिंग-सूची में नहीं, लेकिन स्तर के बिना यह बेकार होगा, उन सभी को स्पष्ट रूप से सूचीबद्ध करने के लिए बहुत अधिक चेतावनी हैं। यदि आप इसे दो अलग cmake_level करने के लिए एक तरह से एकीकृत करना चाहते हैं - एक संकलक के लिए विशिष्ट अर्थ के साथ clang, और native_level पर आधारित चेतावनी का एकीकृत सेट। उनमें से एक को संभवतः स्तर तक छोटा किया जा सकता है। क्षमा करें यदि मैंने वास्तव में बातचीत का पालन नहीं किया और कुछ गलत हो गया
स्लाव

1
@ void.pointer एक वैध बिंदु उठाता है। आपका प्रस्तावित उत्तर पढ़ता है: " मैं इस सुविधा को जोड़ने की योजना बना रहा हूं " । यह नहीं कहता है, कि आपने कुछ सरसरी शोध किया है और अब किसी और से आपके लिए भारी उठाने की उम्मीद है। यदि आप कार्यान्वयन (और इसकी प्रगति पर सवाल) के साथ जिम्मेदार नहीं होना चाहते हैं, तो आपको अपने जवाब को संपादित करने और उस कार्य से खुद को अलग करने की आवश्यकता है जिसे आपने एक साल में अच्छी तरह से प्रगति नहीं की है।
IInspectable

"एक साल बाद, अभी भी कोई प्रगति नहीं हुई है।" - अब यह एक मान्य बिंदु है। शून्य प्रगति के साथ एक वर्ष से अधिक समय बीत चुका है। यह एक परित्यक्त परियोजना का एक बहुत मजबूत संकेत है। यदि आप हमें गलत साबित करना चाहते हैं, तो हमें कुछ प्रगति दिखाएं। ऐसा नहीं हुआ है, लेकिन आपका प्रस्तावित उत्तर अभी भी बताता है, कि यह सुविधा सीएमके से जुड़ने वाली है। एक सुविधा के बारे में सभी उपद्रव क्यों करें जो वर्षों में उपलब्ध नहीं होंगे? यह बिल्कुल भी मददगार नहीं है। या तो कुछ प्रगति दिखाएं, या कम भ्रामक होने के लिए अपने उत्तर को संपादित करें।
IInspectable

5
आप समझते नहीं हैं। यदि आप सुझाव देते हैं कि आप एक सुविधा लागू करने जा रहे हैं, तो आपको उस सुविधा को नियत समय में लागू करने की आवश्यकता है। असफल होने पर, आपको अपने प्रस्तावित उत्तर से उस वादे को हटाने के लिए कहा जाता है। आपने उक्त सुविधा को लागू करने के लिए शून्य प्रतिबद्धता दिखाई है, इसलिए अन्यथा दावा न करें। मैं समझता हूं कि यह बड़ा है। मैं यह भी समझता हूं कि आप इसे खींचने में सक्षम नहीं हो सकते हैं। मैं बस आपको अपने उत्तर को प्रतिबिंबित करने के लिए कह रहा हूं।
IInspectable

6

यहाँ अब तक का सबसे अच्छा समाधान है (एक संकलक जाँच सहित):

if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
    add_definitions(/W2)
endif()

यह Visual Studio में चेतावनी स्तर 2 सेट करेगा। मुझे लगता है कि -W2यह जीसीसी (अनछुए) में भी काम करेगा।

@Williams से अपडेट: यह -Wallजीसीसी के लिए होना चाहिए ।


6
GCC के लिए चेतावनी ध्वज होगा -Wallऔर शायद gcc.gnu.org/onbuildocs/gcc/Warning-Options.html-Wextra पर विस्तृत होगा
मिलिशिया

1
मेरे द्वारा उपयोग की जाने वाली सूची है -W -Wall -Wextra -pedantic-WextraIIRC -Wको GCC के बाद के संस्करण में बदल दिया गया, लेकिन मैं दोनों को कॉम्पिटिशन के लिए छोड़ देता हूं।
जिममोइह

2
यह add_definitions का इच्छित उद्देश्य नहीं है ( "प्रीप्रोसेसर परिभाषाएँ जोड़ने का इरादा है" )। यह सिर्फ एक सर्वोत्तम प्रथाओं की सिफारिश नहीं है। इस आदेश के लिए दिए गए तर्क उत्पन्न बिल्ड स्क्रिप्ट्स में दिखाई देंगे जो ऐसे उपकरण हैं जो उनसे उम्मीद नहीं करते हैं (उदाहरण के लिए संसाधन संकलक)।
IInspectable

यह "कंपाइलर चेक" नहीं है, यह एक बिल्ड टूल चेक है।
थॉमस

3

Cmake 3.17.1 प्रलेखन के अनुसार :

if (MSVC)
    # warning level 4 and all warnings as errors
    add_compile_options(/W4 /WX)
else()
    # lots of warnings and all warnings as errors
    add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()

जीसीसी और क्लैंग इन झंडों को साझा करते हैं, इसलिए इसे सभी 3 को कवर करना चाहिए।


यह प्रयोग न करें। इसके बजाय, target_compile_options () का उपयोग करें। नवीनतम दस्तावेज़ का उल्लेख "सही" लगता है, लेकिन यह केवल पिछड़ी-अनुकूलता के लिए एक प्राचीन प्रविष्टि है।
काओनन

1
@caoanan प्रलेखन में इसके लिए पिछड़ी-अनुकूलता के बारे में कुछ नहीं बताया गया है। add_compile_optionsनिर्देशिका-चौड़ा है, जबकि target_compile_optionsकेवल एक लक्ष्य के लिए है।
तेहरान

2
if(MSVC)
    string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()

यदि आप उपयोग करते हैं target_compile_options- सेमीक डबल /W*ध्वज का उपयोग करने का प्रयास करेगा , जो संकलक द्वारा चेतावनी देगा।


इसके लिए धन्यवाद। मैं भयंकर रूप से add_compile_optionsकेवल उन चेतावनियों को प्राप्त करने के लिए उपयोग कर रहा था, /W3जिनके साथ सामना किया जा रहा है /W4। तथ्य यह है कि सीएमके इस अल्पविकसित विकल्प को संबोधित नहीं कर रहे हैं (चेतावनी स्तर स्थापित करना) विश्वास से परे है।
पुनरुत्थान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.