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 命令 |
|---|---|---|---|---|---|
| Windows | MSVC | x64 | .dll + .lib | .lib | cmake .. -A x64 |
| Windows | MinGW | x64 | .dll + .dll.a | .a | cmake .. -G "MinGW Makefiles" |
| Linux | GCC (GNU) | x64 | .so | .a | cmake .. |
| macOS | Clang (LLVM) | x64/ARM | .dylib | .a | cmake .. |
| Cygwin | GCC | x64 | cygxxx.dll | .a | cmake .. |
七、你未来项目万能 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)