cmake 学习笔记
1、什么是cmake
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。
2、cmake的优势
(1)跨平台
(2)支持所有c++特性
(3)开源:https://github.com/Kitware/CMake
3、基本api
#设置变量 PROJECT_VERSION = 1500
set(PROJECT_VERSION 1500)
#输入日志 引用变量值
message("输出日志 版本号:" ${PROJECT_VERSION})
#CMakeList.txt 所在目录
${CMAKE_CURRENT_LIST_DIR}
#查找目录下文件并赋值给变量FILE_SRC
file(GLOB FILE_SRC ${CMAKE_CURRENT_LIST_DIR}/src)
#遍历子目录查找目录下文件并赋值给变量FILE_SRC
file(GLOB_RESOURCE FILE_SRC ${CMAKE_CURRENT_LIST_DIR}/src)
#遍历子目录查找目录下.h文件并赋值给变量FILE_SRC
file(GLOB_RESOURCE FILE_SRC ${CMAKE_CURRENT_LIST_DIR}/src/*.h)
#工程所在目录
${PEOJECT_SOURCE_DIR}
#添加查找目录,设置头文件包含路径
include_directories(${PROJECT_SOURCE_DIR})
#添加target,library
add_library(lib_name ${FILE_SRC})
#添加command tool target
add_executable(exe_name ${FILE_SRC})
#添加子文件夹,cmake会执行子文件夹中cmakelist.txt
add_subdirectory(tools)
#添加项目依赖
target_link_libraries(exe_name PUBLIC lib_name)
#文件分组,将文件放入project子文件夹(文件需要add_library or add_executable 添加)
source_group("Header Files\\src" FILES ${FILE_SRC})
#添加hear search path
target_include_directories(exe_name PUBLIC "$<Build_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include")
4、编译选项
#编译支持c++ 11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
5、构建项目
(1) file查找需要文件
(2) add_library add_executable 添加文件
(3) source_group 分组文件
(4) target_link_libraries 添加依赖 target_include_directories 添加查找路径
(5) cxx_standard 编译选项
6、按目录分组方法
set(SRC_FLODER src)
set(ALL_FILE_TYPE ${SRC_FLODER}/*.h ${SRC_FLODER}/*.hpp ${SRC_FLODER}/*.cpp ${SRC_FLODER}/*.c)
include_directories(${PROJECT_SOURCE_DIR})
MACRO(SOURCE_GROUP_BY_FOLDER target) # 将源文件和头文件进行分组
SET(SOURCE_GROUP_DELIMITER "/")
SET(last_dir "")
SET(files "")
file(GLOB_RECURSE src_file ${ALL_FILE_TYPE})
FOREACH(file ${src_file})
file(RELATIVE_PATH relative_file "${PROJECT_SOURCE_DIR}/${target}" ${file})
GET_FILENAME_COMPONENT(dir "${relative_file}" PATH)
IF (NOT "${dir}" STREQUAL "${last_dir}")
IF (files)
SOURCE_GROUP("${last_dir}" FILES ${files})
message(STATUS "[SOURCE_GROUP]" ${last_dir} " " ${files})
ENDIF (files)
SET(files "")
ENDIF (NOT "${dir}" STREQUAL "${last_dir}")
SET(files ${files} ${file})
SET(last_dir "${dir}")
ENDFOREACH(file)
IF (files)
SOURCE_GROUP("${last_dir}" FILES ${files})
message(STATUS "[SOURCE_GROUP]" ${last_dir} " " ${files})
ENDIF (files)
ENDMACRO(SOURCE_GROUP_BY_FOLDER)
SOURCE_GROUP_BY_FOLDER(src)
file(GLOB_RECURSE root_All ${ALL_FILE_TYPE})
add_library(${PROJECT_NAME} ${root_All})
7、function设置全局变量 PARENT_SCOPE
function(extra_version)
file(READ "${CMAKE_CURRENT_LIST_DIR}/src/version.h" file_contents)
string(REGEX MATCH "TILEBOXVERSION ([0-9]+)" _ "${file_contents}")
if(NOT CMAKE_MATCH_COUNT EQUAL 1)
message(FATAL_ERROR "Could not extract version number from ToolBox/src/version.h")
endif()
message("version is " ${CMAKE_MATCH_1})
set(PROJECT_VERSION ${CMAKE_MATCH_1} PARENT_SCOPE)
endfunction()