コードがコンパイルされるオペレーティングシステムに基づいて、さまざまなことを行うためにコードが必要です。私はこのようなものを探しています:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
これを行う方法はありますか?同じことをするより良い方法はありますか?
C
ではないC++
コードがコンパイルされるオペレーティングシステムに基づいて、さまざまなことを行うためにコードが必要です。私はこのようなものを探しています:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
これを行う方法はありますか?同じことをするより良い方法はありますか?
C
ではないC++
回答:
OSサイトの事前定義マクロには、チェックの完全なリストがあります。それらのいくつかを、それらが見つかった場所へのリンクとともに以下に示します。
_WIN32
32ビットと64ビットの両方
_WIN64
64ビットのみ
このチェックを使用する際のいくつかの落とし穴については、この関連質問を参照してください。
unix
__unix
__unix__
__APPLE__
__MACH__
両方が定義されています。どちらかをチェックするとうまくいくはずです。
__linux__
linux
廃止(POSIX準拠ではありません)
__linux
廃止(POSIX準拠ではありません)
__FreeBSD__
__ANDROID__
__unix__
。なぜあなたはそれをリストに含めますか?
unix
シンボルを定義し、シンボルを定義しないwin32
ので、注意してください。OTOH定義します__CYGWIN__
。
__linux__
同じ__ANDROID__
ですか?
nadeausoftwareとLambda Fairyの回答に基づいています。
#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
私はあなたが探していると思います:
_WIN32
-コンパイルターゲットが32ビットARM、64ビットARM、x86、またはx64の場合、1として定義されます。それ以外の場合、未定義_WIN64
-コンパイルターゲットが64ビットARMまたはx64の場合、1として定義されます。それ以外の場合、未定義です。
私はあなたが探していると思います:
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
事前に定義された適切なコンパイラに対してグーグルを実行します。
C標準に従って設定された標準マクロはありません。一部のCコンパイラは、一部のプラットフォームで1を設定します(たとえば、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
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/をご覧ください。
OSsymbolが使用され#define OSsymbol
ている#ifdef OSsymbol
場所#define
ターゲットOSを特定する」ことができ、シンボル。
通常は、選択したOSシンボルを定義する中央のヘッダーファイルをインクルードし、OS固有のインクルードおよびライブラリディレクトリを使用してコンパイルおよびビルドします。
開発環境を指定していませんが、コンパイラが一般的なプラットフォームとOSのグローバル定義を提供していると確信しています。
http://en.wikibooks.org/wiki/C_Programming/Preprocessorも参照してください
外部参照については申し訳ありませんが、私はあなたの質問に適していると思います:
にBoost.Predef
は、OS(BOOST_OS_*
)を含むターゲットプラットフォーム用のさまざまな定義済みマクロが含まれています。はい、ブーストは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)
#elif defined(BOOST_OS_AIX)
#elif defined(BOOST_OS_HAIKU)
...
#endif
完全なリストは、BOOST_OS
オペレーティングシステムマクロにあります。
プリプロセッサディレクティブを警告またはエラーとして使用して、コンパイル時にチェックすることができます。このプログラムを実行する必要はなく、単にコンパイルするだけです。
#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;
}
私はあなたが使っているオペレーティングシステムを得るために小さなライブラリを書きました、それは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のドキュメントをご覧ください。