CXX_STANDARD:设置标准
CXX_EXTENSIONS:告诉CMake,只启用ISO C++标准的编译器标志,而不使用特定编译器的扩展。
CXX_STANDARD_REQUIRED:指定所选标准的版本,如果这个版本不可用,CMake将停止配置并出现错误。当这个属性被设置为OFF时,CMake将寻找下一个标准的最新版本,直到一个合适的标志
TODO: 更多编译特性和语言标准
set(CMAKE_CXX_STANDARD 17) # C++17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
通过命令 set_target_properties
target_compile_features( [...])
使用add_executable编译二进制文件,add_library编译库(静态库或动态库)
add_library
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[<source>...])
set_target_properties:设置生成目标的属性,设置的属性可以通过 get_property() 和 get_target_property() 这两个命令获取。cmake中所有的目标属性看这里
set_target_properties(target1 target2 ...
PROPERTIES
prop1 value1 prop2 value2 ...)
为target1,target2,… 设置属性,如:
set_target_properties( <target>
PROPERTIES
CXX_STANDARD 14
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE 1
)
常用的属性有以下:
-fvisibility=hidden
标志CMake将语言的编译器存储在 CMAKE_LANG_COMPILER 变量中,其中是受支持的任何一种语言,对于我们的目的是CXX,C。可以通过以下两种方式设置此变量
如果想查看可用的编译器和编译器标志,可以通过 cmake --system-information 查看
控制生成构建系统使用的配置变量是 CMAKE_BUILD_TYPE,该变量默认为空,CMAKE识别的值为:
两种方式设置构建类型:
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) # 将该变量设置为缓存变量,可以通过缓存进行编辑
endif
target_compile_options
,推荐使用的方式,不仅允许对编译选项进行细粒度控制,而且还可以更好地与CMake的更高级的特性进行集成target_compile_options(
<target>
[BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]
)
为目标设置编译选项,编译选项可以设置三个级别的可见性:
target_compile_options(
my_exe
PRIVATE
"-fPIC"
)
这个例子中解压缩Eigen打包文件,并相应的为目标设置包含目录
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
project(recipe-01 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_custom_target(
unpack-eigen
ALL
COMMAND ${CMAKE_COMMAND} -E tar xzf ${CMAKE_CURRENT_SOURCE_DIR}/eigen-3.4.0.tar.gz # 并不会真正解压一个实体目录出来
COMMAND ${CMAKE_COMMAND} -E rename eigen-3.4.0 eigen # 这里会报错:Error renaming from "eigen-3.4.0" to "eigen": Directory not empty
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Unpacking eigen"
)
add_executable(
linear-algebra linear-algebra.cpp
)
add_dependencies(linear-algebra unpack-eigen)
target_include_directories(
linear-algebra
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/eigen # 上面rename 命令所在行删掉后,这里为啥还是能找到eigen?
)
代码中使用到eigen-3.4.0.tar.gz中的源代码文件,但没有实体解压就可以引用到。
cmake提供了三个选项来在构建时执行自定义命令
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project(recipe-06 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(OpenMP)
if(OpenMP_FOUND)
message(STATUS "package found")
set(_scratch_dir ${CMAKE_CURRENT_BINARY_DIR}/omp_try_compile)
else()
message(STATUS "package not found")
endif()
try_compile(
omp_taskloop_test_1
${_scratch_dir}
SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/taskloop.cpp
LINK_LIBRARIES
OpenMP::OpenMP_CXX
)
message(STATUS "result of try_compile: ${omp_taskloop_test_1}")
include(CheckCXXSourceCompiles)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/taskloop.cpp _snippet)
set(CMAKE_REQUIRED_LIBRARIES OpenMP::OpenMP_CXX)
check_cxx_source_compiles("${_snippet}" omp_taskloop_test_2)
unset(CMAKE_REQUIRED__LIBRARIES)
message(STATUS "Result of check_cxx_source_compiles: ${omp_taskloop_test_2}")
check__compiles_function
之后,必须手动取消对这些变量的设置,确保后续使用中不会保留当前的内容需要由用户从外部可以修改的变量值,可以通过在CMakeLists.txt中使用option()
命令,以选项的形式显示逻辑开关,通过CMake的-D的CLI选项,将值传递到cmake中。如: cmake -D my_option=ON ...
-D开关用于为CMake设置任何类型的变量:逻辑变量,路径等等。
optionq签名:option(
,参数说明:
表示该选项的变量的名称。[initial value]
选项的默认值,可以是ON或OFF。