コードがコンパイルされるオペレーティングシステムに基づいてさまざまなことを行うために、コードが必要です。私はこのようなものを探しています:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
これを行う方法はありますか?同じことをするより良い方法はありますか?
OS用の定義済みマクロサイトには、チェックの非常に完全なリストがあります。それらのいくつかを、それらが見つかった場所へのリンクとともに以下に示します。
_WIN32
32ビットと64ビットの両方_WIN64
64ビットのみ
このチェックを使用する際の落とし穴のいくつかについては、これを参照してください 関連する質問 .
unix
__unix
__unix__
__Apple__
__MACH__
両方が定義されています。いずれかのチェックが機能するはずです。
__linux__
linux
廃止(POSIX準拠ではありません)__linux
廃止(POSIX準拠ではありません)
__FreeBSD__
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
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でテスト済み:
ほとんどの場合、特定の機能が存在するかどうかを確認することをお勧めします。例:関数pipe()
が存在するかどうか。
#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
https://docs.Microsoft.com/en-us/cpp/preprocessor/predefined-macros
あなたが探していると思う:
_WIN32-コンパイルターゲットが32ビットARM、64ビットARM、x86、またはx64の場合、1として定義されます。それ以外の場合、未定義
_ WIN64-コンパイルターゲットが64ビットARMまたはx64の場合、1として定義されます。それ以外の場合、未定義。
あなたが探していると思う:
__GNUC__
__ GNUC_MINOR__
__ GNUC_PATCHLEVEL__
事前に定義された適切なコンパイラーに対してGoogleを実行します。
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/
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
外部参照で申し訳ありませんが、あなたの質問に適していると思います:
#define OSsymbol
および#ifdef OSsymbol
を使用します。OSsymbolは、ターゲットOSを識別する#define
'ableシンボルです。
通常、選択したOSシンボルを定義する中央ヘッダーファイルを含め、OS固有のインクルードおよびライブラリディレクトリを使用してコンパイルおよびビルドします。
開発環境を指定しませんでしたが、コンパイラが共通のプラットフォームとOSのグローバル定義を提供していることは間違いありません。
http://en.wikibooks.org/wiki/C_Programming/Preprocessor も参照してください
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
小さなライブラリ を作成して、使用しているオペレーティングシステムを取得します。 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のドキュメント を参照してください。
ここでは Haik の定義は見つかりませんでした。完了するために、Haiku-osの定義は簡単です__HAIKU__
プリプロセッサディレクティブ 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;
}