针对于OB_GINS的CMakeList文件的深入学习

Project()------配置项目信息

c 复制代码
project(CMakeTemplate VERSION 1.0.0 LANGUAGES C CXX DESCRIPTION "A cmake template project")
//通过project命令配置项目信息

project(项目名称 VERSION major.minor.patch.tweak )CMake会将对应的值分别赋值给以下变量:

c 复制代码
PROJECT_VERSION, <PROJECT-NAME>_VERSION
PROJECT_VERSION_MAJOR, <PROJECT-NAME>_VERSION_MAJOR  //1
PROJECT_VERSION_MINOR, <PROJECT-NAME>_VERSION_MINOR  //0
PROJECT_VERSION_PATCH, <PROJECT-NAME>_VERSION_PATCH  //0
PROJECT_VERSION_TWEAK, <PROJECT-NAME>_VERSION_TWEAK

configure_file------配置自动生成版本头文件

configure_file指令

c 复制代码
configure_file(src/c/cmake_template_version.h.in "${PROJECT_SOURCE_DIR}/src/c/cmake_template_version.h")

configure_file 指令通过读取输入文件中的内容,将 CMakeLists.txt 文件中的变量转变为 C/C++ 中可识别的宏定义,然后存入另一个文件中。

cpp 复制代码
configure_file(<input> <output>
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
               //将input文件复制到output文件,并在输入文件内容中的变量,替换引用为@VAR@或${VAR}的变量值。每个变量引用将替换为该变量的当前值,如果未定义该变量,则为空字符串。

configure_file,复制一份输入文件到输出文件,替换输入文件中被@VAR@或者${VAR}引用的变量值。

如在cmake_template_version.h.in(input文件),内容如下:

cpp 复制代码
#define CMAKE_TEMPLATE_VERSION_MAJOR @CMakeTemplate_VERSION_MAJOR@
#define CMAKE_TEMPLATE_VERSION_MINOR @CMakeTemplate_VERSION_MINOR@
#define CMAKE_TEMPLATE_VERSION_PATCH @CMakeTemplate_VERSION_PATCH@

那么执行CMakeList文件,,系统就会自动生成cmake_template_version.h(output文件),同时,将@CMakeTemplate_VERSION_MAJOR@替换成相应的值(经过CMakeList中的VERSION设置,最终 实现值与变量宏定义的对应)

cpp 复制代码
#define CMAKE_TEMPLATE_VERSION_MAJOR 1
#define CMAKE_TEMPLATE_VERSION_MINOR 0
#define CMAKE_TEMPLATE_VERSION_PATCH 0

set(CMAKE_)指定程序语言版本形式

cpp 复制代码
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)

add_compile_options()配置编译的选项

cpp 复制代码
add_compile_options(-Wall -Wextra -pedantic -Werror)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -std=c99")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -std=c++11")

通过设置变量CMAKE_C_FLAGS 可以配置c编译器的编译选项

通过设置变量CMAKE_CXX_FLAGS配置针对c++编译器的编译选项

在add_compile_options()中:

-WALL选项------提供报警信息

通过add_compile_options命令,能够将其添加到所有的目标上

cpp 复制代码
add_compile_options(-Wall)//将允许gcc提供的所有有用的报警信息,添加到所有的目标上

使用target_compile_options命令。这个命令只会添加到指定的目标上

cpp 复制代码
target_compile_options(target PRIVATE -Wall)
//-Wall 编译选项只会被添加到my_target这个目标,而不会影响到其他的目标。

PRIVATE、PUBLIC、INTERFACE这些关键字的含义:

  1. PRIVATE:定义的target目标能够使用这些编译参数(-Wall等)
  2. PUBLIC:目标自己和其他依赖这个目标的目标都会使用这些编译参数。
  3. INTERFACE:只有依赖这个目标的目标 会使用这些编译参数

set(CMAKE_BUILD_TYPE Debug) 配置编译类型

设置变量CMAKE_BUILD_TYPE来配置编译类型------Debug、Release、RelWithDebInfo、MinSizeRel

message()函数的功能

在CMake中,message()函数用于向终端输出信息。

message函数的用法:message([] "message text" ...)

往往mode参数如下:

  • STATUS: 输出的信息会被发送到CMake的状态消息流,这是message()函数的默认模式。在命令行上,这些消息通常会被显示出来,但在图形界面中,它们可能会被重定向到其他地方。
  • WARNING : 输出的信息会被发送到CMake的警告消息流。这些消息会被显示出来,并且会标记为警告。
  • AUTHOR_WARNING: 这是WARNING模式的一种变体,只有在CMAKE_SUPPRESS_DEVELOPER_WARNINGS变量为FALSE时才会产生警告。
  • SEND_ERROR : 输出的信息会被发送到CMake的错误消息流,但不会立即停止CMake的处理过程。
  • FATAL_ERROR : 输出的信息会被发送到CMake的错误消息流 ,并立即停止CMake的处理过程。

    对于STATUS的举例:
    message(STATUS "Your message")常常被用来输出构建过程中的状态信息
cpp 复制代码
set(MY_VARIABLE "Hello, CMake!");
//而set(变量引用  变量值)就是通过将"Hello, CMake!"的值通过MY_VARIABLE代替
message(STATUS "MY_VARIABLE is: ${MY_VARIABLE}")
//这个例子中message会输出一条状态信息:MY_VARIABLE is: Hello, CMake!
//${MY_VARIABLE}是CMake的变量引用语法,它会被替换为MY_VARIABLE变量的值

