输入关键词开始搜索

CMake 入门

最小 CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(MyApp VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(myapp main.cpp)

构建三步:

mkdir build && cd build
cmake ..         # 生成构建系统
cmake --build .  # 编译

target 管理(Modern CMake 核心)

# 可执行文件
add_executable(myapp main.cpp)

# 静态库
add_library(mylib STATIC src/lib.cpp)

# 动态库
add_library(mylib SHARED src/lib.cpp)

# 头文件库(header-only)
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE include/)

# 关键:全部用 target_* 命令,不用全局 set
target_include_directories(myapp PRIVATE include/)
target_link_libraries(myapp PRIVATE mylib)
target_compile_definitions(myapp PRIVATE VERSION="1.0")
target_compile_options(myapp PRIVATE -Wall -Wextra)

PRIVATE / PUBLIC / INTERFACE

关键字自己用依赖者也用场景
PRIVATE内部实现细节
PUBLIC头文件也需要的
INTERFACEheader-only 库
# mylib 的头文件里用了 Qt::Core → 依赖者也必须能 include Qt
target_link_libraries(mylib PUBLIC Qt6::Core)

# mylib.cpp 里用了 boost → 只有 mylib 需要链接
target_link_libraries(mylib PRIVATE Boost::filesystem)

多目录项目

myapp/
├── CMakeLists.txt
├── src/
│   ├── CMakeLists.txt
│   └── main.cpp
└── lib/
    ├── CMakeLists.txt
    └── mylib.cpp
# 根 CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(MyApp)
add_subdirectory(lib)
add_subdirectory(src)

# lib/CMakeLists.txt
add_library(mylib mylib.cpp)
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

# src/CMakeLists.txt
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE mylib)

find_package

# Qt
find_package(Qt6 REQUIRED COMPONENTS Core Widgets Sql)
target_link_libraries(myapp PRIVATE Qt6::Core Qt6::Widgets Qt6::Sql)

# OpenCV
find_package(OpenCV REQUIRED)
target_link_libraries(myapp PRIVATE ${OpenCV_LIBS})

# 自定义库(非标准路径)
find_package(mylib REQUIRED PATHS /opt/custom/lib/cmake)

条件编译

option(ENABLE_TESTS "Build tests" ON)

if(ENABLE_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

# 平台判断
if(WIN32)
    target_sources(myapp PRIVATE win_specific.cpp)
elseif(APPLE)
    target_sources(myapp PRIVATE mac_specific.cpp)
else()
    target_sources(myapp PRIVATE linux_specific.cpp)
endif()

Qt 集成

cmake_minimum_required(VERSION 3.16)
project(PulseQt VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)       # 自动处理 Q_OBJECT moc
set(CMAKE_AUTORCC ON)       # 自动处理 .qrc
set(CMAKE_AUTOUIC ON)       # 自动处理 .ui

find_package(Qt6 REQUIRED COMPONENTS Core Widgets Sql SerialPort)

add_executable(pulseqt
    main.cpp
    mainwindow.h mainwindow.cpp
)

target_link_libraries(pulseqt PRIVATE
    Qt6::Core
    Qt6::Widgets
    Qt6::Sql
    Qt6::SerialPort
)

常见变量

${CMAKE_SOURCE_DIR}         # 顶层 CMakeLists.txt 所在
${CMAKE_BINARY_DIR}         # build 目录
${CMAKE_CURRENT_SOURCE_DIR} # 当前 CMakeLists.txt 所在
${PROJECT_NAME}             # 项目名
${PROJECT_VERSION}          # 版本号

# 安装
install(TARGETS myapp DESTINATION bin)
install(FILES config.json DESTINATION etc/myapp)

调试 CMake

message(STATUS "Qt version: ${Qt6_VERSION}")  # 信息
message(WARNING "Something might be wrong")     # 警告
message(FATAL_ERROR "Cannot continue")          # 致命错误

# 打印所有变量
get_cmake_property(_vars VARIABLES)
foreach(_var ${_vars})
    message(STATUS "${_var}=${${_var}}")
endforeach()