常用 CMake 变量
变量名 | 说明 |
---|---|
CMAKE_CXX_STANDARD |
指定 C++ 标准版本,例如 17 。 |
CMAKE_CXX_STANDARD_REQUIRED |
强制要求使用指定的 C++ 标准版本,值为 ON 或 OFF 。 |
CMAKE_BUILD_TYPE |
设置构建类型,例如 Debug 或 Release 。 |
CMAKE_CXX_FLAGS |
为 C++ 编译器添加全局编译选项。 |
CMAKE_CXX_FLAGS_DEBUG |
为 Debug 构建类型添加特定的编译选项。 |
CMAKE_CXX_FLAGS_RELEASE |
为 Release 构建类型添加特定的编译选项。 |
CMAKE_SOURCE_DIR |
顶层 CMakeLists.txt 所在的目录路径。 |
CMAKE_BINARY_DIR |
CMake 生成的构建文件所在的目录路径。 |
PROJECT_SOURCE_DIR |
当前项目的源代码目录路径。 |
PROJECT_BINARY_DIR |
当前项目的构建文件目录路径。 |
CMAKE_CURRENT_SOURCE_DIR |
当前处理的 CMakeLists.txt 所在的源代码目录路径。 |
CMAKE_CURRENT_BINARY_DIR |
当前处理的 CMakeLists.txt 所生成的构建文件所在的目录路径。 |
CMAKE_INSTALL_PREFIX |
安装目标文件的根目录。 |
CMAKE_MODULE_PATH |
查找自定义 CMake 模块的路径列表。 |
CMAKE_PREFIX_PATH |
查找库和包的前缀路径列表。 |
CMAKE_INCLUDE_PATH |
查找头文件的附加路径。 |
CMAKE_LIBRARY_PATH |
查找库文件的附加路径。 |
CMAKE_RUNTIME_OUTPUT_DIRECTORY |
指定可执行文件的输出目录。 |
CMAKE_ARCHIVE_OUTPUT_DIRECTORY |
指定静态库和归档文件的输出目录。 |
CMAKE_LIBRARY_OUTPUT_DIRECTORY |
指定动态库的输出目录。 |
CMAKE_VERBOSE_MAKEFILE |
是否生成详细的 Makefile,值为 ON 或 OFF 。 |
CMAKE_EXPORT_COMPILE_COMMANDS |
生成用于编译数据库的 compile_commands.json 文件,值为 ON 或 OFF 。 |
CMAKE_CONFIGURATION_TYPES |
设置多配置构建的配置类型列表,例如 Debug;Release;MinSizeRel;RelWithDebInfo 。 |
命令备忘清单
生成项目构建系统
$ cmake [<options>] <path-to-source | path-to-existing-build>bash
$ cmake [<options>] -S <path-to-source> -B <path-to-build>
建立一个项目
$ cmake --build <dir> [<options>] [-- <build-tool-options>]
安装项目
$ cmake --install <dir> [<options>]
运行指定项目
cmake --build <dir> --target <project>
打开一个项目
$ cmake --open <dir>
运行脚本
$ cmake [-D <var>=<value>]... -P <cmake-script-file>
运行命令行工具
$ cmake -E <command> [<options>]
运行查找包工具
$ cmake --find-package [<options>]
运行工作流预设
$ cmake --workflow [<options>]
查看帮助
$ cmake --help[-<topic>]
最小CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
project(example)
add_executable(a.out a.cpp b.cpp)
通配符源文件
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cpp")
project(example)
add_executable(a.out ${src})
设置CXXFLAGS
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cc")
project(example)
set(CMAKE_CXX_FLAGS "-Wall -Werror -O3")
add_executable(a.out ${src})
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cc")
project(example)
add_executable(a.out ${src})
target_compile_options(a.out PRIVATE -Werror)
带有构建类型的CXXFLAGS
# 通用
set(CMAKE_CXX_FLAGS "-Wall -Werror -O3")
# 调试
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g")
# 发布
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -pedantic")
构建调试/发布版本
$ cmake -DCMAKE_BUILD_TYPE=Release ../
$ cmake -DCMAKE_BUILD_TYPE=Debug ../
带有类型的构建
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
project(example)
add_executable(a.out a.cc)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(a.out PRIVATE -g -O0 -Wall)
else()
target_compile_options(a.out PRIVATE -O3 -Wall -Werror)
endif()
现代CMake更倾向于使用生成器表达式来检查条件,而不是检查CMAKE_BUILD_TYPE
。
扫描二维码关注公众号,回复:
17563416 查看本文章

cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
project(example)
add_executable(a.out a.cc)
target_compile_options(a.out PRIVATE
$<IF:$<CONFIG:Debug>, -g -O0 -Wall, -O3 -Wall -Werror>
)
版本配置文件
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cpp")
project(example VERSION 1.0)
configure_file(version.h.in version.h)
add_executable(a.out ${src})
target_include_directories(a.out PUBLIC "${PROJECT_BINARY_DIR}")
version.h.in
#pragma once
#define VERSION_MAJOR @example_VERSION_MAJOR@
#define VERSION_MINOR @example_VERSION_MINOR@
构建/链接静态库
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cpp")
project(example VERSION 1.0)
configure_file(version.h.in version.h)
add_executable(a.out ${src})
add_library(b b.cpp)
target_link_libraries(a.out PUBLIC b)
target_include_directories(a.out PUBLIC "${PROJECT_BINARY_DIR}")
构建/链接共享库
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cpp")
project(example VERSION 1.0)
configure_file(version.h.in version.h)
add_executable(a.out ${src})
add_library(b SHARED b.cpp)
target_link_libraries(a.out PUBLIC b)
target_include_directories(a.out PUBLIC "${PROJECT_BINARY_DIR}")
子目录
子目录 fib/
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cpp")
add_library(b SHARED b.cpp)
target_include_directories(b PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
项目目录
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
file(GLOB src "*.cpp")
project(example VERSION 1.0)
configure_file(version.h.in version.h)
add_executable(a.out ${src})
add_subdirectory(fib)
target_link_libraries(a.out PUBLIC b)
target_include_directories(a.out PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_BINARY_DIR/fib}"
)
PUBLIC & PRIVATE
- PUBLIC - 只影响当前目标,不影响依赖项
- INTERFACE - 仅影响依赖项
cmake_minimum_required(VERSION 3.10)
project(example)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(Boost)
add_executable(a.out a.cpp)
add_library(b STATIC b.cpp b.h)
target_include_directories(a.out PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(b PRIVATE "${Boost_INCLUDE_DIR}")
target_link_libraries(a.out INTERFACE b) # 链接b失败
生成器表达式
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
project(example)
set(target fib)
add_library(${target} src/fib.cc)
target_compile_options(${target} PRIVATE -Wall -Werror -Wextra)
target_include_directories(${target}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
安装
cmake_minimum_required(VERSION 3.10)
project(a)
add_library(b_static STATIC b.cc)
add_library(b_shared SHARED b.cc)
add_executable(a a.cc b.cc)
include(GNUInstallDirs)
set(INSTALL_TARGETS a b_static b_shared)
install(TARGETS ${INSTALL_TARGETS}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(FILES b.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
配置时运行命令
execute_process(
COMMAND git submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_SUBMOD_RESULT
)
选项
# $ make -p build
# $ cd build
# $ cmake -DBUILD_TEST=ON ../
option(BUILD_TEST "Build test" OFF)
if (BUILD_TEST)
message("Build tests.")
else()
message("Ignore tests.")
endif()
为库创建别名
当CMakeLists.txt
在命名空间Foo::
中导出Foo时,还需要创建一个别名Foo::Foo
。
add_library(Foo::Foo ALIAS Foo)
查找和使用外部包
find_package(Boost REQUIRED COMPONENTS filesystem system) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(MyExecutable ${Boost_LIBRARIES}) endif()
设置 CMake 选项
在项目中使用 option()
语句为用户提供可配置选项。
cmake_minimum_required(VERSION 3.10)
project(example)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Define an option
option(BUILD_TESTS "Build the tests" OFF)
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
使用条件语句
根据条件编译不同代码或设置不同编译选项。
cmake_minimum_required(VERSION 3.10)
project(example)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
自定义命令和目标
使用 add_custom_command
和 add_custom_target
添加自定义构建步骤。
cmake_minimum_required(VERSION 3.10)
project(example)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/generated_file.cpp
COMMAND ${CMAKE_COMMAND} -E echo "Generating file"
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/generated_file.cpp
DEPENDS some_other_target
)
add_custom_target(generate_file ALL DEPENDS ${CMAKE_BINARY_DIR}/generated_file.cpp)
add_executable(a.out main.cpp ${CMAKE_BINARY_DIR}/generated_file.cpp)
使用 FindPackage 和 CMake 模块
利用 find_package
和 CMake 自带模块查找并使用外部库。
cmake_minimum_required(VERSION 3.10)
project(example)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(Boost REQUIRED COMPONENTS filesystem system)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(a.out ${Boost_LIBRARIES})
else()
message(FATAL_ERROR "Boost not found")
endif()
导出目标
为使库可以被其他项目使用,使用 install
命令导出目标。
cmake_minimum_required(VERSION 3.10)
project(example)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_library(foo SHARED foo.cpp)
install(TARGETS foo EXPORT fooConfig
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(EXPORT fooConfig DESTINATION cmake)
使用 FetchContent 下载外部项目
使用 FetchContent
下载并构建外部项目。
cmake_minimum_required(VERSION 3.11)
project(example)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.10.0
)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(test_example test.cpp)
target_link_libraries(test_example gtest gtest_main)
add_test(NAME example_test COMMAND test_example)