CMAKE में OS विशिष्ट निर्देश: कैसे करें?


108

मैं CMAKE के लिए एक शुरुआत हूं। नीचे एक सरल cmake फ़ाइल है जो mingw वातावरण की खिड़कियों में अच्छी तरह से काम करती है। समस्या स्पष्ट रूप target_link_libraries()से CMAKE के कार्य के साथ है जहां मैं libwsock32.a लिंक कर रहा हूं। खिड़कियों में यह काम करता है और मुझे परिणाम मिलते हैं।

हालाँकि, उम्मीद के मुताबिक, लिनक्स में, वह /usr/bin/ldदिखेगा -lwsock32जिसके लिए लिनक्स ओएस नहीं है।

मेरी समस्या यह है: मैं लिनक्स ओएस में wsock32 पुस्तकालय को जोड़ने से बचने के लिए CMAKE को कैसे निर्देश दे सकता हूं ???

किसी भी प्रकार की सहायता सराहनीय होगी।

मेरी सरल CMake फ़ाइल:

 PROJECT(biourl)
 set (${PROJECT_NAME}_headers ./BioSocketAddress.h  ./BioSocketBase.h ./BioSocketBuffer.h ./BioSocketCommon.h  ./BioSocketListener.h  ./BioSocketPrivate.h  ./BioSocketStream.h ./BioUrl.h BioDatabase.h )

set (${PROJECT_NAME}_sources BioSocketAddress.C  BioSocketBase.C  BioSocketCommon.C BioSocketStream.C  BioUrl.C BioDatabase.C )

add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_headers} ${${PROJECT_NAME}_sources} )

# linkers
#find_library(ws NAMES wsock32 PATHS ${PROJECT_SOURCE_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_DEFAULT_PATH)

target_link_libraries(${PROJECT_NAME} bioutils wsock32)

install (TARGETS ${PROJECT_NAME}
       RUNTIME DESTINATION bin
       LIBRARY DESTINATION lib
       ARCHIVE DESTINATION lib/archive )

जवाबों:


144

उपयोग

if (WIN32)
    #do something
endif (WIN32)

या

if (UNIX)
    #do something
endif (UNIX)

या

if (MSVC)
    #do something
endif (MSVC)

या इसी के समान

देख CMake उपयोगी चर और CMake जाँच प्लेटफार्म


सोलारिस के लिए कोई क्या उपयोग करता है?
jww

हम्म, लिंक्ड-इन पेज सहायक है, लेकिन WIN32 या UNIX का उल्लेख नहीं करता है। कोई अन्य / समान संसाधन जो हो सकता है?
rchilton1980

1
आह, यह पाया। इसमें UNIX, WIN32 और संभवतः उनके सभी "साथियों" का उल्लेख है
rchilton1980

2
@ rchilton1980: पृष्ठ स्थानांतरित, नया लिंक: gitlab.kitware.com/cmake/community/wikis/doc/cmake/…
schnaader

किसी और के लिए आश्चर्य: Per legacy, the else() and endif() commands admit an optional <condition> argument. If used, it must be a verbatim repeat of the argument of the opening if command.स्रोत: cmake.org/cmake/help/latest/command/if.html
Zyl

73

यह इस तरह का एक आम मुद्दा है, geronto- पोस्टिंग:

    if(UNIX AND NOT APPLE)
        set(LINUX TRUE)
    endif()

    # if(NOT LINUX) should work, too, if you need that
    if(LINUX) 
        message(STATUS ">>> Linux")
        # linux stuff here
    else()
        message(STATUS ">>> Not Linux")
        # stuff that should happen not on Linux 
    endif()

सीमेक बूलियन लॉजिक डॉक्स

सीएमके मंच के नाम, आदि।


9
उल्लेख करने के लिए धन्यवाद APPLE
विक्टर सर्जेनको

@VictorSergienko Всегда рад помочь :)
mlvljr

3
यूनिक्स लिंडक्स नहीं है। cmake_system_name के लिए cmake उपयोगी चर वेबसाइट से लिंक। लिनक्स मिश्रित केस ओएस डिटेक्टर का उपयोग करें
उज्ज्वल

टिबर का उत्तर बेहतर है
उज्ज्वल

1
हाँ, FreeBSD भी पास हो जाएगा (UNIX AND NOT APPLE)... और @mlvljr का लिंक बदल गया है: gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/… अब।
स्लीवेन

45

सामान्य रूप में

आप उस जैसे कई ऑपरेटिंग सिस्टम के लिए चर का पता लगा सकते हैं और निर्दिष्ट कर सकते हैं:

Microsoft Windows का पता लगाएं

if(WIN32)
    # for Windows operating system in general
endif()

या:

if(MSVC OR MSYS OR MINGW)
    # for detecting Windows compilers
endif()

Apple MacOS का पता लगाएं

if(APPLE)
    # for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
endif()

यूनिक्स और लिनक्स का पता लगाएं

if(UNIX AND NOT APPLE)
    # for Linux, BSD, Solaris, Minix
endif()

आपका विशिष्ट लिंकर मुद्दा

Windows- विशिष्ट wsock32लाइब्रेरी के साथ अपनी समस्या को हल करने के लिए , इसे अन्य प्रणालियों से हटा दें, जैसे:

