> For the complete documentation index, see [llms.txt](https://chenxiaowei.gitbook.io/cmake-cookbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chenxiaowei.gitbook.io/cmake-cookbook/2.0-chinese/2.1-chinese.md).

# 2.1 检测操作系统

**NOTE**:*此示例代码可以在* <https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-02/recipe-01> *中找到。该示例在CMake 3.5版(或更高版本)中是有效的，并且已经在GNU/Linux、macOS和Windows上进行过测试。*

CMake是一组跨平台工具。不过，了解操作系统(OS)上执行配置或构建步骤也很重要。从而与操作系统相关的CMake代码，会根据操作系统启用条件编译，或者在可用或必要时使用特定于编译器的扩展。本示例中，我们将通过一个不需要编译任何源代码的示例，演示如何使用CMake检测操作系统。为了简单起见，我们只考虑配置过程。

## 具体实施

我们将用一个非常简单的`CMakeLists.txt`进行演示:

1. 首先，定义CMake最低版本和项目名称。请注意，语言是`NONE`:

   ```
   cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
   project(recipe-01 LANGUAGES NONE)
   ```
2. 然后，根据检测到的操作系统信息打印消息:

   ```
   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()
   ```

   测试之前，检查前面的代码块，并考虑相应系统上的具体行为。
3. 现在，测试配置项目:

   ```
   $ mkdir -p build
   $ cd build
   $ cmake ..
   ```
4. 关于CMake输出，这里有一行很有趣——在Linux系统上(在其他系统上，输出会不同):

   ```
   -- Configuring on/for Linux
   ```

## 工作原理

CMake为目标操作系统定义了`CMAKE_SYSTEM_NAME`，因此不需要使用定制命令、工具或脚本来查询此信息。然后，可以使用此变量的值实现特定于操作系统的条件和解决方案。在具有`uname`命令的系统上，将此变量设置为`uname -s`的输出。该变量在macOS上设置为“Darwin”。在Linux和Windows上，它分别计算为“Linux”和“Windows”。我们了解了如何在特定的操作系统上执行特定的CMake代码。当然，应该尽量减少这种定制化行为，以便简化迁移到新平台的过程。

**NOTE**:*为了最小化从一个平台转移到另一个平台时的成本，应该避免直接使用Shell命令，还应该避免显式的路径分隔符(Linux和macOS上的前斜杠和Windows上的后斜杠)。CMake代码中只使用前斜杠作为路径分隔符，CMake将自动将它们转换为所涉及的操作系统环境。*
