एकल फ़ाइलों के लिए ध्वज संकलित करें


109

मैं किसी प्रोजेक्ट को संकलित करने के लिए झंडे के एक वैश्विक सेट का उपयोग करना चाहूंगा, जिसका अर्थ है कि मेरे शीर्ष-स्तरीय CMakeLists.txt फ़ाइल में मैंने निर्दिष्ट किया है:

ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )

हालांकि, एक उपनिर्देशिका में एक विशिष्ट फ़ाइल के लिए (मान लें कि "foo.cpp"), मैं लागू नहीं करने के लिए संकलित झंडे को स्विच करना चाहता हूं-वेबफेक ++ (इसमें वाणिज्यिक पुस्तकालय जिसे मैं बदल नहीं सकता हूं) शामिल है। केवल उपयोग करने के लिए स्थिति को सरल बनाने के लिए, मैंने कोशिश की:

 SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
 ADD_EXECUTABLE( foo foo.cpp )

, जो काम नहीं किया। मैंने भी कोशिश की

SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )

तथा

ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )

जिसमें न तो काम किया गया।

अंत में, मैंने इस विक्षेप को हटाने की कोशिश की:

REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )

, जो भी काम नहीं करता था (मतलब, मुझे व्यावसायिक पुस्तकालय के बारे में बहुत सारी शैली की चेतावनी मिलती है)। (** नोट: अगर मैं फिर से शामिल करने योग्य है, तो वेफ्रेक् ट निर्मित होने के बाद-WEffc ++ निर्देश को दोबारा शामिल नहीं करने पर चेतावनी को दबा दिया जाता है।)

मैंने भी अस्थायी झंडे को हटाने की कोशिश की: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , लेकिन इससे कोई फायदा नहीं हुआ।

क्या इसका कोई सुरुचिपूर्ण समाधान नहीं है?


1
रुको, अगर आपका आखिरी प्रयास काम करता है, लेकिन इसके निर्माण के बाद ही, यह एक कैशिंग मुद्दा नहीं हो सकता है? अपना परिवर्तन करने के बाद CMakeCache को हटाने का प्रयास करें।
कैमरून

संबंधित, देखें कि सीएमके में केवल एक निष्पादन योग्य के लिए संकलक ध्वज को कैसे बदलना है? आंद्रे का जवाब दिखाता है कि मौजूदा विकल्पों को नए विकल्पों के साथ बदलने का एक तरीका क्या है।
jww

जवाबों:


126

ऊपर दिए गए आपके प्रयास आपकी फ़ाइल / लक्ष्य में आगे के झंडे जोड़ रहे हैं बजाय कि आप अपेक्षा के अनुरूप हैं। उदाहरण के लिए, स्रोत फ़ाइलों पर गुणों के लिए डॉक्स से - COMPILE_FLAGS :

जब ये स्रोत फ़ाइल बनाता है तो ये झंडे संकलन झंडों की सूची में जुड़ जाएंगे।

आपको -Weffc++ऐसा करने के लिए foo.cpp के लिए ध्वज का प्रतिकार करने में सक्षम होना चाहिए

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

इसमें कंपाइलर कमांड के -Wno-effc++बाद जोड़ने का प्रभाव होना चाहिए -Weffc++, और बाद की सेटिंग जीत जाती है। पूर्ण कमांड को देखने के लिए और जांचें कि यह वास्तव में मामला है, आप कर सकते हैं

make VERBOSE=1

एक तरफ, जीएनयू सी ++ स्टैंडर्ड लाइब्रेरी के अनुरक्षकों में से एक इस उत्तर-Weffc++ में एक बहुत ही नकारात्मक राय प्रस्तुत करता है ।

एक और बात यह है कि आप add_definitionsइस अर्थ में दुरुपयोग कर रहे हैं कि आप इसका उपयोग संकलक झंडे के लिए कर रहे हैं, बजाय इच्छित प्रीप्रोसेसर परिभाषाओं के।

यह उपयोग करने के लिए बेहतर होगा add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

या सीएमके संस्करणों के लिए <3.0 कुछ और करने के लिए जैसे:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")

नीचे दी गई टिप्पणियों में आगे के सवालों के जवाब में, मेरा मानना ​​है कि किसी एकल फ़ाइल पर किसी ध्वज को विश्वसनीय रूप से निकालना असंभव है । कारण यह है कि किसी भी स्रोत फ़ाइल के लिए, उसके पास COMPILE_OPTIONSऔर उसके लक्ष्य का 1 लागू होता है, लेकिन ये उस स्रोत फ़ाइल के किसी भी गुण में दिखाई नहीं देते हैं।COMPILE_FLAGS

आप लक्ष्य से समस्या के झंडे को उतारने पर विचार कर सकते हैं COMPILE_OPTIONS, फिर इसे लक्ष्य के प्रत्येक स्रोत पर व्यक्तिगत रूप से लागू कर सकते हैं, इसे आवश्यक स्रोत फ़ाइल से अलग कर सकते हैं।

हालाँकि, जबकि यह कई परिदृश्यों में काम कर सकता है, इसमें कुछ समस्याएं हैं।

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

