CMake 判断 平台 / 编译器 / 位数 的使用

CMake 跨平台配置
Windows / Linux / macOS
x86 / x64
MSVC / MinGW / Cygwin / Clang(LLVM) / GCC(GNU)
静态库 / 动态库


先记住一句终极真理(90% 坑都来自这里)

编译器 必须 === 平台 必须 === 位数 必须 === 库类型

不能混搭!

  • MSVC 库 ≠ MinGW 库
  • x86 ≠ x64
  • 静态库 ≠ 动态库
  • Debug ≠ Release

一、CMake 判断 平台 / 编译器 / 位数(万能模板)

先给你一段任何项目都能放开头的 CMake 检测代码:

cmake_minimum_required(VERSION 3.20)
project(MyApp)

# 1. 判断操作系统
if(WIN32)
    message("系统: Windows")
elseif(UNIX AND NOT APPLE)
    message("系统: Linux")
elseif(APPLE)
    message("系统: macOS")
endif()

# 2. 判断编译器
if(MSVC)
    message("编译器: MSVC (cl.exe)")
elseif(MINGW)
    message("编译器: MinGW (GCC for Windows)")
elseif(CYGWIN)
    message("编译器: Cygwin")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    message("编译器: Clang (LLVM)")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    message("编译器: GCC (GNU)")
endif()

# 3. 判断位数 x86 / x64
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    message("架构: x64 (64位)")
else()
    message("架构: x86 (32位)")
endif()

你运行 cmake .. 就能看到当前环境。


二、所有组合的 CMake 完整配置(直接复制用)

组合 1:Windows + MSVC + x64 + 动态库(最常用)

环境:VS2019/2022,cl.exe

cmake_minimum_required(VERSION 3.20)
project(MyApp)
set(CMAKE_CXX_STANDARD 17)

# MSVC 编译动态库必须加这个
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

# 1. 生成动态库
add_library(MyLib SHARED src/mylib.cpp)

# 2. 生成可执行文件
add_executable(MyApp src/main.cpp)

# 3. 链接动态库
target_link_libraries(MyApp MyLib)

构建命令(x64):

cmake .. -A x64
cmake --build . --config Release

生成:

MyApp.exe
MyLib.dll
MyLib.lib

组合 2:Windows + MSVC + x64 + 静态库

add_library(MyLib STATIC src/mylib.cpp)  # 只要把 SHARED 改成 STATIC
add_executable(MyApp src/main.cpp)
target_link_libraries(MyApp MyLib)

生成:

MyApp.exe
MyLib.lib  # 静态库,直接打包进 exe

组合 3:Windows + MinGW + x64 + 动态库

MinGW 就是 Windows 上的 GCC

cmake_minimum_required(VERSION 3.20)
project(MyApp)
set(CMAKE_CXX_STANDARD 17)

add_library(MyLib SHARED src/mylib.cpp)
add_executable(MyApp src/main.cpp)
target_link_libraries(MyApp MyLib)

构建命令(必须指定 MinGW 生成器):

cmake .. -G "MinGW Makefiles"
mingw32-make

生成:

MyApp.exe
libMyLib.dll
libMyLib.dll.a

组合 4:Windows + MinGW + x64 + 静态库

add_library(MyLib STATIC src/mylib.cpp)
add_executable(MyApp src/main.cpp)
target_link_libraries(MyApp MyLib)

生成:

MyApp.exe
libMyLib.a

组合 5:Linux + GCC + x64 + 动态库

add_library(MyLib SHARED src/mylib.cpp)
add_executable(MyApp src/main.cpp)
target_link_libraries(MyApp MyLib)

构建:

cmake ..
make

生成:

MyApp
libMyLib.so

组合 6:Linux + GCC + x64 + 静态库

add_library(MyLib STATIC src/mylib.cpp)

生成:

MyApp
libMyLib.a

组合 7:macOS + Clang(LLVM) + x64/ARM + 动态库

add_library(MyLib SHARED src/mylib.cpp)
add_executable(MyApp src/main.cpp)
target_link_libraries(MyApp MyLib)

生成:

MyApp
libMyLib.dylib

组合 8:macOS + Clang + 静态库

add_library(MyLib STATIC src/mylib.cpp)

生成:

libMyLib.a

组合 9:Cygwin + GCC

add_library(MyLib SHARED src/mylib.cpp)

生成:

cygMyLib.dll

三、CMake 如何强制指定编译器?(超级重要)

你可以不依赖系统默认,直接指定用什么编译器:

1. 强制用 MSVC(VS)

Windows 自动默认

2. 强制用 MinGW

cmake .. -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER=g++

3. 强制用 Clang

cmake .. -DCMAKE_CXX_COMPILER=clang++

4. 强制用 GCC

cmake .. -DCMAKE_CXX_COMPILER=g++

四、CMake 强制指定 x86 / x64

Windows(MSVC)

# x64
cmake .. -A x64

# x86
cmake .. -A Win32

Linux/macOS

# x64(默认)
cmake ..

# x86
cmake .. -DCMAKE_CXX_FLAGS="-m32"

五、静态库 / 动态库 一句话区别(CMake 版)

SHARED = 动态库(运行时需要)
STATIC = 静态库(编译打包进 exe)

Windows

  • 动态:.dll + .lib
  • 静态:.lib

Linux

  • 动态:.so
  • 静态:.a

macOS

  • 动态:.dylib
  • 静态:.a

MinGW

  • 动态:.dll + .dll.a
  • 静态:.a

六、我把所有差异浓缩成一张表(你存这张就够)

平台编译器架构动态库名静态库名CMake 命令
WindowsMSVCx64.dll + .lib.libcmake .. -A x64
WindowsMinGWx64.dll + .dll.a.acmake .. -G "MinGW Makefiles"
LinuxGCC (GNU)x64.so.acmake ..
macOSClang (LLVM)x64/ARM.dylib.acmake ..
CygwinGCCx64cygxxx.dll.acmake ..

七、你未来项目万能 CMake 模板(最终版)

cmake_minimum_required(VERSION 3.20)
project(MyProject)
set(CMAKE_CXX_STANDARD 17)

# 自动判断平台
if(WIN32)
    set(PLATFORM_WINDOWS 1)
elseif(UNIX AND NOT APPLE)
    set(PLATFORM_LINUX 1)
elseif(APPLE)
    set(PLATFORM_MAC 1)
endif()

# 自动判断编译器
if(MSVC)
    add_compile_options("/W4")
elseif(MINGW)
    add_compile_options("-Wall")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    add_compile_options("-Wall -Wextra")
endif()

# 生成库(可切换静态/动态)
add_library(MyLib STATIC src/mylib.cpp)
# add_library(MyLib SHARED src/mylib.cpp)

# 生成可执行文件
add_executable(MyApp src/main.cpp)
target_link_libraries(MyApp MyLib)