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标识符指定包含的范围。这对库很重要,将在下一个示例中说明。有关此功能的更多详细信息,请参见此处。
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的参数含义是:
对于public headers,通常最好将include文件夹与子目录进行 “命名间隔(namespaced)”。
传递给target_include_directories的目录将是包含目录树的根,并且C++文件应包括从此处到标头的路径。
对于此示例,您可以看到我们按以下方式进行操作:
#include "static/Hello.h"
使用此方法意味着在项目中使用多个库时,头文件名冲突的可能性较小。
创建将使用您的库的可执行文件时,必须告知编译器该库。可以使用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范围的任何包含目录。
以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
输出自己想要的名字。
是GCOV图形化的前端工具, 是Linux Test Project维护的开放源代码工具,最初被设计用来支持Linux内核覆盖率的度量。 基于Html输出,并生成一棵完整的HTML树,输出包括概述、覆盖率百分比、图表,能快速浏览覆盖率数据。 支持大项目,提供三个级别的视图:目录视图、文件视图、源码视图。
# 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目录。
当使用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开始,直至构建测试和测试套件。
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。
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 |
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 |
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。