दूसरा - CMake v3.0 के बाद से, लक्ष्य निर्दिष्ट कर सकते हैं INTERFACE_COMPILE_OPTIONS। इसका मतलब है कि आपके लक्ष्य की एक निर्भरता आपके लक्ष्य COMPILE_OPTIONSको इसके माध्यम से जोड़ या ओवरराइड कर सकती है INTERFACE_COMPILE_OPTIONS। तो आपको आगे अपने सभी लक्ष्य की निर्भरता के माध्यम से पुनरावृत्ति करना होगा (विशेष रूप से आसान काम नहीं है क्योंकि LINK_LIBRARIESलक्ष्य की सूची में जनरेटर के भाव भी हो सकते हैं) किसी भी समस्या का झंडा लगाने वाले को खोजने के लिए, और कोशिश करें और इसे उन लोगों से हटा दें लक्ष्य INTERFACE_COMPILE_OPTIONSभी।

जटिलता के इस चरण में, मैं सीएमके को एक स्रोत फ़ाइल से बिना शर्त एक विशिष्ट ध्वज को हटाने के लिए कार्यक्षमता प्रदान करने के लिए एक पैच प्रस्तुत करना चाहूंगा।


1: ध्यान दें कि COMPILE_FLAGSस्रोत फ़ाइलों पर संपत्ति के विपरीत , COMPILE_FLAGSलक्ष्य पर संपत्ति को हटा दिया जाता है।


6
लेकिन आप वास्तव में फ़ाइलों के लिए संकलन झंडे को अलग-अलग बिना उन्हें कैसे जोड़ सकते हैं। उदाहरण के लिए, मैं फ़ाइलों के लिए परिणामी लक्ष्य के लिए विभिन्न संकलित झंडे का उपयोग करना चाहता हूं, लेकिन चूंकि उन्हें जोड़ा जाता है इसलिए मुझे उन्हें मैन्युअल रूप से निकालना होगा। क्या कोई ऐसी संपत्ति नहीं है जो अपेंड नहीं करती है लेकिन वास्तव में उन्हें केवल निर्दिष्ट फ़ाइल / लक्ष्य के लिए निर्धारित करती है?
15

2
-Fno- ध्वज उपलब्ध नहीं होने पर हम क्या कर सकते हैं (-fflag सेट है)?
gnzlbg

@ Baradé आप एक स्रोत फ़ाइल के लिए नहीं कर सकते।
फ्रेजर

@gnzlbg फिर, हम बहुत फंस गए हैं। मैंने अपने उत्तर को थोड़ा और जानकारी देने के लिए अद्यतन किया है (और एक संभावित समाधान जो शायद कुछ परिदृश्यों में काम करेगा )।
फ्रेजर

वहाँ वास्तव में एकल फ़ाइल संकलन विकल्प सेटिंग करने के लिए कोई समाधान नहीं है? मुझे कुछ फ़ाइलों के लिए gcc कवरेज जनरेशन को निष्क्रिय करना होगा जो gcov को क्रैश कर रही हैं।
लोथार

5

बस @ फ्रेजर के सही उत्तर को जोड़ना।

यदि आप विशिष्ट फ़ोल्डर में विशेष ध्वज जोड़ना चाहते हैं तो आप ऐसा कर सकते हैं:

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_property(SOURCE ${SPECIAL_SRC_FILES} PROPERTY COMPILE_FLAGS -Wno-effc++)

या

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_source_files_properties(${SPECIAL_SRC_FILES} PROPERTIES COMPILE_FLAGS -Wno-effc++)

ध्यान दें कि इसकी चर्चा यहाँ के रूप में GLOB का उपयोग करने के लिए अनुशंसित नहीं है


0

@Fraser उत्तर का उपयोग करते हुए, मैंने Qt को संभालने के लिए निम्नलिखित को शामिल किया है क्योंकि चर में अर्धविराम द्वारा अलग किए गए कई पथ शामिल हैं। इसका मतलब है कि मुझे पहले एक foreach()लूप जोड़ना था और हाथ से झंडे शामिल करना था । लेकिन इससे मुझे एक अपवाद की अनुमति मिलती है: foo.cpp (कि एक फ़ाइल अब के लिए Qt का उपयोग करती है, लेकिन लंबे समय तक मैं उस निर्भरता को दूर करना चाहता हूं और मैं यह सुनिश्चित करना चाहता हूं कि कहीं और क्यूटी रेंगना न हो)।

find_package(Qt5Core REQUIRED)
set(QT_INCLUDE_PROPERTIES "")
foreach(DIR ${Qt5Core_INCLUDE_DIRS})
    set(QT_INCLUDE_PROPERTIES "${QT_INCLUDE_PROPERTIES} -isystem ${DIR}")
endforeach()
set_source_files_properties(foo.cpp PROPERTIES
    COMPILE_FLAGS
        ${QT_INCLUDE_PROPERTIES}
)

यह भी ध्यान दें कि मैं -isystemइसके बजाय -Iकुछ चेतावनियों से बचने के लिए उपयोग करता हूं जो क्यूटी हेडर अन्यथा उत्पन्न करते हैं (मेरे पास एक टन चेतावनी है जो चालू है)।

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