cmake实战练习

cmake实战练习

测试环境

系统环境

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
inxi -b
<<'CONTENT'
System:
  Host: VM-4-17-ubuntu Kernel: 6.8.0-71-generic arch: x86_64 bits: 64
  Console: pty pts/0 Distro: Ubuntu 24.04 LTS (Noble Numbat)
Machine:
  Type: Kvm System: Tencent Cloud product: CVM v: 3.0 serial: 6b3a36b3-a76e-48d4-90af-df94e3af521d
  Mobo: N/A model: N/A serial: N/A BIOS: SeaBIOS v: seabios-1.9.1-qemu-project.org
    date: 04/01/2014
CPU:
  Info: dual core AMD EPYC 7K62 [MCP] speed (MHz): avg: 2595
Graphics:
  Device-1: Cirrus Logic GD 5446 driver: cirrus v: kernel
  Display: server: No display server data found. Headless machine? tty: 209x58
  API: OpenGL v: 4.5 vendor: mesa v: 25.2.8-0ubuntu0.24.04.1 note: console (EGL sourced)
    renderer: llvmpipe (LLVM 20.1.2 256 bits)
Network:
  Device-1: Intel 82371AB/EB/MB PIIX4 ACPI type: network bridge driver: piix4_smbus
  Device-2: Red Hat Virtio network driver: virtio-pci
Drives:
  Local Storage: total: 560 GiB used: 216.64 GiB (38.7%)
Info:
  Memory: total: 4 GiB available: 3.64 GiB used: 1.04 GiB (28.5%)
  Processes: 131 Uptime: 11d 2h 53m Init: systemd target: graphical (5) Shell: Bash inxi: 3.3.34
CONTENT

准备软件环境

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 更新软件源
apt install update

# 安装cmake和gtest库
sudo apt install cmake libgtest-dev

