मैं ओएस को प्रीप्रोसेसर निर्देश के साथ कैसे जांच सकता हूं?


195

मुझे ऑपरेटिंग सिस्टम पर आधारित विभिन्न चीजों को करने के लिए अपने कोड की आवश्यकता होती है, जिस पर यह संकलित हो जाता है। मैं कुछ इस तरह की तलाश में हूँ:

#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif

क्या इसे करने का कोई तरीका है? क्या एक ही काम करने का एक बेहतर तरीका है?



8
@ कोरी क्लेन: नहीं-नहीं। यह प्रश्न वर्षों पहले पूछा गया है
John_West 19

यह लगभग Cनहीं हैC++
ilgaar

जवाबों:


290

पूर्व-निर्धारित मैक्रो ओएस के लिए साइट की जाँच के लिए एक बहुत ही पूरी सूची है। यहां उनमें से कुछ हैं, जहां वे पाए जाते हैं, लिंक के साथ:

खिड़कियाँ

_WIN32   32 बिट और 64 बिट
_WIN64   64 बिट दोनों ही

यूनिक्स (लिनक्स, * बीएसडी, मैक ओएस एक्स)

इस चेक का उपयोग करने के कुछ नुकसानों पर संबंधित प्रश्न देखें ।

unix
__unix
__unix__

मैक ओएस एक्स

__APPLE__
__MACH__

दोनों परिभाषित हैं; या तो काम करना चाहिए।

लिनक्स

__linux__
linux अप्रचलित (POSIX आज्ञाकारी नहीं)
__linuxअप्रचलित (POSIX आज्ञाकारी नहीं)

FreeBSD

__FreeBSD__

एंड्रॉयड

__ANDROID__


1
दी गई इस साइट में iOS शामिल नहीं है, इसलिए यह iOS और OS X के बीच अंतर करने में सक्षम नहीं है।
गैरी माकिन

2
मैक ओएस परिभाषित नहीं करता है __unix__। आप इसे सूची में क्यों शामिल करेंगे?
विक्टर सर्जेनको

1
cpp -dM / dev / null आपको स्थापित gcc के आपके संस्करण पर सभी gcc पूर्वनिर्धारित मैक्रो की सूची देगा
katta

1
साइगविन unixप्रतीकों को परिभाषित करता है और win32लोगों को परिभाषित नहीं करता है, इसलिए सावधान रहें। OTOH यह परिभाषित करता है __CYGWIN__
डेविड

के __linux__रूप में ही है __ANDROID__??
कोई नहीं

72

शो GCC विंडोज पर परिभाषित करता है:

gcc -dM -E - <NUL:

लिनक्स पर:

gcc -dM -E - </dev/null

MinGW में पूर्वनिर्धारित मैक्रो:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

UNIXes पर:

unix __unix__ __unix

1
विंडोज और यूनिक्स केवल OSes नहीं हैं
fuclv

35

Nadeausoftware और लैम्ब्डा फेयरी के जवाब के आधार पर ।

#include <stdio.h>

/**
 * Determination a platform of an operation system
 * Fully supported supported only GNU GCC/G++, partially on Clang/LLVM
 */

#if defined(_WIN32)
    #define PLATFORM_NAME "windows" // Windows
#elif defined(_WIN64)
    #define PLATFORM_NAME "windows" // Windows
#elif defined(__CYGWIN__) && !defined(_WIN32)
    #define PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window)
#elif defined(__ANDROID__)
    #define PLATFORM_NAME "android" // Android (implies Linux, so it must come first)
#elif defined(__linux__)
    #define PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other
#elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__)
    #include <sys/param.h>
    #if defined(BSD)
        #define PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD
    #endif
#elif defined(__hpux)
    #define PLATFORM_NAME "hp-ux" // HP-UX
#elif defined(_AIX)
    #define PLATFORM_NAME "aix" // IBM AIX
#elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
    #include <TargetConditionals.h>
    #if TARGET_IPHONE_SIMULATOR == 1
        #define PLATFORM_NAME "ios" // Apple iOS
    #elif TARGET_OS_IPHONE == 1
        #define PLATFORM_NAME "ios" // Apple iOS
    #elif TARGET_OS_MAC == 1
        #define PLATFORM_NAME "osx" // Apple OSX
    #endif
#elif defined(__sun) && defined(__SVR4)
    #define PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana
#else
    #define PLATFORM_NAME NULL
#endif

// Return a name of platform, if determined, otherwise - an empty string
const char *get_platform_name() {
    return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME;
}

int main(int argc, char *argv[]) {
    puts(get_platform_name());
    return 0;
}

GCC के साथ परीक्षण किया गया और इस पर अड़े रहे:

  • डेबियन 8
  • विंडोज (MinGW)
  • विंडोज (साइगविन)

प्रिय @MD XF, कृपया अपने विंडोज,
मिनगडब्ल्यू

विंडोज 7 एंटरप्राइज 6.1.7601। साइगविन 2.7.0-1। मुझे MinGW संस्करण नहीं मिल रहा है लेकिन मैंने इसे कल डाउनलोड किया।
एमडी एक्सएफ

