CMake小窥

CMake构建模版

最简单的单级目录

1
2
3
cmake_minimum_required (VERSION 2.6)   #版本要求
project (Tutorial) #工程名称
add_executable(Tutorial tutorial.cpp) #制定生成目标

多级目录

头文件和源文件分别存储在include和src中。

1
2
3
4
5
6
7
8
9
10
11
12
cmake_minimum_required(VERSION 3.10)
project(hello_world)

set(CMAKE_CXX_STANDARD 17)

# 添加头文件搜索路径
include_directories(${PROJECT_SOURCE_DIR}/include)

# 添加源文件路径
aux_source_directory(${PROJECT_SOURCE_DIR}/src DIR_SRCS)

add_executable(Hello ${DIR_SRCS})

大型项目

每个目录下都要有CMakeLists.txt,通过add_subdirectory进行递归构建。

实战:构建gteset进行测验

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
├── CMakeLists.txt
├── build # 用于构建
├── code # 代码目录
│ ├── CMakeLists.txt # add_subdirectory(source)
│ ├── include
│ │ └── hello.h
│ └── source
│ ├── CMakeLists.txt
│ └── hello.cpp
└── test # 测试代码目录
├── CMakeLists.txt
├── googletest
├── hello_test.cc
└── main.cpp

最外层CMake

1
2
3
4
5
6
7
cmake_minimum_required(VERSION 3.10)
project(hello_test)

set(CMAKE_CXX_STANDARD 17)

add_subdirectory(code)
add_subdirectory(test)

没什么好说的,就是添加两个子文件夹内的Cmake。

code目录

code目录主要依靠source目录下的CMakeLists。注意这里是构建静态库而不是构建可执行文件,因为我们的可执行文件是在test目录下构建的。

1
2
3
4
5
6
# 添加头文件路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
# 添加源文件
aux_source_directory(. src_list)
# 构建静态库
add_library(hello ${src_list})

test目录

我们的目的是测试code目录下的代码,main文件为固定的模版,用于启动所有测试;hello_test文件用于测试code目录下的打印hello函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// main.cpp
#include <iostream>
#include <gtest/gtest.h>

using namespace std;

int main(int argc, char *argv[]){
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
// hello_test.cpp
#include <gtest/gtest.h>
#include "hello.h"

TEST(HelloTest, BasicAssertions) {
print_hello();
EXPECT_STRNE("hello", "world");
EXPECT_EQ(7 * 6, 42);
}

googletest目录通过主动构建形成。

1
2
3
4
5
git clone https://github.com/google/googletest.git -b v1.15.2
cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output.
cd build
cmake .. # Generate native build scripts for GoogleTest.

那么CMake该怎么写呢?

1
2
3
4
5
6
7
8
9
10
11
12
# 添加头文件
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../code/include)
# 添加googleTest的cmake,EXCLUDE_FROM_ALL指示make不要构建googletest目录下的内容(前面已经构建过了)
add_subdirectory(googletest EXCLUDE_FROM_ALL)
# 添加源文件
aux_source_directory(. exe_src)
# 设置输出路径(重要,否则将找不到可执行文件)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/build)
# 链接库
add_executable(helloTest ${exe_src})
target_link_libraries(helloTest gtest)
target_link_libraries(helloTest hello)

执行

1
2
3
$ cd build && camke ..
$ make
$ ./helloTest

输出,可以看到中间打印了hello。

1
2
3
4
5
6
7
8
9
10
11
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from HelloTest
[ RUN ] HelloTest.BasicAssertions
hello
[ OK ] HelloTest.BasicAssertions (0 ms)
[----------] 1 test from HelloTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
作者

Desirer

发布于

2025-01-19

更新于

2025-01-19

许可协议