技术分享
GCC与make简述
00 分钟
2024-9-12
2024-10-28
type
status
date
slug
summary
tags
category
icon
password
😀
GCC 是一款强大的编译器,用于将 C、C++、Fortran、Ada 等编程语言编写的源代码编译成可执行的机器代码。

📝 GCC基本指令

输出可执行文件 -o

这个参数指定编译生成的可执行文件名称。默认情况下,GCC 会生成一个名为 a 的可执行文件。在Linux下只需要运行./a 就可以运行程序了。
 

生成目标文件 .o 文件 c

c 选项表示只编译源文件,不链接。它会生成目标文件(.o 文件),通常用于大型项目的分阶段编译。
举个栗子:
例如如下项目,EXAMPLE_GCC目录下有三个文件,其中a.cpp是主文件。
notion image
如果每次都执行g++ a.cpp printnum.cpp -o output 速度会很慢,这时我们就可以采用生成目标文件的方法: 首先,分别生成a.cpp和printnum.cpp的目标文件:
之后再将其目标文件进行链接:
这种方法的好处在于:如果只有少量文件的源码变动,只需要用-c 参数先生成其目标文件,之后再与别的目标文件进行链接即可。在大型工程中,省去了不必要的编译步骤。
 

启用调试信息 -g

-g 选项会在编译时生成调试信息。生成的可执行文件可以在调试器(如 gdb)中使用,方便调试源代码。
 

显示所有警告 Wall

-Wall 是最常用的选项之一,它会启用所有常见的警告信息,帮助你发现潜在的问题。这个选项在编译时提供有价值的提示,建议在开发阶段始终开启。
 

处理优化选项 -O

GCC 提供了不同级别的优化选项,适合不同的开发阶段:
  • O0:无优化(默认)。
  • O1:基本优化,适用于开发和调试。
  • O2:更高级的优化,适合发布版。
  • O3:最激进的优化,可能会增加代码大小和编译时间。
  • Os:优化代码体积,适合对内存和空间要求严格的场景。
  • Ofast:启用所有优化,包括可能违反标准的激进优化。
示例:
 

启用额外警告 -Wextra

-Wextra 会启用更多的警告(比 -Wall 包含的更多),帮助你更严格地检查代码。
 

标准版本控制 -std=

GCC 支持不同的 C++ 标准版本,通过 -std= 选项来指定。例如:
  • std=c++98:启用 C++98 标准。
  • std=c++11:启用 C++11 标准。
  • std=c++14:启用 C++14 标准。
  • std=c++17:启用 C++17 标准
  • std=c++20:启用 C++20 标准。
例如:
 

启用性能分析 pg

-pg 选项用于启用 gprof 性能分析工具。在编译时插入额外的代码,以便运行时收集性能分析信息,之后可以用 gprof 查看程序的性能瓶颈
 
 
💡
Make 是一个构建自动化工具,它通过读取一个名为 Makefile 的文件来自动化执行复杂的编译和构建任务。在大型项目中,手动编译每个文件、管理依赖项是很费时的,而 Make 提供了有效的解决方案。通过学习 Makefile 的结构、规则和功能,可以极大提高开发效率。

📝 make的基础使用

Makefile 的基本结构

一个典型的 Makefile 由以下部分组成:
  1. 变量(Variables):定义一些常用的值,避免重复输入。
  1. 规则(Rules)Makefile 的核心部分,定义了文件如何生成的规则。
  1. 命令(Commands):规则中的操作步骤,如编译、链接等。
  1. 依赖关系(Dependencies):指明目标文件的生成依赖哪些文件。

基本语法结构:

  • target:要生成的文件,通常是可执行文件或目标文件(.o)。
  • dependencies:生成目标文件所依赖的源文件或其他文件。
  • command:生成目标文件的命令。注意:命令行必须以 Tab 键开头
比如上面的例子用make实现:
这个 Makefile 做了以下事情:
  • 编译 a.oprintnum.o,分别依赖源文件 hello.cppworld.cpp
  • 生成可执行文件,它依赖 a.oprintnum.o
 

Makefile 变量

Makefile 中可以使用变量来避免重复输入命令和文件名。变量使用时需要加上 $()${}

变量定义和使用:

  • CC 变量表示使用的编译器,通常是 g++
  • CFLAGS 变量表示编译时的选项,例如 Wall 开启警告,g 启用调试信息。
使用变量不仅使 Makefile 更简洁,也方便以后修改编译器或编译选项。
 

自动变量

Make 提供了一些自动变量,用于简化规则中的命令。
常用的自动变量有:
  • $@:当前的目标文件(target)。
  • $<:第一个依赖文件(dependencies)。
  • $^:所有依赖文件列表。
例子:
解释:
  • $(CC) $^ -o $@$^ 代表所有依赖文件,即 hello.o world.o$@ 代表当前目标 hello
  • $(CC) $(CFLAGS) -c $<$< 代表第一个依赖文件,即 hello.cppworld.cpp
使用自动变量可以减少硬编码的文件名,进一步提高 Makefile 的通用性。
 

模式规则(Pattern Rules)

在项目中,我们通常有很多类似的规则,比如多个 .cpp 文件需要编译为 .o 文件。Makefile 提供了模式规则来简化这一过程。
例子:
解释:
  • %.o: %.cpp 是一个模式规则,表示所有 .o 文件依赖同名的 .cpp 文件。
  • $< 是自动变量,表示依赖的 .cpp 文件。
有了模式规则,Makefile 不需要为每个源文件单独写一条规则,这大大简化了文件编写。
 

伪目标(Phony Targets)

Makefile 中的一些目标并不对应实际的文件,例如 clean。为了避免与文件名冲突,Makefile 使用伪目标。
例子:
.PHONY: clean 声明 clean 是一个伪目标,表示它不是一个实际文件。即使目录中有名为 clean 的文件,Makefile 也会优先执行伪目标的规则。
常见的伪目标:
  • clean:清理生成的中间文件。
  • all:编译所有目标文件。
  • install:安装文件到指定位置。
 
上一篇
双序列比对 Pairwise sequence alignment ——序列比对Sequence Alignment.
下一篇
NumPy学习笔记(二)一维数组、NumPy的数据类型、常见的一维数组生成函数