आपको संभवतः जागरूक किया जाना चाहिए - यह कार्यक्रम मानक सी है, इसलिए इसे सभी आज्ञाकारी प्रणालियों पर काम करना चाहिए।
एमडी एक्सएफ

प्रिय @MD XF, इस जानकारी के लिए धन्यवाद। मैंने आपको इस उत्तर के शीर्ष पर योगदानकर्ता के रूप में जोड़ा।
PADYMKO

10

ज्यादातर मामलों में यह जांचना बेहतर है कि क्या दी गई कार्यक्षमता मौजूद है या नहीं। उदाहरण के लिए: यदि फ़ंक्शन pipe()मौजूद है या नहीं।


3
यदि कोई फ़ंक्शन परिभाषित है, तो यह देखने का एक आसान तरीका है?
हयालसी

1
यदि आप autoconfig का उपयोग कर रहे हैं, तो आप AC_CHECK_FUNCS () के साथ फ़ंक्शन की जांच कर सकते हैं। AC_CHECK_FUNCS (पाइप sqrt) फ़ंक्शन उपलब्ध होने पर HAVE_PIPE और HAVE_SQRT को परिभाषित करेगा। मुझे नहीं पता कि यह अन्य निर्माण उपकरणों के साथ कैसे है, लेकिन मुझे लगता है कि वे भी इस तरह से समर्थन करते हैं।
क्विनमार्स

@MDXF C ++ 17 के अनुसार, __has_include है। मुझे नहीं लगता कि यह अभी तक सी में मानकीकृत है, लेकिन सभी प्रमुख कंपाइलर (जीसीसी, क्लैंग, आईसीसी, एमएसवीसी) इसे सी-मोड में भी विक्रेता-विशिष्ट एक्सटेंशन के रूप में लागू करते हैं।
अलकारो


5

Microsoft C / C ++ कंपाइलर (MSVC) पूर्वनिर्धारित मैक्रोज़ यहां मिल सकते हैं

मुझे लगता है कि आप देख रहे हैं:

  • _WIN32- संकलन लक्ष्य 32-बिट एआरएम, 64-बिट एआरएम, x86, या x64 होने पर 1 के रूप में परिभाषित किया गया। अन्यथा, अपरिभाषित
  • _WIN64- संकलन लक्ष्य 64-बिट एआरएम या x64 होने पर 1 के रूप में परिभाषित किया गया। अन्यथा, अपरिभाषित।

gcc संकलक PreDefined MAcros यहाँ पाया जा सकता है

मुझे लगता है कि आप देख रहे हैं:

  • __GNUC__
  • __GNUC_MINOR__
  • __GNUC_PATCHLEVEL__

पूर्व-परिभाषित अपने उपयुक्त संकलक के लिए एक Google करें।


4

कोई मानक मैक्रो नहीं है जो C मानक के अनुसार सेट किया गया है। कुछ C कंपाइलर कुछ प्लेटफ़ॉर्म पर सेट करेंगे (जैसे Apple के पैच किए गए GCC ने यह इंगित करने के लिए एक मैक्रो सेट किया है कि यह Apple सिस्टम पर और डार्विन प्लेटफॉर्म के लिए संकलन है)। आपका प्लेटफ़ॉर्म और / या आपका सी कंपाइलर कुछ भी सेट कर सकता है, लेकिन कोई सामान्य तरीका नहीं है।

जैसे हायालसी ने कहा, इन मैक्रों को किसी तरह अपनी निर्माण प्रक्रिया में सेट करना सबसे अच्छा है। कोड को संशोधित किए बिना अधिकांश संकलक के साथ एक मैक्रो को परिभाषित करना आसान है। आप बस -D MACROजीसीसी को पास कर सकते हैं , अर्थात

gcc -D Windows
gcc -D UNIX

और आपके कोड में:

#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
#    error Unsupported operating system
#endif

4

MinGW पर, _WIN32परिभाषित चेक काम नहीं कर रहा है। यहाँ एक समाधान है:

#if defined(_WIN32) || defined(__CYGWIN__)
    // Windows (x86 or x64)
    // ...
#elif defined(__linux__)
    // Linux
    // ...
#elif defined(__APPLE__) && defined(__MACH__)
    // Mac OS
    // ...
#elif defined(unix) || defined(__unix__) || defined(__unix)
    // Unix like OS
    // ...
#else
    #error Unknown environment!
#endif

अधिक जानकारी के लिए कृपया देखें: https://sourceforge.net/p/predef/wiki/OperatingSystems/


3
बढ़िया लिंक। ---
एमडी एक्सएफ

2

उपयोग करें #define OSsymbolऔर #ifdef OSsymbol जहां OSsymbol एक #define'सक्षम प्रतीक है जो आपके लक्ष्य OS की पहचान करता है।

आमतौर पर आप चयनित ओएस प्रतीक को परिभाषित करने वाली एक केंद्रीय हेडर फ़ाइल शामिल करते हैं और संकलन और निर्माण के लिए ओएस-विशिष्ट शामिल और पुस्तकालय निर्देशिका का उपयोग करते हैं।

