菜缤的世界 CairBin's Blog - CMake
type: channel
link: https://blog.cairbin.top/index.php/tag/CMake/
items: CMake基础用法

CMake基础用法
type: item
date: 2023-09-08T17:54:53+00:00
description: CMake基础用法CMake介绍CMake是一个跨平台的安装（编译）工具，可以用简单的语句来描述安装（编译）过程。他能够输出各种各样的makefile或者project文件。笔者主要用CMake来构建CPP项目（但不仅限于CPP）。由于makefile通常依赖于当前的编译平台，编写makefile相较于麻烦一些，依赖也容易出错，而CMake恰好能解决上述问题。使用CMake编译项目流程如下：项目源码编写CMakeLists.txt文件执行cmake命令生成makefile文件执行make命令生成目标文件前提一个项目的目录大概是这样的. ├── bin ├── build ├── CMakeLists.txt ├── include ├── lib └── src下面对其介绍：bin目标文件生成目录build cmake命令生成的文件存放目录include 项目自己编写的头文件目录lib 库的目录src 源文件的目录CMakeLists.txt CMake配置文件，注意这个名称必须这样写（大小写也一致）我们接下来就根据这个目录结构来进行编写CMake的配置文件CMake使用注释注释行# 这是个行注释注释块#[[ 这是块注释 ]]指定cmake版本如指定Cmake最低版本为3.26cmake_minimum_required(VERSION 3.26)该命令并不是必须的，但是在编写项目的时候使用高版本的CMake命令通常会向下兼容，但使用低版本的CMake却没有高版本的特性，所以通常指定一个最低版本CMake以减少不必要的错误。设置项目名称例如名称设置为HelloWorldproject(HelloWorld)set的使用set命令可以自定义变量，而使用这些变量需要用${}将其名称包括进去例如我指定变量名为VAR_NAME，其值为var_valueset(VAR_NAME var_value) # 定义变量 message(${VAR_NAME}) # 使用变量并输出它的值设置CPP标准同理编译器可能默认使用低标准的C++，但是项目中包含高标准的特性，所以一般指定一个项目所使用的C++ 表准。例如项目中使用了auto关键字，这个是C++11标准里的，编译器可能默认C++98标准，这时候编译就会报错。set(CMAKE_CXX_STANDARD 11)设置可执行文件输出路径设置EXECUTABLE_OUTPUT_PATH宏来指定可执行程序的输出命令set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)其中CMAKE_SOURCE_DIR为CMakeLists.txt的目录这句话的含义是将可执行文件放到了./bin目录下设置库的输出目录设置LIBRARY_OUTPUT_PATH宏来指定生成库的输出目录set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)搜索文件搜索源文件，有两种方式我们项目的源文件都在./src目录下将搜索到的源文件路径存放到SRC这个变量里利用aux_source_directoryaux_source_directory(${CMAKE_SOURCE_DIR}/src SRC)使用filefile(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)这里file命令的第一个参数如果是GLOB则只搜索当前目录，如果是GLOB_RECURSE则进行递归搜索设置头文件目录include_directories(${PROJECT_SOURCE_DIR}/include)这里宏PROJECT_SOURCE_DIR对应项目根目录打印日志信息# 打印HelloWorld（重要信息） message("HelloWorld") # 打印Hello(非重要信息) message(STATUS "Hello")message命令第一个参数可指定消息类型：如果没有第一个参数，则这是重要信息STATUS：则这是非重要信息WARNING：警告信息，但会继续执行后面的命令AUTHOR_WARNING：警告信息(dev)，但会继续执行后面的命令SEND_ERROR：错误信息，继续执行，但会跳过生成的步骤FATAL_ERROR：错误信息，中止所有处理的过程字符串追加使用set拼接# 省略号表示参数数量不固定 set(变量名 ${变量1} ${变量2} ...)用法如下# 定义一些字符串 set(VAR1 hello) set(VAR2 world) # 拼接字符串，FINAL_STR的值为helloworldhaha123 set(FINAL_STR ${VAR1} ${VAR2} haha123)使用list拼…