创建CMakeLists.txt文件

  • CMakeList.txt
cmake_minimum_required(VERSION 3.20)

project(demo001 LANGUAGES C)

add_executable(demo001 main.c)
  • 在相同目录下main.c
#include <stdio.h>

int main(void)
{
    printf("Hello, World!\n");
    return 0;
}
  • 构建生成文件

-S . 指定源码目录,-B build 指定构建目录(不污染源码)

-G "MinGW Makefiles" 指定生成器(Windows 下需显式指定;如果用的是 MSVC/Ninja,换成对应生成器)

# 强制使用 make
cmake -B build -G "MinGW Makefiles"
# 强制使用 make
cmake -B build -G "Unix Makefiles"
# 强制使用 ninja
cmake -B build -G "Ninja"
  • 编译

cmake --build build 等价于进入 build 目录执行 make

cmake --build build

CMake 选择编译器的优先级从高到低如下:

  1. 显式指定(最高优先级)
    • 命令行参数:-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
    • 环境变量:CC=gcc CXX=g++ cmake ..(配置阶段生效,但命令行参数优先级更高)
  2. 生成器(Generator)暗示
    • -G "MinGW Makefiles" → 自动在 PATH 中查找 MinGW 的 gcc/g++
    • -G "Visual Studio 17 2022" → 固定使用 MSVC(cl.exe),忽略环境变量
    • -G "Unix Makefiles" → 查找 gcc、clang 等常见编译器
    • -G "Ninja"→ 不绑定任何特定的编译器
  3. PATH 顺序探测 若未指定生成器或生成器不锁定特定编译器,CMake 会按 PATH 中的顺序依次尝试 gcc、clang、cl 等,找到第一个可用的即使用。
  4. 缓存复用 首次配置后,编译器路径会写入 build/CMakeCache.txt(变量 CMAKE_C_COMPILER:FILEPATH=...)。 后续重新运行 cmake ..(不清理缓存)时,CMake 不会重新探测,而是直接使用缓存中的值。
    • 若要重新探测,需删除 build 目录,或使用 -DCMAKE_C_COMPILER=... 覆盖缓存。