web-dev-qa-db-ja.com

プリプロセッサディレクティブでOSを確認するにはどうすればよいですか?

コードがコンパイルされるオペレーティングシステムに基づいてさまざまなことを行うために、コードが必要です。私はこのようなものを探しています:

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

これを行う方法はありますか?同じことをするより良い方法はありますか?

164
perimosocordiae

OS用の定義済みマクロサイトには、チェックの非常に完全なリストがあります。それらのいくつかを、それらが見つかった場所へのリンクとともに以下に示します。

Windows

_WIN32 32ビットと64ビットの両方
_WIN64 64ビットのみ

Unix(Linux、* BSD、Mac OS X)

このチェックを使用する際の落とし穴のいくつかについては、これを参照してください 関連する質問 .

unix
__unix
__unix__

Mac OS X

__Apple__
__MACH__

両方が定義されています。いずれかのチェックが機能するはずです。

Linux

__linux__
linux廃止(POSIX準拠ではありません)
__linux廃止(POSIX準拠ではありません)

FreeBSD

__FreeBSD__

239
Lambda Fairy

windowsでGCCが定義するものを示します。

gcc -dM -E - <NUL:

linuxの場合:

gcc -dM -E - </dev/null

MinGWの事前定義マクロ:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

uNIXの場合:

unix __unix__ __unix
63
qwer

nadeausoftware および Lambda Fairy's answer に基づきます。

#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およびclangでテスト済み:

  • Debian 8
  • Windows(MinGW)
  • Windows(Cygwin)
24
Seti Volkylany

ほとんどの場合、特定の機能が存在するかどうかを確認することをお勧めします。例:関数pipe()が存在するかどうか。

10
quinmars
#ifdef _WIN32
// do something for windows like include <windows.h>
#Elif defined __unix__
// do something for unix like include <unistd.h>
#Elif defined __Apple__
// do something for mac
#endif
7

Microsoft C/C++コンパイラ(MSVC)の定義済みマクロは、次の場所にあります。

https://docs.Microsoft.com/en-us/cpp/preprocessor/predefined-macros

あなたが探していると思う:

_WIN32-コンパイルターゲットが32ビットARM、64ビットARM、x86、またはx64の場合、1として定義されます。それ以外の場合、未定義
_ WIN64-コンパイルターゲットが64ビットARMまたはx64の場合、1として定義されます。それ以外の場合、未定義。

gccコンパイラーの事前定義されたマクロは、次の場所にあります。

http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html

あなたが探していると思う:

__GNUC__
__ GNUC_MINOR__
__ GNUC_PATCHLEVEL__

事前に定義された適切なコンパイラーに対してGoogleを実行します。

5
Martin York

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
anakod

C標準に従って設定される標準マクロはありません。一部のCコンパイラは、一部のプラットフォームで設定します(たとえば、Appleのパッチを適用したGCCは、AppleシステムおよびDarwinプラットフォームでコンパイルしていることを示すマクロを設定します)。プラットフォームやCコンパイラで何かを設定することもありますが、一般的な方法はありません。

Hayalciが言ったように、これらのマクロはビルドプロセスで何らかの形で設定するのが最善です。コードを変更せずに、ほとんどのコンパイラでマクロを簡単に定義できます。 -D MACROをGCCに単純に渡すことができます。

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
3
Mecki

外部参照で申し訳ありませんが、あなたの質問に適していると思います:

C/C++のヒント:コンパイラーの定義済みマクロを使用してオペレーティングシステムの種類を検出する方法

2
bruziuz
2
MD XF

#define OSsymbolおよび#ifdef OSsymbolを使用します。OSsymbolは、ターゲットOSを識別する#define 'ableシンボルです。

通常、選択したOSシンボルを定義する中央ヘッダーファイルを含め、OS固有のインクルードおよびライブラリディレクトリを使用してコンパイルおよびビルドします。

開発環境を指定しませんでしたが、コンパイラが共通のプラットフォームとOSのグローバル定義を提供していることは間違いありません。

http://en.wikibooks.org/wiki/C_Programming/Preprocessor も参照してください

2
devio

一部のコンパイラは、これに役立つ#definesを生成します。コンパイラのドキュメントを読んで、それらが何であるかを判断してください。 MSVC__WIN32__であるものを定義します、 GCCtouch foo.h; gcc -dM foo.hで確認できるものがあります

1
davenpcj

Boost.Predef を使用できます。これには、OSを含むターゲットプラットフォーム用のさまざまな定義済みマクロが含まれます。はい、boostはC++ライブラリとよく考えられますが、これはCでも機能するプリプロセッサヘッダーです

このライブラリは、C、C++、Objective C、およびObjective C++の事前定義マクロまたは一般的に利用可能なヘッダーで定義されたマクロの収集可能な情報から、コンパイラ、アーキテクチャ、オペレーティングシステム、ライブラリ、およびその他のバージョン番号のセットを定義します。このライブラリのアイデアは、Boost Configライブラリを拡張して、サポートする機能定義よりも多くの一貫した情報を提供するという提案から生まれました。以下は、その簡単な提案の編集版です。

例えば

#include <boost/predef.h>

#if defined(BOOST_OS_WINDOWS)
#Elif defined(BOOST_OS_Android)
#Elif defined(BOOST_OS_LINUX)
#Elif defined(BOOST_OS_BSD)
...
#endif
0
phuclv

小さなライブラリ を作成して、使用しているオペレーティングシステムを取得します。 clib (Cパッケージマネージャ)を使用してインストールできるため、次のように使用するのは本当に簡単です。プロジェクトの依存関係。

インストール

$ clib install abranhe/os.c

使用法

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

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

使用しているオペレーティングシステムの名前を含む文字列(char*)を返します。このプロジェクトの詳細については、 Githubのドキュメント を参照してください。

0

ここでは Haik の定義は見つかりませんでした。完了するために、Haiku-osの定義は簡単です__HAIKU__

0
TadejP

プリプロセッサディレクティブ as warningまたはerrorを使用して、コンパイル時にチェックできますrunこのプログラムはまったく必要ありませんcompile it。

#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
HaSeeB MiR