CMake学习笔记
B. Hello Headers
Directory Path
CMake语法指定了许多变量,可用于帮助您在项目或源代码树中找到有用的目录。其中一些包括:
变量 |
信息 |
---|---|
CMAKE_SOURCE_DIR |
root source目录 |
CMAKE_CURRENT_SOURCE_DIR |
当前source目录(如果使用子项目和目录) |
PROJECT_SOURCE_DIR |
当前cmake项目的source目录 |
CMAKE_BINARY_DIR |
root binary / build目录。这是您运行cmake命令的目录 |
CMAKE_CURRENT_BINARY_DIR |
您当前所在的build目录 |
PROJECT_BINARY_DIR |
当前项目的build目录 |
源文件变量
创建包含源文件的变量可以使您更清楚地了解这些文件,并将其轻松添加到多个命令中,例如add_executable()函数。
# Create a sources variable with a link to all cpp files to compile
set(SOURCES
src/Hello.cpp
src/main.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
注意:在SOURCES变量中设置特定文件名的另一种方法是使用GLOB命令使用通配符模式匹配来查找文件。
file(GLOB SOURCES "src/*.cpp")
Tip |
对于现代CMake,不建议对源使用变量。相反,通常直接在add_xxx函数中声明源。 这对于glob命令尤其重要,如果添加新的源文件,这些命令可能不会始终为您显示正确的结果。 |
---|
包含目录
当您有其他包含文件夹时,可以使用target_include_directories()函数使编译器意识到它们。编译此目标时,这将使用 -I 标志将这些目录添加到编译器,例如-I/directory/path.
使用include_directories也可以。
PRIVATE标识符指定包含的范围。这对库很重要,将在下一个示例中说明。有关此功能的更多详细信息,请参见此处。
C. Static Library
添加静态库
add_library() 函数用于从某些源文件创建一个库。
add_library(hello_library STATIC
src/Hello.cpp
)
这将用于创建名为libhello_library.a的静态库,并在add_library调用中包含源文件。
注意 |
如前面的示例所述,我们将源文件直接传递给add_library调用,这是现代CMake的建议。 |
---|
填充目录
在此示例中,我们使用target_include_directories()函数来包含库中的目录,scope设置为PUBLIC。
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
这将导致在以下情况下使用包含的目录:
- 编译库时
- 编译链接库的任何其他目标时
scope的参数含义是:
- PRIVATE - 目录已添加到此目标的包含目录
- INTERFACE - 该目录被添加到链接该库的任何目标的包含目录中。
- PUBLIC - 如上所述,它包含在此库中以及链接到该库的所有目标。
对于public headers,通常最好将include文件夹与子目录进行 “命名间隔(namespaced)”。
传递给target_include_directories的目录将是包含目录树的根,并且C++文件应包括从此处到标头的路径。
对于此示例,您可以看到我们按以下方式进行操作:
#include "static/Hello.h"
使用此方法意味着在项目中使用多个库时,头文件名冲突的可能性较小。
链接一个库 Linking a Library
创建将使用您的库的可执行文件时,必须告知编译器该库。可以使用target_link_libraries()函数来完成。
add_executable(hello_binary
src / main.cpp
)
target_link_libraries(hello_binary
PRIVATE
hello_library
)
这告诉CMake在链接期间将hello_library链接到hello_binary可执行文件。它还将从链接库目标传播具有PUBLIC或INTERFACE范围的任何包含目录。
g++命令总结
以1.cpp为例
命令:g++ 1.cpp
功能:生成默认为a.exe的文件,包含了编译链接。
常用命令
1. g++ -E 1.cpp > 1.i Preprocess only; do not compile, assemble or link
只预处理,不生成文件。这一步主要进行宏的替换、注释消除、找到库文件。1.i 中会有很多代码。
2. g++ -S 1.cpp Compile only; do not assemble or link
只编译,不汇编、不连接 ,生成1.s.,里面是汇编指令
3. g++ -c 1.cpp Compile and assemble, but do not link
从汇编生成目标代码(机器码). 生成1.o文件。
4. g++ 1.o -L <PATH>
链接目标代码,生成可执行程序
5. g++ xxx.x -o yyy.x
输出自己想要的名字。
GTEST总结
LCOV
1. Lcov是什么?
是GCOV图形化的前端工具, 是Linux Test Project维护的开放源代码工具,最初被设计用来支持Linux内核覆盖率的度量。 基于Html输出,并生成一棵完整的HTML树,输出包括概述、覆盖率百分比、图表,能快速浏览覆盖率数据。 支持大项目,提供三个级别的视图:目录视图、文件视图、源码视图。
2. 如何在Linux平台安装Lcov?
# wget http://downloads.sourceforge.net/ltp/lcov-1.9.tar.gz
# tar -zxvf lcov-1.9.tar.gz
# cd lcov-1.9
# ls
bin contrib descriptions.tests lcovrc man rpm
CHANGES COPYING example Makefile README
# make install
不需要编译,直接安装即可,lcov, gendesc, genhtml, geninfo, genpng将被安装到/usr/bin目录。
Gtest 基本概念
当使用google test,通过编写启动assertions,这是检查条件是否为真的statement。断言的结果可能是success, nonfatal failure 或 fatal failure。如果发生fatal failure,它将中止当前功能。否则程序将继续正常运行。
Tests 使用assertions来验证被测试代码的行为。如果测试崩溃或断言失败,则它fails;否则success。
一个测试套件test suite包含一个或多个测试。您应该将测试分为反映被测代码结构的测试套件。当一个测试套件中的多个测试需要共享通用对象common objects和子例程subroutines时,可以将它们放入一个 test fixture 类。
一个测试程序 test program 可以包含多个测试套件。
现在,我们将说明如何编写测试程序,该程序从各个assertion level开始,直至构建测试和测试套件。
Assertions
ASSERT_*
版本失败时会产生致命故障,并中止当前函数。EXPECT_*
版本会产生非致命故障,不会中止当前函数。通常EXPECT_*
是首选,因为它们允许在测试中报告多个故障。但是,如果在断言失败时继续执行没有意义,则应使用ASSERT_*
由于一个失败的ASSERT_*
会立即从当前函数返回,可能会跳过其后的清理代码,因此可能会导致空间泄漏。根据泄漏的性质,它可能值得或不值得修复 —— 因此请牢记这一点,如果您除了断言错误之外还遇到堆检查程序错误。
要提供自定义失败消息,只需使用<<
运算符或此类运算符的序列将其流式传输到宏中macro 即可 。一个例子:
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
for (int i = 0; i < x.size(); ++i) {
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}
可以流到ostream
的任何内容都可以流到一个断言宏assertion macro —— 特别是C字符串和string
对象。如果一个宽字符串(wchar_t*
,TCHAR*
在Windows的UNICODE
模式上,或std::wstring
)流式传输到一个断言assertion,在打印时将被转换为UTF-8。
Basic Assertions
These assertions do basic true/false condition testing.
Fatal assertion |
Nonfatal assertion |
Verifies |
---|---|---|
ASSERT_TRUE(condition); |
EXPECT_TRUE(condition); |
condition is true |
ASSERT_FALSE(condition); |
EXPECT_FALSE(condition); |
condition is false |
Binary Comparison
This section describes assertions that compare two values.
Fatal assertion |
Nonfatal assertion |
Verifies |
---|---|---|
ASSERT_EQ(val1, val2); |
EXPECT_EQ(val1, val2); |
val1 == val2 |
ASSERT_NE(val1, val2); |
EXPECT_NE(val1, val2); |
val1 != val2 |
ASSERT_LT(val1, val2); |
EXPECT_LT(val1, val2); |
val1 < val2 |
ASSERT_LE(val1, val2); |
EXPECT_LE(val1, val2); |
val1 <= val2 |
ASSERT_GT(val1, val2); |
EXPECT_GT(val1, val2); |
val1 > val2 |
ASSERT_GE(val1, val2); |
EXPECT_GE(val1, val2); |
val1 >= val2 |
- sql带条件查找最小缺失编号
- activiti学习笔记(六) 监听器
- activiti学习笔记(五) 流程部署
- 打开文件open()函数的使用方法详解
- activiti学习笔记(四) 配置器
- WaitForMultipleObjects用法详解,一看就懂
- activiti学习笔记(三) 监听生命周期
- Assignment 2 | 斯坦福CS231n-深度学习与计算机视觉课程
- 五个值得深思的PHP面试题
- 5个值得深思的 PHP 面试问题
- activiti学习笔记(二) 获取流程实例
- 文件操作(偏移量)
- 基于Python实现matplotlib中动态更新图片(交互式绘图)
- 使用cJSON创建JSON字符串
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- React 条件渲染最佳实践(7 种方法)
- 一文带你层层解锁「文件下载」的奥秘
- Android实现简单C/S聊天室应用
- Android仿IOS回弹效果 支持任何控件
- 送你一道字节前端原题(Add sumOf)|文末送红宝书
- xadmin使用formfield_for_dbfield函数过滤下拉表单实例
- Python3之外部文件调用Django程序操作model等文件实现方式
- python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
- 前端多线程大文件下载实践,提速10倍(拿捏百度云盘)
- docker 中的mysql 经常重启优化
- python MultipartEncoder传输zip文件实例
- 当Flutter遇到节流与防抖的思路和流程优化
- 花样使用Handler与源码分析
- 几个你不知道的Git小命令,却收获快乐。
- Flutter路由的跳转、动画和传参详解(最简单)