# 编译gtest库
cd /usr/src/gtest
mkdir build; cd build
sudo cmake ..
sudo make -j$((2*$(nproc)))
sudo cp lib/*.a /usr/lib
cmake版本
1
2
3
4
5
6
cmake --version
<<'CONTENT'
cmake version 3.28.3

CMake suite maintained and supported by Kitware (kitware.com/cmake)
CONTENT
安装vim并简单配置vim的vimrc文件
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 单独粘贴运行,更新用户的缓存信息,让密码有效期延长5分钟
sudo -v

# 批量粘贴运行
sudo apt install -y vim
if [ ! -f "/etc/vim/vimrc_bak" ]; then
  sudo cp /etc/vim/vimrc /etc/vim/vimrc_bak
fi
sudo tee -a /etc/vim/vimrc << 'EOF'
" vimrc for me
set nu
set ai
set si
set sw=4
set ts=4
set mouse=a
noremap <C-a> <Esc>ggVG "全选
syntax enable
syntax on
EOF

准备测试项目

目录结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
tree MyProject
<<'CONTENT'
MyProject/
├── build
├── CMakeLists.txt
├── src
│   ├── CMakeLists.txt
│   ├── include
│   │   └── mylib.h
│   ├── lib
│   │   ├── module1.cpp
│   │   └── module2.cpp
│   └── main.cpp
└── tests
    ├── CMakeLists.txt
    └── test_main.cpp

6 directories, 8 files
CONTENT

创建目录结构

创建了目录结构后,后边的代码可直接通过cat命令创建并追加对应的内容到对应的文件中

1
2
3
4
5
mkdir -p ./MyProject/
mkdir -p ./MyProject/src
mkdir -p ./MyProject/src/lib
mkdir -p ./MyProject/src/include
mkdir -p ./MyProject/tests

创建CMakeLists.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
find ./MyProject -name "CMakeLists.txt" -exec bash -c $'echo -e "\n# === {} ==="; echo "cat - > {} <<\'EOF\'"; cat "{}"; echo "EOF"' {} \;

# === ./MyProject/src/CMakeLists.txt ===
cat - > ./MyProject/src/CMakeLists.txt <<'EOF'
# 创建库目标
add_library(MyLib STATIC
        lib/module1.cpp
        lib/module2.cpp
)

# 指定库的头文件
target_include_directories(MyLib PUBLIC ${CMAKE_SOURCE_DIR}/src/include)

# 创建可执行文件目标
add_executable(MyExecutable main.cpp)

# 链接到可执行文件
target_link_libraries(MyExecutable PRIVATE MyLib)
EOF

# === ./MyProject/CMakeLists.txt ===
cat - > ./MyProject/CMakeLists.txt <<'EOF'
# 指定最低 CMake 版本
cmake_minimum_required(VERSION 3.28)
# 定义项目名称和版本
project(MyProject VERSION 1.0)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 包含头文件路径
include_directories($(PROJECT_SOURCE_DIR)/src/include)

# 添加子目录
add_subdirectory(src)
add_subdirectory(tests)
EOF

# === ./MyProject/tests/CMakeLists.txt ===
cat - > ./MyProject/tests/CMakeLists.txt <<'EOF'
# 查找 GTest 包
find_package(GTest REQUIRED)

# 创建测试目标
add_executable(TestMyLib test_main.cpp)

# 链接库和 GTest 到测试目标(使用现代 CMake 方式)
target_link_libraries(TestMyLib PRIVATE
    MyLib
    GTest::gtest      # Google Test 库
    GTest::gtest_main # 提供 main 函数的库
)

# 可选:启用测试
enable_testing()
add_test(NAME TestMyLib COMMAND TestMyLib)
EOF

编写源代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
find ./MyProject -type f ! -name "CMakeLists.txt" -name "*" -exec bash -c $'echo -e "\n# === {} ==="; echo "cat - > {} <<\'EOF\'"; cat "{}"; echo "EOF"' {} \;

# === ./MyProject/src/main.cpp ===
cat - > ./MyProject/src/main.cpp <<'EOF'
#include <iostream>
#include "mylib.h"

int main() {
        std::cout << "Hello, CMake!" << std::endl;
        return 0;
}
EOF

# === ./MyProject/src/lib/module2.cpp ===
cat - > ./MyProject/src/lib/module2.cpp <<'EOF'
#include "mylib.h"

// Implementation of module2
EOF

# === ./MyProject/src/lib/module1.cpp ===
cat - > ./MyProject/src/lib/module1.cpp <<'EOF'
#include "mylib.h"

// Implementation of module1
EOF

# === ./MyProject/src/include/mylib.h ===
cat - > ./MyProject/src/include/mylib.h <<'EOF'
#ifndef MYLIB_H
#define MYLIB_H

// Declarations of module functions

#endif // MYLIB_H
EOF

# === ./MyProject/tests/test_main.cpp ===
cat - > ./MyProject/tests/test_main.cpp <<'EOF'
#include <gtest/gtest.h>
// Test cases for MyLib
TEST(MyLibTest, BasicTest) {
        EXPECT_EQ(1, 1);
}
EOF

编译和测试

1
2
3
4
5
6
7
8
# 进入项目根目录
cd MyProject
# 创建构建目录
mkdir build; cd build
# 配置项目
cmake ..
# 编译项目
make -j$((2*$(nproc)))

运行

构建目录目录结构
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
tree -L 2 ../build/
<<'CONTENT'
../build/
├── CMakeCache.txt
├── CMakeFiles
│   ├── 3.28.3
│   ├── cmake.check_cache
│   ├── CMakeConfigureLog.yaml
│   ├── CMakeDirectoryInformation.cmake
│   ├── CMakeScratch
│   ├── Makefile2
│   ├── Makefile.cmake
│   ├── pkgRedirects
│   ├── progress.marks
│   └── TargetDirectories.txt
├── cmake_install.cmake
├── Makefile
├── src
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── libMyLib.a
│   ├── Makefile
│   └── MyExecutable
└── tests
    ├── CMakeFiles
    ├── cmake_install.cmake
    ├── CTestTestfile.cmake
    ├── Makefile
    └── TestMyLib

9 directories, 18 files
CONTENT
运行可执行文件
1
./src/MyExecutable
运行测试
1
./tests/TestMyLib
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计