CMake中的option配置

cpp 复制代码
option(<variable> "<help_text>" [value])
variable:定义选项名称
help_text:说明选项的含义
value:定义选项默认状态,一般是OFF或者ON,除去ON之外,其他所有值都为认为是OFF。
**自己编写的一个简单的option用于定义全局宏的运用程序**

通过终端控制操作option宏的开关

自己的CMakeList.txt文件的设置:

自己的main.ccp函数的配置:

通过模仿学习打捞的终端进行宏定义的开关的开启和关闭,实现最终主程序的宏定义的调用::

自己定义的TEST_DEFINE_OPTION=ON
自己定义的TEST_DEFINE_OPTION=OFF

对于最终执行文件的输出如下:

动态库与静态库的区别

静态库:在编译程序时,直接将库中的代码链接到可执行程序中------这样使得可执行程序可以直接运行,但是造成内存空间的严重牺牲

动态库:编译程序时,可执行程序中只保存对应的函数引用表,只有到程序执行时,再链接对应的库。------这样使用的优点是在多个执行程序使用同一个库的时候,节省空间的内存,但是,链接操作,往往使得程序的运行速度变慢
大佬理解------学习

如何通过CMakeList编译静态库

实现math编译成静态库,命名为math

同时主函数main.cpp文件依赖math静态库

步骤1:

将项目路径src/c/math下的源文件编译为静态库------需要获得编译此静态库所需的所有文件的列表

file(GLOB_RECURSE) 是一个用来匹配指定路径下所有符合通配符条件的文件的命令。
GLOB_RECURSE递归查找目录下的所有文件file() 命令则可以用来获取文件列表
通过add_library命令编译名为math的静态库,库的类型是第二个参数STATIC指定的。

cpp 复制代码
file(GLOB_RECURSE MATH_SOURCE_SET src/c/*cpp)
//这行代码的用途是:递归地查找 src 目录下所有以 .cpp 结尾的文件,并将它们存储在MATH_SOURCE_SET变量中。
cpp 复制代码
add_library(math_static STATIC ${MATH_SOURCE_SET})

install函数的剖析:

cpp 复制代码
install(<TYPE> files... DESTINATION <dir>
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>]
        [OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP])
  <TYPE>:这是一个必选参数,它定义了我们要安装的内容的类型。这个参数可以是TARGETS(目标),FILES(文件),DIRECTORY(目录)等。
  • files...:这是一个或多个我们要安装的文件或目标 。对于TARGETS ,这将是我们在add_executable或add_library中定义的目标名称 。对于FILES和DIRECTORY,这将是文件或目录的路径
  • DESTINATION :这是一个必选参数,它定义了我们要将文件或目标安装到哪个目录。
  • [PERMISSIONS permissions...]:这是一个可选参数,它允许我们定义安装的文件或目标的权限。如果我们不指定这个参数,CMake将使用默认的权限。
  • [CONFIGURATIONS [Debug|Release|...]]:这是一个可选参数,它允许我们定义在哪些构建配置中执行安装命令。如果我们不指定这个参数,CMake将在所有的构建配置中执行安装命令。
  • [COMPONENT ]:这是一个可选参数,它允许我们将安装的文件或目标分组到一个组件中。这个参数在创建安装包时非常有用。
  • [OPTIONAL]:这是一个可选参数,它允许我们定义如果文件或目标不存在,CMake是否应该继续执行安装命令。
  • [NAMELINK_ONLY|NAMELINK_SKIP]:这是一个可选参数,它只对库目标有效。它允许我们定义是否安装库的名字链接。

以上就是CMake的install命令的基本结构和各个参数的含义。在理解了这些基本概念后,我们就可以开始使用这个命令来安装我们的文件和目标了。在接下来的小节中,我们将深入探讨如何使用这个命令来安装目标和文件,以及如何管理安装目录。
install函数详细解释

在install执行之前,我首先将CMAKE_INSTALL_PREFIX 默认的/usr/local路径改成了当前路径下的src文件夹
参考CMAKE_INSTALL_PREFIX路径更改设置

cpp 复制代码
set(CMAKE_INSTALL_PREFIX "/home/zhaobojun/CLionProjects/MyZBBJ/src")

然后执行install命令------然后我通过install中的files命令------安装所需要的头文件到我的DESTINATION地址

cpp 复制代码
install(FILES ${MATH_HEADER_FILE} DESTINATION include/*.h)

最终src/下面包含的文件夹为:

这里注意我犯错误的一点在于:在cmake ... | make | make install 以后才能成功执行install安装文件

cpp 复制代码
cmake ..
make 
make install 
//我想笑死,我一直没有install 然后排查了半天才明白

参考message 信息打印设置
参考宏定义add_defination设置
linux之cmake 为了阅读mysql安装中的编译细节
CMake之install方法的使用
CMake简单案例

插入大佬博客以表示尊重

相关推荐
Rinai_R3 分钟前
计算机组成原理的学习笔记(7)-- 存储器·其二 容量扩展/多模块存储系统/外存/Cache/虚拟存储器
笔记·物联网·学习
吃着火锅x唱着歌3 分钟前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
drebander4 分钟前
MySQL 查询优化案例分享
数据库·mysql
ragnwang5 分钟前
C++ Eigen常见的高级用法 [学习笔记]
c++·笔记·学习
初晴~20 分钟前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱5813625 分钟前
InnoDB 的页分裂和页合并
数据库·后端
滚雪球~36 分钟前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语38 分钟前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport39 分钟前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg41 分钟前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全