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

unix
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

FreeBSD

Android

ANDROID

  1. #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
  2. //define something for Windows (32-bit and 64-bit, this part is common)
  3. #ifdef _WIN64
  4. //define something for Windows (64-bit only)
  5. #else
  6. //define something for Windows (32-bit only)
  7. #endif
  8. #elif __APPLE__
  9. #include <TargetConditionals.h>
  10. #if TARGET_IPHONE_SIMULATOR
  11. // iOS, tvOS, or watchOS Simulator
  12. #elif TARGET_OS_MACCATALYST
  13. // Mac's Catalyst (ports iOS API into Mac, like UIKit).
  14. #elif TARGET_OS_IPHONE
  15. // iOS, tvOS, or watchOS device
  16. #elif TARGET_OS_MAC
  17. // Other kinds of Apple platforms
  18. #else
  19. # error "Unknown Apple platform"
  20. #endif
  21. #elif __ANDROID__
  22. // android
  23. #elif __linux__
  24. // linux
  25. #elif __unix__ // all unices not caught above
  26. // Unix
  27. #elif defined(_POSIX_VERSION)
  28. // POSIX
  29. #else
  30. # error "Unknown compiler"
  31. #endif

需要注意:

  • windows32/64平台,__WIN32_都会被定义,而___WIN64只在64位windows上定义,因此要先判断_WIN64
  • 所有的apple系统都会定义 __APPLE__,包括MacOSX和iOS
  • TARGET_IPHONE_SIMULATORTARGET_OS_IPHONE的子集,
    TARGET_OS_IPHONETARGET_OS_MAC的子集。也就是说iOS模拟器上会同时定义这三个宏。因此判断的时候要先判断子集。
  • 另外mac上可以用以下命令行获取GCC定义的预编译宏:
    gcc -arch i386 -dM -E - < /dev/null | sort (i386可替换为arm64等)

测试实例

  1. int main()
  2. {
  3. //系统宏
  4. #ifdef __ANDROID__
  5. string port("/dev/ttyUSB1");
  6. #elif __linux__
  7. string port("/dev/ttyUSB0");
  8. #elif _WIN32
  9. string port("Com3");
  10. #endif
  11. //编译器宏
  12. #ifdef _MSC_VER
  13. cout << "hello MSVC" << endl;
  14. #elif __GNUC__
  15. cout << "hello gcc" << endl;
  16. #elif __BORLANDC__
  17. cout << "hello Borland c++" << endl;
  18. #endif
  19. }

以上代码在vs2019中测试没有问题。
其中ANDROID宏在安卓ndk开发时候会用到

2 在CMakeLists.txt中通过宏区分不同操作系统

cmake / CMakeLists.txt中 判断操作系统平台

  1. if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  2. message(STATUS "Configuring on/for Linux")
  3. elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  4. message(STATUS "Configuring on/for macOS")
  5. elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  6. message(STATUS "Configuring on/for Windows")
  7. elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX")
  8. message(STATUS "Configuring on/for IBM AIX")
  9. else()
  10. message(STATUS "Configuring on/for ${CMAKE_SYSTEM_NAME}")
  11. endif()