if(WIN32)
    target_link_libraries(${PROJECT_NAME} bioutils wsock32)
else
    target_link_libraries(${PROJECT_NAME} bioutils)
endif()

2
सोलारिस के लिए कोई क्या उपयोग करता है?
jww

1
टाइपो: एमएसवीएस एमएसवीसी होना चाहिए। मैंने आपके लिए इसे संपादित करने की कोशिश की, लेकिन
स्टैकओवरफ़्लो

1
प्रलेखन के अनुसार, "APPLE" का तात्पर्य है, कि हम एक सेब लक्ष्य के लिए निर्माण कर रहे हैं; यानी OSX, लेकिन IOS, watchOS आदि। क्या कोई तरीका है कि OS X का विश्वसनीय तरीके से पता लगाया जाए?

@ जुलिएन यदि आप आईओएस, टीवीओएस या वॉचओएस के लिए निर्माण कर रहे हैं, तो आप सबसे अधिक संभावना एक cmake टूलकिन फ़ाइल का उपयोग करने जा रहे हैं, जिसमें किसी प्रकार का चर सेट होना चाहिए जो कि आप जो खोज रहे हैं उसे प्राप्त करने के लिए उपयोग किया जा सकता है।
मोचीसन

@ जूलियन एफडब्ल्यूआईडब्ल्यू: सीमेक प्रलेखन केवल पुष्टि करता है कि इसमें 3.10.3 के
इटमैक्सस

19

आपके पास CMAKE से कुछ विशेष शब्द हैं, एक नज़र डालें:

if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
    // do something for Linux
else
    // do something for other OS

3
मानक सीएमके तरीका: आंतरिक रूप से असंगत :) [यह एक सही / से-बिंदु का जवाब है, हालांकि]
mlvljr

खोज करने वालों के लिए, यहाँ github.com/Kitware/CMake/blob/master/Modules/…
AT

STREQUALपहले ऑपरेंड के रूप में चर (स्ट्रिंग के अलावा) को स्वीकार करता है, इसलिए यह अधिक संक्षिप्त हो सकता हैif(CMAKE_SYSTEM_NAME STREQUAL "Linux")...
विज्ञापन एन

11

जनरेटर के भाव भी संभव हैं:

target_link_libraries(
    target_name
    PUBLIC
        libA
        $<$<PLATFORM_ID:Windows>:wsock32>
    PRIVATE
        $<$<PLATFORM_ID:Linux>:libB>
        libC
)

यह विंडोज़ पर libA, wsock32 और libC को लिंक करेगा और Linux पर libA, libB & libC को लिंक करेगा

CMake जेनरेटर एक्सप्रेशन


इसके लिए धन्यवाद आप अतिरिक्त ">" जोड़ते हैं। जो "$ <$ <PLATFORM_ID: Windows>: wsock32>" है
wow2006

6

उसकी कोशिश करो:

if(WIN32)
    set(ADDITIONAL_LIBRARIES wsock32)
else()
    set(ADDITIONAL_LIBRARIES "")
endif()

target_link_libraries(${PROJECT_NAME} bioutils ${ADDITIONAL_LIBRARIES})

आप अन्य उपयोगी चर यहां पा सकते हैं ।


यह काम किया है और मैं व्यक्तिगत रूप से इस तरह से बहुत सहज है। आपका बहुत बहुत धन्यवाद।
प्रसाद

2

मैं इसे यहां छोड़ना चाहता हूं क्योंकि मैंने एंड्रॉइड एसडीके के साथ विंडोज में एंड्रॉइड के लिए संकलन करते समय इसके साथ संघर्ष किया था।

CMake TARGET और HOST प्लेटफॉर्म के बीच अंतर करता है।

मेरा लक्ष्य Android था इसलिए CMAKE_SYSTEM_NAME जैसे चरों का "Android" मान था और यहाँ अन्य उत्तर से चर WIN32 को परिभाषित नहीं किया गया था। लेकिन मैं जानना चाहता था कि क्या मेरा HOST सिस्टम Windows था क्योंकि मुझे Windows या Linux या IOs पर संकलन करते समय कुछ अलग तरीके से करने की आवश्यकता थी। ऐसा करने के लिए मैंने CMAKE_HOST_SYSTEM_NAME का उपयोग किया, जो मैंने पाया कि शायद ही कहीं भी जाना जाता है या इसका उल्लेख नहीं किया गया है क्योंकि अधिकांश लोगों के लिए TARGEt और HOST समान हैं या वे परवाह नहीं करते हैं।

आशा है कि यह कहीं किसी की मदद करता है ...


-5

जाँच करने के लिए कुछ प्रीप्रोसेसर मैक्रो का उपयोग करें यदि यह विंडोज़ या लिनक्स में है। उदाहरण के लिए

#ifdef WIN32
LIB= 
#elif __GNUC__
LIB=wsock32
#endif

शामिल -l $ (LIB) में आप कमांड का निर्माण करते हैं।

आप दोनों को अलग करने के लिए कुछ कमांड लाइन तर्क भी निर्दिष्ट कर सकते हैं।


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