CMakelist使用说明

默认路径

CMAKE_CURRENT_LIST_FILE :输出调用这个变量的CMakeLists.txt 的完整路径
CMAKE_MODULE_PATH :定义自己的cmake 模块所在的路径
EXECUTABLE_OUTPUT_PATH :重新定义最终结果的存放目录
LIBRARY_OUTPUT_PATH :重新定义最终结果的存放目录

CMAKE_INCLUDE_CURRENT_DIR :自动添加CMAKE_CURRENT_BINARY_DIR 和CMAKE_CURRENT_SOURCE_DIR 到当前处理的CMakeLists.txt

PRIVATE: 将链接只用于当前目标,相当于.c包含,对外的.h不包含
INTERFACE: 将链接只用于依赖于当前目标的文件,当前目标不使用; 相当于.c不使用,对外的.h使用
PUBLIC:相当于PRIVATE + INTERFACE;所有对象都可以使用链接;相当于.c使用,对外的.h也使用

关键字

Option

在CMakeList中添加编译选项。

option(TRANSLATION_ENABLED "TRANSLATION_ENABLED " OFF)
if(TRANSLATION_ENABLED){
message("Auto generate translation file ")
}

add_executable

添加可执行文件

add_executable(${APP_NAME}
    ${APP_SRC}
)

aux_source_directory

把当前路径下src目录下的所有源文件路径放到变量hello_src中(不会递归包含子目录,仅包含指定的dir目录)

aux_source_directory(./src ${hello_src})

$ENV{NAME}

cmake 调用环境变量:

MESSAGE(STATUS “HOME dir: $ENV{HOME})

设置环境变量的方式是:SET(ENV{ 变量名} 值)

file (GLOB)

查找文件夹目录下的所有符合类型的文件,放入ALL_SOURCES 对象中

file (GLOB ALL_SOURCES "./Src/*.cpp" "./Src/UI/*.cpp" "./Src/Tools/*.cpp")

find_package()

set(QT_PATH D:/Qt/5.12.11/msvc2017_64)

SET(CMAKE_PREFIX_PATH ${QT_PATH}/lib/cmake) #将cmake文件夹包含进项目优先查找路径中,之后find_package才能找到

命令是用来查找依赖包的XXX.cmake文件,把一整个依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到,后续只管用就好了
查找路径:同时还会搜索系统的PATH路径,其中如果是以/bin或者/sbin结尾的,会自动转化为其父目录。
_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
可以通过NO_CMAKE_ENVIRONMENT_PATH来跳过。

version和EXACT: 都是可选的,version指定的是版本,如果指定就必须检查找到的包的版本是否和version兼容。如果指定EXACT则表示必须完全匹配的版本而不是兼容版本就可以。
QUIET 可选字段,表示如果查找失败,不会在屏幕进行输出(但是如果指定了REQUIRED字段,则QUIET无效,仍然会输出查找失败提示语)。
MODULE 可选字段。前面提到说“如果Module模式查找失败则回退到Config模式进行查找”,但是假如设定了MODULE选项,那么就只在Module模式查找,如果Module模式下查找失败并不回落到Config模式查找。
REQUIRED可选字段。表示一定要找到包,找不到的话就立即停掉整个cmake。而如果不指定REQUIRED则cmake会继续执行。
COMPONENTS,components:可选字段,表示查找的包中必须要找到的组件(components),如果有任何一个找不到就算失败,类似于REQUIRED,导致cmake停止执行。
OPTIONAL_COMPONENTS和components:可选的模块,找不到也不会让cmake停止执行。

link_libraries

link_libraries用在add_executable之前,用来链接静态库

target_link_libraries

target_link_libraries用在add_executable之后,用来链接导入库即按照header file + .lib + .dll方式隐式调用动态库的.lib库

target_link_libraries(${APP_NAME} PRIVATE Qt5::Widgets  Qt5::PrintSupport Qt5::Concurrent ${APP_LIBS})

target_include_directories

指定目标包含的头文件路径; 目标 由 add_library() 或 add_executable() 生成

include()

include指令用来载入并运行来自于文件或模块的CMake代码, 该命令用于导入文件或模块中的CMAKE代码, 类似于c语言中的include 功能

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                      [NO_POLICY_SCOPE])

file | module: 指定的包含CMKE指定的文件 或者 模块名。模块名其实就是安装cmake时已经提供的***.cmake文件

