cen's blog cen's blog
首页
  • 编程文章

    • markdown使用
  • 学习笔记

    • 《JavaScript教程》
    • C++学习
    • C++数据结构
    • MySQL
    • Linux
  • 高中时代
  • 工作日常
  • CLion
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

cen

十年饮冰,难凉热血
首页
  • 编程文章

    • markdown使用
  • 学习笔记

    • 《JavaScript教程》
    • C++学习
    • C++数据结构
    • MySQL
    • Linux
  • 高中时代
  • 工作日常
  • CLion
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • 技术文档

    • Git使用手册
    • Markdown使用教程
    • npm常用命令
    • cmake教程
      • Makefile
        • 规则
        • 伪目标(.PHONY)
      • cmake
        • 示例
    • npm packageJson属性详解
    • yaml语言教程
    • Git修改分支名
  • GitHub技巧

  • Nodejs

  • 博客搭建

  • CLion

  • 工具
  • 技术文档
cen
2025-05-08
目录

cmake教程

# Makefile

在Linux环境下,当我们输入make命令时,它就在当前目录查找一个名为Makefile的文件,然后,根据这个文件定义的规则,自动化地执行任意命令,包括编译命令。

Makefile这个单词,顾名思义,就是指如何生成文件。

# 规则

目标文件: 依赖文件1 依赖文件2...
  执行的命令
1
2

注意:Makefile的规则中,命令必须以Tab开头,不能是空格

例如:下面是一个简单的C++程序:

// main.cpp
#include <iostream>

int main() {
    std::cout << "Hello World!" << std::endl;
    return 0;
}
1
2
3
4
5
6
7

使用命令行g++ main.cpp -o main和./main来构建和执行代码,输出Hello World!

现在将程序复杂:

.
├── main
├── main.cpp
├── message.cpp
└── message.h
1
2
3
4
5

这时我们可以添加Makefile文件,更加方便构建:

project: main.cpp message.cpp
	g++ main.cpp message.cpp -o project
1
2

此时,make会新建一个project文件,./project执行后输出结果

更加规范地,可以把编译和链接过程分开编写:

project: main.o message.o
	g++ main.o message.o -o project

main.o: main.cpp
	g++ -c main.cpp

message.o: message.cpp
	g++ -c message.cpp
1
2
3
4
5
6
7
8

# 伪目标(.PHONY)

伪目标(Phony Target) 是一种特殊的“目标”,它并不代表一个实际的文件,而是用来执行某些特定操作的一组命令。常见的伪目标包括clean、install、all等。

  • clean
.PHONY:clean
clean:
	rm *.o project
1
2
3

.PHONY显式的表示clean是一个伪目标,这样make不会将clean当作文件名来处理

  • all
# ...
.PHONY:clean all
clean:
	rm *.o project
all:main.o message.o
	echo 'all done'
1
2
3
4
5
6

# cmake

CMake是一个跨平台的开源构建系统生成器,它简化了复杂软件项目的构建过程。不同于直接编写 Makefile,CMake 使用一种高级语言(CMakeLists.txt 文件)来描述如何编译和链接代码(自动生成Makefile文件)

# 示例

写一个简单的main函数,创建CMakeLists.txt

# 表明项目的最低版本号 3.10
cmake_minimum_required(VERSION 3.10)

# 声明项目名称
project(testCmake)

# 声明目标文件和依赖文件
add_executable(main main.cpp)
1
2
3
4
5
6
7
8

终端执行命令cmake .和make,最后./main输出结果

现在将程序复杂:

.
├── main
├── main.cpp
├── message01.cpp
├── message01.h
├── message02.cpp
└── message02.h
1
2
3
4
5
6
7
# 表明项目的最低版本号 3.10
cmake_minimum_required(VERSION 3.10)

# 声明项目名称
project(testCmake)

# 声明目标文件和依赖文件
add_executable(main main.cpp message01.cpp message02.cpp)
1
2
3
4
5
6
7
8

这里,如果我们的源文件太多的话,就会极不方便,可以用以下写法简化:

