在 Windows 和 Linux 上编译 C++:ifdef 开关 [重复]
Posted
技术标签:
【中文标题】在 Windows 和 Linux 上编译 C++:ifdef 开关 [重复]【英文标题】:C++ compiling on Windows and Linux: ifdef switch [duplicate] 【发布时间】:2011-10-02 18:11:21 【问题描述】:我想在 Linux 和 Windows 上运行一些 c++ 代码。我只想为一个操作系统而不是另一个操作系统包含一些代码。有没有一个标准的#ifdef 曾经可以使用?
类似:
#ifdef LINUX_KEY_WORD
... // linux code goes here.
#elif WINDOWS_KEY_WORD
... // windows code goes here.
#else
#error "OS not supported!"
#endif
这个问题确实是重复的,但这里的答案要好得多,尤其是接受的那个。
【问题讨论】:
@MooingDuck:我确认我想决定目标操作系统,而不是使用的编译器。 How to detect reliably Mac OS X, ios, Linux, Windows in C preprocessor?, Detect Windows or Linux in C, C++ 【参考方案1】:你可以这样做:
#if MACRO0
//code...
#elif MACRO1
//code...
#endif
…标识符可以是:
__linux__ Defined on Linux
__sun Defined on Solaris
__FreeBSD__ Defined on FreeBSD
__NetBSD__ Defined on NetBSD
__OpenBSD__ Defined on OpenBSD
__APPLE__ Defined on Mac OS X
__hpux Defined on HP-UX
__osf__ Defined on Tru64 UNIX (formerly DEC OSF1)
__sgi Defined on Irix
_AIX Defined on AIX
_WIN32 Defined on Windows
【讨论】:
【参考方案2】:我知道这不是答案,但如果有人在 Qt 中看起来相同,则添加
在 Qt 中
https://wiki.qt.io/Get-OS-name-in-Qt
QString Get::osName()
#if defined(Q_OS_android)
return QLatin1String("android");
#elif defined(Q_OS_BLACKBERRY)
return QLatin1String("blackberry");
#elif defined(Q_OS_IOS)
return QLatin1String("ios");
#elif defined(Q_OS_MAC)
return QLatin1String("osx");
#elif defined(Q_OS_WINCE)
return QLatin1String("wince");
#elif defined(Q_OS_WIN)
return QLatin1String("windows");
#elif defined(Q_OS_LINUX)
return QLatin1String("linux");
#elif defined(Q_OS_UNIX)
return QLatin1String("unix");
#else
return QLatin1String("unknown");
#endif
【讨论】:
【参考方案3】:此响应与宏战争无关,但如果找不到匹配的平台,则会产生错误。
#ifdef LINUX_KEY_WORD
... // linux code goes here.
#elif WINDOWS_KEY_WORD
... // windows code goes here.
#else
#error Platform not supported
#endif
如果不支持#error
,您可以使用static_assert (C++0x) 关键字。或者您可以实现自定义 STATIC_ASSERT,或者只声明一个大小为 0 的数组,或者使用具有重复案例的开关。简而言之,在编译时而不是在运行时
【讨论】:
#error
必须被支持(不像#warning
是一个扩展)。但我同意这不一定是构建失败的最佳方式。
@Thomas:确实。幸运的是,如果 #error
在某些不兼容的实现中不受支持,那么不正确的预处理器语句的结果就是,嗯 --- 一个错误。如果它也不是一个错误,那么编译器就是一个REALLY REALLY蹩脚的编译器,无论如何都不值得支持(尽管我高度怀疑这样的编译器是否存在)。【参考方案4】:
这取决于使用的编译器。
例如,Windows 的定义可以是WIN32
或_WIN32
。
Linux 的定义可以是UNIX
或__unix__
或LINUX
或__linux__
。
【讨论】:
有这样一个标准。那些不遵守它的工具链,要么是错误的,要么是石器时代的,要么就是坏的。WIN32
在Windows.h
内部定义。因此,如果不包含标头,则类型开关将不起作用。 _WIN32
应该默认定义。【参考方案5】:
不,这些定义取决于编译器。您可以做什么,使用您自己的一组定义,并将它们设置在 Makefile 上。请参阅this thread 了解更多信息。
【讨论】:
正确,但没有帮助 @Cicada:当所有编译器(值得讨论)都做同样的事情时,依赖编译器就没有意义了。 然而,没有标准来定义这个,而这正是他所要求的。我正在更新答案以将其指向有关此问题的有用参考 我很高兴您建议使用 makefile 作为“编译器依赖”定义的替代方案。与使用 makefile 相比,更多的编译器使用相同的定义。 编译器不使用makefile,makefile使用编译器。【参考方案6】:这取决于编译器。如果您在 Linux 上使用 G++ 和在 Windows 上使用 VC++ 进行编译,则可以这样做:
#ifdef linux
...
#elif _WIN32
...
#else
...
#endif
【讨论】:
这总是会的。所有编译器都以相同的方式实现这一点。 linux 上的 Clang 模仿 GCC,Windows 上的 Clang 和 GCC 模仿 MSVC。 @rubenvb:所有现有编译器,方便。这种行为不是标准化的,对于一些没人使用的编译器来说也可能有所不同。【参考方案7】:使用:
#ifdef __linux__
//linux code goes here
#elif _WIN32
// windows code goes here
#else
#endif
【讨论】:
以上是关于在 Windows 和 Linux 上编译 C++:ifdef 开关 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
C++/LapackE 代码在 Windows 上编译良好,但相同的代码在 Linux 上编译失败
使用 cmake 在 windows 上编译 c++ 数据库时出错