例如:
#这里导入CheckCXXCompilerFlag模块, 并运行该模块内的CHECK_CXX_COMPILER_FLAG命令。

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)

include_directories(dir)

该函数包含的路径可以用于源文件路径的查找,相当于把该路径加入到cmake的编译路径上;单不能用于find_package使用,find_package查找路径有自己的顺序
include_directories完全可以实现target_include_directories的所有功能,但是建议使用target_include_directories,为了保证包含路径的清晰
include_directories(header-dir) 是一个全局包含,向下传递,就是说如果某个目录的 CMakeLists.txt 中使用了该指令,其下所有的子目录默认也包含了header-dir 目录

target_compile_options

设定目标的编译选项,例如设置目标编译时以utf-8识别文件

if(WIN32)
  target_compile_options(${APP_NAME} PRIVATE "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
  target_compile_options(${APP_NAME} PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
endif()

Set()

1)给一般变量赋值s

set(FOO  “x”)。         //FOO作用域为当前作用域。
set(FOO "x" PARENT_SCOPE)   //FOO作用域跳上一级。

2)给缓存变量赋值:
缓存变量可以理解为当第一次运行cmake时,这些变量缓存到一份文件中(即编译目录下的CMakeCache.txt)。
当再次运行cmake时,这些变量会直接使用缓存值,可以利用ccmake或者cmake-gui等工具来重新赋值。

set(FOO, "x" CACHE <type><docstring> FORCE)  
//<type>可以理解为所存入变量类型,<docstring>为变量的描述

include

include(sub/CMakeLists.txt) 

可以加载 子目录中的 CMakeLists.txt 文件,此时相当于子目录中的CMakeLists.txt的全部内容放在主目录中运行
子目录和主目录没有父子关系
在子目录中设置的变量在父目录中也一样使用
此时如果在子目录中也声明一个project时会和主目录的projrct冲突,后面声明的会覆盖之前声明的project

add_subdirectory

add_subdirectory(sub_dir) 

也是加载子目录,不过子目录是单独构建的,而不是在主目录下构建的;一般在子目录的CMakeLists.txt中都会再声明一个project;
该命令成用于构建示例等单独的项目;如果主目录想要访问子目录定义的变量需要使用set(PARENT_SCOPE)来定义变量

其他

${PROJECT_NAME} //$+{}会获取到{}里面的变量对应的值
if(" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")  : STREQUAL 判断两个字符串是否相等
message( [STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]"message to display" ...)打印一条信息

示例


if(" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")
  message(FATAL_ERROR "\n${Red}FATAL: In-source builds are not allowed.You should create a separate directory for build files.${ColorReset}")
endif()

cmake_minimum_required(VERSION 3.5)# cmake version require
project(TestCMakelist VERSION 1.0.0 LANGUAGES CXX) #project name
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

#############################添加qt库 add qt dll
#set(QT_PATH D:/Qt/Qt5.12.11/msvc2017_64)
#set(CMAKE_PREFIX_PATH ${QT_PATH}/lib/cmake)
find_package(Qt5 COMPONENTS Widgets Gui Core PrintSupport LinguistTools Concurrent REQUIRED)


#############################添加源文件
set(APP_SRC
    ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.h
    ${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.ui
)

#############################添加翻译
option(TRANSLATION_ENABLED "TRANSLATION_ENABLED " OFF)
if(TRANSLATION_ENABLED)
message("Auto generate translation file ")
set(TS_FILE
    ${CMAKE_CURRENT_SOURCE_DIR}/Language/Chinese.ts
    ${CMAKE_CURRENT_SOURCE_DIR}/Language/English.ts
    ${CMAKE_CURRENT_SOURCE_DIR}/Language/Russian.ts
    )

#根据输入的参数生成.ts(translation source)文件,ts文件同时会被转换成.qm文件,并将qm文件路径放在QM_FILES里面。
#输入的参数是路径,可以是文件也可以是目录。如果后缀带有.ts将会被创建或者更新。其他的文件或目录会被lupdate认为是接收,用于更新ts文件。
#lupdate soruse file-> .ts
#lrelease  .ts->.qm
#app 使用 .qm进行程序的翻译
qt5_create_translation(QM_FILES 
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${TS_FILE}
    )
endif()
              
#############################add exe
set(App_Name TestApp)
add_executable( ${App_Name}
    ${APP_SRC}
    ${QM_FILES}
)
target_link_libraries(${App_Name} PRIVATE Qt5::Widgets  Qt5::PrintSupport Qt5::Concurrent)