जवाबों:
सीएमके स्क्रिप्ट लिखते समय सिंटैक्स के बारे में आपको बहुत कुछ जानने की जरूरत है और सीएमके में चर का उपयोग कैसे करें।
स्ट्रिंग्स का उपयोग set()
:
set(MyString "Some Text")
set(MyStringWithVar "Some other Text: ${MyString}")
set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")
या साथ string()
:
string(APPEND MyStringWithContent " ${MyString}")
का उपयोग कर सूची set()
:
set(MyList "a" "b" "c")
set(MyList ${MyList} "d")
या इसके साथ बेहतर list()
:
list(APPEND MyList "a" "b" "c")
list(APPEND MyList "d")
फ़ाइल नामों की सूची:
set(MySourcesList "File.name" "File with Space.name")
list(APPEND MySourcesList "File.name" "File with Space.name")
add_excutable(MyExeTarget ${MySourcesList})
set()
कमांडstring()
कमांडlist()
कमांडपहले "सामान्य चर" और चीजें हैं जो आपको उनके दायरे के बारे में जानने की जरूरत है:
CMakeLists.txt
वे में और सब कुछ कहा जाता है सेट कर रहे हैं वहाँ से ( add_subdirectory()
, include()
, macro()
और function()
)।add_subdirectory()
और function()
आदेश, विशेष कर रहे हैं, क्योंकि वे खोलने-अप अपने स्वयं के दायरे।
set(...)
वहां केवल दिखाई देते हैं और वे उस स्तर के सभी सामान्य चर की एक प्रति बनाते हैं, जिन्हें वे कहा जाता है (जिन्हें मूल गुंजाइश कहा जाता है)।set(... PARENT_SCOPE)
function(xyz _resultVar)
स्थापित करना होगाset(${_resultVar} 1 PARENT_SCOPE)
include()
या macro()
स्क्रिप्ट में जो कुछ भी सेट करते हैं, वे चर को सीधे उस दायरे में संशोधित करेंगे जहां से उन्हें बुलाया जाता है।दूसरा "ग्लोबल वैरिएबल कैश" है। कैश के बारे में जानने के लिए आपको जिन चीजों की आवश्यकता है:
CMakeCache.txt
आपके बाइनरी आउटपुट डायरेक्टरी में फ़ाइल में संग्रहीत हैं ।Cache के मान उत्पन्न होने से पहले CMake के GUI एप्लिकेशन में संशोधित किए जा सकते हैं। इसलिए वे - सामान्य चर की तुलना में - ए type
और ए हैं docstring
। मैं आमतौर पर GUI का उपयोग नहीं करता हूं इसलिए मैं set(... CACHE INTERNAL "")
अपने वैश्विक और निरंतर मूल्यों को निर्धारित करने के लिए उपयोग करता हूं।
कृपया ध्यान दें कि INTERNAL
कैश वेरिएबल टाइप इंप्लीमेंट करता हैFORCE
यदि आप set(... CACHE ... FORCE)
सिंटैक्स का उपयोग करते हैं तो एक CMake स्क्रिप्ट में आप केवल मौजूदा कैश प्रविष्टियों को बदल सकते हैं । यह व्यवहार उदाहरण के लिए CMake द्वारा ही किया जाता है, क्योंकि यह आम तौर पर Cache प्रविष्टियों को स्वयं बाध्य नहीं करता है और इसलिए आप इसे दूसरे मान से पूर्व-परिभाषित कर सकते हैं।
cmake -D var:type=value
, बस cmake -D var=value
या साथ cmake -C CMakeInitialCache.cmake
।unset(... CACHE)
।कैश वैश्विक है और आप उन्हें अपने CMake स्क्रिप्ट में कहीं भी सेट कर सकते हैं। लेकिन मैं आपको दो बार सोचने की सलाह दूंगा कि कैश वैरिएबल का उपयोग कहां किया जाए (वे वैश्विक हैं और वे लगातार हैं)। मैं आमतौर पर अपने स्वयं के गैर-निरंतर वैश्विक चर को परिभाषित करने के लिए set_property(GLOBAL PROPERTY ...)
और set_property(GLOBAL APPEND PROPERTY ...)
वाक्यविन्यास पसंद करता हूं।
नुकसान से बचने के लिए आपको निम्नलिखित चर के बारे में जानना चाहिए:
find_...
आदेशों - सफल अगर - कैश्ड चर के रूप में उनके परिणाम लिख सकता हूं "इसलिए कोई कॉल फिर से खोज करेंगे कि"set(MyVar a b c)
है "a;b;c"
और set(MyVar "a b c")
है"a b c"
list()
सूचियों को संभालने के लिए कमांड पसंद करते हैंfunctions()
बजाय इसका उपयोग करने की अनुशंसा की जाती है macros()
क्योंकि आप अपने स्थानीय चर को मूल दायरे में नहीं दिखाना चाहते हैं।project()
और enable_language()
कॉल के साथ सेट किए गए हैं । इसलिए उन आदेशों का उपयोग करने से पहले कुछ चर निर्धारित करना महत्वपूर्ण हो सकता है।कभी-कभी केवल डीबगिंग चर मदद करता है। निम्नलिखित आपकी मदद कर सकते हैं:
printf
का उपयोग करके पुरानी डिबगिंग शैली का उपयोग करें message()
। सीएमके के साथ भेजे गए मॉड्यूल का उपयोग करने के लिए भी कुछ तैयार हैं: CMakePrintHelpers.cmake , CMakePrintSystemInformation.cmakeCMakeCache.txt
अपने बाइनरी आउटपुट डायरेक्टरी में फ़ाइल में देखें। यह फ़ाइल तब भी जेनरेट होती है जब आपके मेक इनवायरमेंट की वास्तविक पीढ़ी विफल हो जाती है।cmake --trace ...
सीएमके की पूर्ण पार्सिंग प्रक्रिया को देखने के लिए कॉल करें। यह अंतिम रिज़र्व की तरह है, क्योंकि यह बहुत अधिक आउटपुट उत्पन्न करता है।$ENV{...}
और लिख सकते हैंset(ENV{...} ...)
$<...>
का मूल्यांकन केवल तब किया जाता है जब सीएमके का जनरेटर मेक एनवायरनमेंट लिखता है (यह सामान्य वेरिएबल्स की तुलना करता है जो "पार्सर द्वारा" इन-प्लेस "प्रतिस्थापित किए जाते हैं)${${...}}
आप एक चर में चर नाम देना और उसकी सामग्री को संदर्भित कर सकते।if()
आदेश देखें )
if(MyVariable)
आप सीधे सही / गलत के लिए एक चर (संलग्न की कोई आवश्यकता नहीं यहाँ जाँच कर सकते हैं ${...}
)1
, ON
, YES
, TRUE
, Y
, या एक गैर शून्य संख्या।0
, OFF
, NO
, FALSE
, N
, IGNORE
, NOTFOUND
, खाली स्ट्रिंग, या प्रत्यय में समाप्त हो जाती है -NOTFOUND
।if(MSVC)
, लेकिन यह किसी ऐसे व्यक्ति के लिए भ्रमित हो सकता है जो इस सिंटैक्स शॉर्टकट को नहीं जानता है।set(CMAKE_${lang}_COMPILER ...)
if()
आज्ञाओं में सिरदर्द दे सकता है । यहाँ एक उदाहरण है कि कहाँ CMAKE_CXX_COMPILER_ID
है "MSVC"
और क्या MSVC
है "1"
:
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
सच है, क्योंकि यह मूल्यांकन करता है if("1" STREQUAL "1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
गलत है, क्योंकि यह मूल्यांकन करता है if("MSVC" STREQUAL "1")
if(MSVC)
cmake_policy(SET CMP0054 NEW)
"केवल if()
तर्क या व्याख्या के रूप में तर्क की व्याख्या करते समय निर्धारित करने के लिए सेट करूंगा ।"option()
आदेश
ON
या OFF
वे कुछ विशेष हैंडलिंग जैसे उदाहरण पर निर्भरता की अनुमति देते हैंoption
साथ गलती न करें set
। दिए गए मूल्य option
वास्तव में केवल "प्रारंभिक मूल्य" है (पहले कॉन्फ़िगरेशन चरण के दौरान कैश में एक बार स्थानांतरित) और बाद में सीएमके के जीयूआई के माध्यम से उपयोगकर्ता द्वारा बदला जाना है ।${MyString}
जाने पर "यदि तर्क दिए गए ..." के लिए त्रुटियों का एक समूह होता है , जैसे कि सीमेक त्रुटि यदि: "यदि दिए गए तर्कों" के बाद परांठे, "नहीं", "समानताएं" और इसी तरह ।
if (MyString ...)
यह करना है (यदि यह आपका कोड चेतावनी दे रहा है)।
जल्दी और गंदे होने के लिए यहां कुछ बुनियादी उदाहरण हैं।
चर सेट करें:
SET(INSTALL_ETC_DIR "etc")
चर का उपयोग करें:
SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")
चर सेट करें:
SET(PROGRAM_SRCS
program.c
program_utils.c
a_lib.c
b_lib.c
config.c
)
चर का उपयोग करें:
add_executable(program "${PROGRAM_SRCS}")
if ("${MyString}" ...)
रहा हूँ तो मैं चेतावनी देख रहा हूँPolicy CMP0054 is not set: Only interpret if() arguments as variables or keywords when unquoted
:। उदाहरण के लिए, 367 बनाएँ देखें । कोई विचार?