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 _WIN32string port("Com3");#endif//编译器宏#ifdef _MSC_VERcout << "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()