# 表明项目的最低版本号 3.10
cmake_minimum_required(VERSION 3.10)

# 声明项目名称
project(testCmake)

# 将当前目录的所有源文件保存在SRC_DIR中
aux_source_directory(. SRC_DIR)

# 声明目标文件和依赖文件
add_executable(main ${SRC_DIR})
1
2
3
4
5
6
7
8
9
10
11

但是我们看一下文件树

.
├── CMakeCache.txt
├── CMakeFiles
│   ├── 3.26.5
│   │   ├── CMakeCCompiler.cmake
│   │   ├── CMakeCXXCompiler.cmake
│   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   ├── CMakeSystem.cmake
│   │   ├── CompilerIdC
│   │   │   ├── a.out
│   │   │   ├── CMakeCCompilerId.c
│   │   │   └── tmp
│   │   └── CompilerIdCXX
│   │       ├── a.out
│   │       ├── CMakeCXXCompilerId.cpp
│   │       └── tmp
│   ├── cmake.check_cache
│   ├── CMakeConfigureLog.yaml
│   ├── CMakeDirectoryInformation.cmake
│   ├── main.dir
│   │   ├── build.make
│   │   ├── cmake_clean.cmake
│   │   ├── compiler_depend.internal
│   │   ├── compiler_depend.make
│   │   ├── compiler_depend.ts
│   │   ├── DependInfo.cmake
│   │   ├── depend.make
│   │   ├── flags.make
│   │   ├── link.txt
│   │   ├── main.cpp.o
│   │   ├── main.cpp.o.d
│   │   ├── message01.cpp.o
│   │   ├── message01.cpp.o.d
│   │   ├── message02.cpp.o
│   │   ├── message02.cpp.o.d
│   │   └── progress.make
│   ├── Makefile2
│   ├── Makefile.cmake
│   ├── pkgRedirects
│   ├── progress.marks
│   └── TargetDirectories.txt
├── cmake_install.cmake
├── CMakeLists.txt
├── main
├── main.cpp
├── Makefile
├── message01.cpp
├── message01.h
├── message02.cpp
└── message02.h
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

会发现太过于杂乱,为了更加规范,我们可以在bin文件夹存放生成的源码文件(a.out/.o/...),build文件夹存放(cmake产生的文件),include文件夹(存放头文件),src文件夹(存放源文件)。

# 表明项目的最低版本号 3.10
cmake_minimum_required(VERSION 3.10)

# 声明项目名称
project(testCmake)

# bin 存放生成的可执行文件
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# 将当前目录的所有源文件保存在SRC_DIR中
aux_source_directory(src SRC_DIR)

# include 存放头文件
include_directories(include)

# 声明目标文件和依赖文件
add_executable(main ${SRC_DIR})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

执行命令:

cd build
cmake ..
cd ..
make
cd buile/bin
./main
1
2
3
4
5
6

这样一来,目录树会更加清晰:

.
├── build
│   ├── bin
│   │   └── main
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.26.5
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── cmake.check_cache
│   │   ├── CMakeConfigureLog.yaml
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── main.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── compiler_depend.make
│   │   │   ├── compiler_depend.ts
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       ├── main.cpp.o
│   │   │       ├── main.cpp.o.d
│   │   │       ├── message01.cpp.o
│   │   │       ├── message01.cpp.o.d
│   │   │       ├── message02.cpp.o
│   │   │       └── message02.cpp.o.d
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── pkgRedirects
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   └── Makefile
├── CMakeLists.txt
├── include
│   ├── message01.h
│   └── message02.h
└── src
    ├── main.cpp
    ├── message01.cpp
    └── message02.cpp
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
上次更新: 2025/05/09, 14:02:34
npm常用命令
npm packageJson属性详解

← npm常用命令 npm packageJson属性详解→

最近更新
01
线程安全
05-21
02
项目
05-07
03
高中时代
05-07
更多文章>
Theme by Vdoing | Copyright © 2024-2025 京ICP备2020044002号-3 京公网安备11010502056119号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式