आपने अपने विकास के वातावरण को निर्दिष्ट नहीं किया है, लेकिन मुझे पूरा यकीन है कि आपका संकलक सामान्य प्लेटफार्मों और OSes के लिए वैश्विक परिभाषित करता है।

Http://en.wikibooks.org/wiki/C_Programming/Preprocessor भी देखें


2

2

बाहरी संदर्भ के लिए क्षमा करें, लेकिन मुझे लगता है कि यह आपके प्रश्न के अनुकूल है:

C / C ++ टिप: कंपाइलर पूर्वनिर्धारित मैक्रो का उपयोग करके ऑपरेटिंग सिस्टम प्रकार का पता कैसे लगाएं


1
उस मेटा पोस्ट को हटा दिया गया था। मजेदार कि मॉडरेशन के कारणों के लिए हटाए गए पदों के बारे में एक मेटा पोस्ट मॉडरेशन के कारणों के लिए हटा दिया गया था।
एमडी एक्सएफ

:) हाँ। बिलकुल पागल
bruziuz

2

आप Boost.Predefओएस ( BOOST_OS_*) सहित लक्ष्य प्लेटफ़ॉर्म के लिए विभिन्न पूर्वनिर्धारित मैक्रोज़ का उपयोग कर सकते हैं । हाँ बढ़ावा को अक्सर C ++ लाइब्रेरी के रूप में माना जाता है, लेकिन यह एक प्रीप्रोसेसर हेडर है जो C के साथ भी काम करता है!

यह लायब्रेरी सूचना, C, C ++, ऑब्जेक्टिव C, और ऑब्जेक्टिव C ++ और पूर्ववर्ती मैक्रो या आम तौर पर उपलब्ध हेडर में परिभाषित लोगों को इकट्ठा कर सकने वाली जानकारी से संकलक, आर्किटेक्चर, ऑपरेटिंग सिस्टम, लाइब्रेरी और अन्य संस्करण संख्याओं के समूह को परिभाषित करती है। इस लाइब्रेरी के लिए विचार बूस्ट कॉन्फिगरेशन लाइब्रेरी का विस्तार करने के प्रस्ताव से बाहर हो गया, जो कि अधिक परिभाषाओं और सूचनाओं का समर्थन करता है। इस संक्षिप्त प्रस्ताव का एक संपादित संस्करण निम्नलिखित है।

उदाहरण के लिए

#include <boost/predef.h>

#if defined(BOOST_OS_WINDOWS)
#elif defined(BOOST_OS_ANDROID)
#elif defined(BOOST_OS_LINUX)
#elif defined(BOOST_OS_BSD)
#elif defined(BOOST_OS_AIX)
#elif defined(BOOST_OS_HAIKU)
...
#endif

पूरी सूची ऑपरेटिंग सिस्टम मैक्रोज़ में पाई जा सकती हैBOOST_OS


1

मुझे यहां हाइकु की परिभाषा नहीं मिली । पूर्ण होने के लिए हाइकु-ओएस परिभाषा सरल है__HAIKU__


0

कुछ कंपाइलर #defines जेनरेट करेंगे जो आपकी मदद कर सकते हैं। वे क्या हैं, यह निर्धारित करने के लिए कंपाइलर प्रलेखन पढ़ें। MSVC एक को परिभाषित करता है __WIN32__, GCC कुछ है जिसे आप देख सकते हैंtouch foo.h; gcc -dM foo.h


1
gcc: error: अपरिचित कमांड लाइन विकल्प '--show-defines' gcc: घातक त्रुटि: कोई इनपुट फाइल संकलन समाप्त नहीं हुआ।
सेबी 2020

0

आप पूर्व-प्रोसेसर निर्देशों का उपयोग चेतावनी या त्रुटि के रूप में कर सकते हैं ताकि आप इस कार्यक्रम को चलाने की आवश्यकता न समझें

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
    #error Windows_OS
#elif defined(__linux__)
    #error Linux_OS
#elif defined(__APPLE__) && defined(__MACH__)
    #error Mach_OS
#elif defined(unix) || defined(__unix__) || defined(__unix)
    #error Unix_OS
#else
    #error Unknown_OS
#endif

#include <stdio.h>
int main(void)
{
    return 0;
}

0

मैंने आपके द्वारा संचालित ऑपरेटिंग सिस्टम को प्राप्त करने के लिए एक छोटी सी लाइब्रेरी लिखी है , इसे क्लिब (सी पैकेज मैनेजर) का उपयोग करके स्थापित किया जा सकता है , इसलिए इसे अपनी परियोजनाओं के लिए निर्भरता के रूप में उपयोग करना वास्तव में सरल है।

इंस्टॉल

$ clib install abranhe/os.c

प्रयोग

#include <stdio.h>
#include "os.h"

int main()
{
    printf("%s\n", operating_system());
    // macOS
    return 0;
}

यह char*आपके द्वारा उपयोग किए जा रहे ऑपरेटिंग सिस्टम के नाम के साथ एक स्ट्रिंग ( ) लौटाता है , इस परियोजना के बारे में अधिक जानकारी के लिए इसे गितुब पर प्रलेखन देखें

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