web-dev-qa-db-ja.com

CプリプロセッサでMac OS X、iOS、Linux、Windowsを確実に検出する方法

Mac OS X、iOS、Linux、WindowsでクロスプラットフォームのC/C++コードをコンパイルする必要がある場合、プリプロセッサプロセス中にそれらを確実に検出するにはどうすればよいですか。

286
Eonil

ほとんどのコンパイラで使用される定義済みマクロがあります。リスト here を見つけることができます。 GCCコンパイラの定義済みマクロは、 here にあります。 gccの例を次に示します。

#ifdef _WIN32
   //define something for Windows (32-bit and 64-bit, this part is common)
   #ifdef _WIN64
      //define something for Windows (64-bit only)
   #else
      //define something for Windows (32-bit only)
   #endif
#Elif __Apple__
    #include "TargetConditionals.h"
    #if TARGET_IPHONE_SIMULATOR
         // iOS Simulator
    #Elif TARGET_OS_IPHONE
        // iOS device
    #Elif TARGET_OS_MAC
        // Other kinds of Mac OS
    #else
    #   error "Unknown Apple platform"
    #endif
#Elif __linux__
    // linux
#Elif __unix__ // all unices not caught above
    // Unix
#Elif defined(_POSIX_VERSION)
    // POSIX
#else
#   error "Unknown compiler"
#endif

定義されたマクロは、使用するコンパイラに依存します。

_WIN64#ifdef_WIN32#ifdefにネストできます。これは、x86バージョンだけでなく、Windowsをターゲットにするときに_WIN32が定義されているためです。これにより、一部のインクルードが両方に共通している場合、コードの重複が防止されます。

466
Evgeny Gavrin

Jakeが指摘するように、TARGET_IPHONE_SIMULATORはTARGET_OS_IPHONEのサブセットです。

また、TARGET_OS_IPHONEはTARGET_OS_MACのサブセットです。

そのため、もっと良い方法があります。

#ifdef _WIN64
   //define something for Windows (64-bit)
#Elif _WIN32
   //define something for Windows (32-bit)
#Elif __Apple__
    #include "TargetConditionals.h"
    #if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
        // define something for simulator   
    #Elif TARGET_OS_IPHONE
        // define something for iphone  
    #else
        #define TARGET_OS_OSX 1
        // define something for OSX
    #endif
#Elif __linux
    // linux
#Elif __unix // all unices not caught above
    // Unix
#Elif __posix
    // POSIX
#endif
29
PatchyFog

当然の答えの種類: [このサイト] の人々は全てのOS /コンパイラのペアに対して定義されたマクロの表を作るのに時間がかかりました

たとえば、_WIN32はCygwin(POSIX)を使用したWindowsでは定義されていませんが、ISはWindows、Cygwin(非POSIX)、MinGWで使用できます(Clang、 GNU、Intelなど).

とにかく、私はテーブルが非常に有益であることがわかり、ここで共有したいと思いました。

5
houtanb