c/c++ 项目基础
文章目录
c/c++ 可以说是现代软件的基石,类库繁多,构建工具也很多。
在介绍构建工具前,我打算梳理一下 c/c++ 体系的一些基本概念。
1. 编译器
编译器的目的是编译源代码,生成可执行文件或类库文件。
典型的编译器组成部分如下:
- 前端
- 优化器
- 后端
嗯?什么,前端不是写 js 的吗?怎么编译器也有前端了? 请听我娓娓道来
1.1 前端
编译器的前端不同于软件开发中的前端,它的主要任务是词法分析、语法分析和语义分析。
词法分析的任务是将源代码分割成一个个的词法单元,比如 int
、main
、(
、)
、{
、}
、;
、return
、0
、;
。
语法分析的任务是将词法单元组合成语法单元,比如 int main() { return 0; }
。
语义分析的任务是检查语法单元是否符合语法规则,比如 int main() { return 0; }
是合法的,而 int main() { return 0 }
是不合法的。
一般来说,编译器的前端会生成一棵语法树(AST),AST 这个词就很眼熟了,经常在各种演讲炫耀中听到,全称是抽象语法树(Abstract Syntax Tree)。
咱们听到 react/flutter 中的摇树优化(tree shaking)就是摇这个玩意。
1.2 优化器
优化器在分类时其实属于后端,但是现在通常会单独提出来作为一部分。
优化器的任务是对语法树进行优化。因为编译的本质是将源码转为二进制,所以优化器的优化目标是二进制代码,而不是源码。
它可以做一些显而易见的事,比如将 int a = 1 + 2;
优化成 int a = 3;
。这样可以减少运行时的执行步骤。
当然,现代的 ide 会提示你合并,但是那和本文无关。
1.3 后端
后端的任务是将语法树转为目标代码。
1.4 常见的编译器
在介绍构建工具之前,我们先来看看常见的编译器。
- gcc: GNU Compiler Collection,GNU 的编译器集合,包含了 c/c++ 编译器、汇编器、链接器等。
- llvm: Low Level Virtual Machine,低级虚拟机,是一个编译器工具链,包含了编译器前端、优化器、后端、汇编器、链接器等。clang 是 llvm 的一个前端。
- msvc: Microsoft Visual C++,微软的 c/c++ 编译器,包含了编译器前端、优化器、后端、汇编器、链接器等。
除此以外,其他的都是偏小众的,就不说了。
个人建议,如果你是 linux 用户,那么 clang/llvm 是你的首选,如果你是 windows 用户,那么 msvc 是你的首选。 macOS 用户,直接使用 xcode 带的 clang,如果是交叉编译到 Android,可以使用 NDK 中的 clang。
2. 构建工具
然后,就到了构建工具的时间了。
为什么需要构建工具?
因为编译器本质上执行的是一个一个文件的编译,而现代软件的项目通常是由多个文件组成的,所以需要一个工具来协调编译器的工作。 而构建工具就是用来做这个事情的。 它们的主要任务是:
- 读取环境变量或构建工具的参数或配置文件
- 生成编译器的命令行参数
- 执行编译、链接、打包等操作
有一些常见的构建工具
- Autotools
- CMake
- Meson
- Microsoft Visual Studio
- Xcode
- Android Studio
它们涵盖了 99%的场景。
前三个是跨平台的,后三个是平台相关的。
2.1 Autotools
Autotools 是 GNU 的构建工具,它的主要特点是跨平台,配置编译器、编译参数,然后打包。
常用步骤是 ./configure
、make
、make install
。
2.2 CMake
CMake 是跨平台的构建工具,它也是目前最流行的构建工具之一。
常用步骤是 cmake
、make
、make install
。
2.3 Meson
Meson 是跨平台的构建工具,它的主要特点使用了 python 语法,配置文件比 autotools 和 cmake 更加易读。
常用步骤是 meson
、ninja
、ninja install
。
2.4 Microsoft Visual Studio
Microsoft Visual Studio 是微软的 IDE,它的主要特点是集成了编译器、调试器、构建工具等。 号称宇宙最强 IDE,主要用于 Windows 开发。
内置的构建工具是 msbuild
。
2.5 Xcode
Xcode 是苹果的 IDE,它的主要特点是集成了编译器、调试器、构建工具等。 主要用于 macOS/iOS 开发。
内置的构建工具是 xcodebuild
。
2.6 Android Studio
Android Studio 是谷歌的 IDE,它主要用于 Android 开发。
内置的构建工具是 gradle
。集成的用于构建 c/c++ 的构建工具是 cmake
。
底层的构建工具是 NDK。
ninja or make
ninja 和 make 都是构建工具,但与cmake、meson等构建工具不同,它们只负责执行构建。
因为语法简单、直观,所以很多构建工具都会生成ninja或make的构建文件。 然后通过 ninja 或 make 来执行构建。
ninja 在构建速度评测上完全超越了 make,所以如果你的构建工具支持 ninja,那么就推荐ninja。
目前,cmake、meson 可以生成 ninja 构建文件。
3. 调试器
调试器的主要任务是调试程序,它可以让你在程序运行时查看变量的值、执行步骤、堆栈信息等。
调试器的分类:
- 交互式调试器
- gdb: GNU Debugger,GNU 的调试器
- lldb: Low Level Virtual Machine Debugger,低级虚拟机调试器
- 非交互式调试器
- strace: Linux 的系统调用跟踪工具
- dtruss: macOS 的系统调用跟踪工具
3.1 gdb
gdb 是 GNU 的调试器,它的主要特点是交互式调试,支持多种语言。
3.2 lldb
lldb 是 LLVM 的调试器,它的主要特点是交互式调试,支持多种语言。
3.3 strace
strace 是 Linux 的系统调用跟踪工具,它的主要特点是非交互式调试,只能跟踪系统调用。
3.4 dtruss
dtruss 是 macOS 的系统调用跟踪工具,它的主要特点是非交互式调试,只能跟踪系统调用。
4. 其他工具
除了编译器、构建工具、调试器以外,还有一些其他的工具。
- 静态分析工具
- clang-tidy
- 动态分析工具
- valgrind
- perf
- 代码格式化工具
- clang-format
- clang-format-diff
- clang-tidy-diff
- 代码检查工具
- clang-tidy
- clang-check
- 其他工具
- git
- svn
- hg
4.1 静态分析工具
静态分析工具是用来分析源代码的,它用来检查代码是否符合规范,是否有潜在的 bug 等。
常用的静态分析工具是 clang-tidy。
4.2 动态分析工具
动态分析工具是用来分析程序运行时的,它用来检查程序是否有潜在的 bug 等。
常用的动态分析工具是 valgrind 和 perf。
4.3 代码格式化工具
代码格式化工具是用来格式化源代码的,它的主要特点是可以统一代码风格。
常用的代码格式化工具是 clang-format。
4.4 代码检查工具
代码检查工具是用来检查代码的,它的主要特点是可以检查代码中的 bug。
常用的代码检查工具是 clang-tidy。
5. 总结
这篇文章主要介绍了常见的 c/c++ 开发工具,以上。