1 源码中通过宏来区分不同操作系统
The Predefined Macros for OS site has a very complete list of checks. Here are a few of them, with links to where they’re found:
1.1 Windows
WIN32 Both 32 bit and 64 bit
WIN64 64 bit only
__CYGWIN
1.2 Unix (Linux, *BSD, but not Mac OS X)
See this related question on some of the pitfalls of using this check.
unix
Mac OS X
APPLE Also used for classic
MACH
Both are defined; checking for either should work.
Linux
linux
linux Obsolete (not POSIX compliant)
__linux Obsolete (not POSIX compliant)
FreeBSD
Android
ANDROID
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
//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, tvOS, or watchOS Simulator
#elif TARGET_OS_MACCATALYST
// Mac's Catalyst (ports iOS API into Mac, like UIKit).
#elif TARGET_OS_IPHONE
// iOS, tvOS, or watchOS device
#elif TARGET_OS_MAC
// Other kinds of Apple platforms
#else
# error "Unknown Apple platform"
#endif
#elif __ANDROID__
// android
#elif __linux__
// linux
#elif __unix__ // all unices not caught above
// Unix
#elif defined(_POSIX_VERSION)
// POSIX
#else
# error "Unknown compiler"
#endif
需要注意:
- windows32/64平台,
__WIN32_
都会被定义,而___WIN64
只在64位windows上定义,因此要先判断_WIN64
- 所有的apple系统都会定义
__APPLE__
,包括MacOSX和iOS TARGET_IPHONE_SIMULATOR
是TARGET_OS_IPHONE
的子集,TARGET_OS_IPHONE
是TARGET_OS_MAC
的子集。也就是说iOS模拟器上会同时定义这三个宏。因此判断的时候要先判断子集。- 另外mac上可以用以下命令行获取GCC定义的预编译宏:
gcc -arch i386 -dM -E - < /dev/null | sort
(i386可替换为arm64等)
测试实例
int main()
{
//系统宏
#ifdef __ANDROID__
string port("/dev/ttyUSB1");
#elif __linux__
string port("/dev/ttyUSB0");
#elif _WIN32
string port("Com3");
#endif
//编译器宏
#ifdef _MSC_VER
cout << "hello MSVC" << endl;
#elif __GNUC__
cout << "hello gcc" << endl;
#elif __BORLANDC__
cout << "hello Borland c++" << endl;
#endif
}
以上代码在vs2019中测试没有问题。
其中ANDROID宏在安卓ndk开发时候会用到
2 在CMakeLists.txt中通过宏区分不同操作系统
cmake / CMakeLists.txt中 判断操作系统平台
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
message(STATUS "Configuring on/for Linux")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
message(STATUS "Configuring on/for macOS")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
message(STATUS "Configuring on/for Windows")
elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX")
message(STATUS "Configuring on/for IBM AIX")
else()
message(STATUS "Configuring on/for ${CMAKE_SYSTEM_NAME}")
endif()