目录
gcc 工具
gcc 是一款广泛使用的 C 语言编译器,可以根据需要生成 .o 目标文件、.a 静态库文件、.so 动态库文件以及 ELF 可执行文件等。
C 程序编译文件类型
-
.c:C 语言源代码文件;
-
.h:头文件;
-
.o:编译后的目标文件;
-
.a:由 .o 目标文件构成的静态库文件,用于静态链接。
-
.so:共享库文件,用于动态链接;
-
.i:已经预处理过的文件,不需要再对其执行预处理;
-
.s:汇编代码文件;
-
.S:经过预处理的汇编代码文件;
gcc 指令选项
gcc 指令的格式如下:
gcc [options] file1 file2 ...
-
-o {filename}
:指示输出文件的名称。 -
-l
:指示需要链接的函数库名称。可以是库文件的基本名称,也可以是完整的库文件名。值的注意的是,如果相同路径下具有同名的动静态库文件,那么会默认使用动态库,而使用静态库则需要使用 -static 说明。- 静态库文件 libmyib.a,使用 -lmylib,或 -l:libmyib.a,或 -l/path/to/libmyib.a(相当于同时使用了 -L)。
- 动态库文件 libmylib.so.1,使用 -lmylib,或 -l:libmyib.so.1,或 -l/path/to/libmyib.so.1(相当于同时使用了 -L)。
-
-L
:指示静态或动态库文件所在的 /lib/ 路径。通常用于非系统默认路径的场景中。 -
-g
:指示生成 GDB Debug 所需的符号信息。 -
-D<macro>
:定义一个宏,可以使用多次,例如:gcc -DDEBUG -DVERSION=1.0 file.c。 -
-U<macro>
:取消定义一个宏,例如:gcc -UDEBUG file.c。 -
-c
:指示只编译、不链接,通常用于编译不包含 main 主程序的子程序文件。 -
-E
:指示只进行预处理操作,生成预处理结果,可以使用该选项查看预处理后的代码。 -
-S
:指示只进行编译操作,生成汇编代码文件。 -
-fPIC
:生成位置无关的代码,生成共享库时使用。 -
-fno-stack-protector
:禁用栈保护,可以提高程序性能。 -
-O<level>
:指定编译和链接的优化等级,级别从 0 到 3,级别越高,优化程度越大。但编译和链接的速度更慢。 -
-v
:指示打印详细过程。 -
-Wall
:开启所有警告信息。 -
-Werror
:将所有警告信息视为错误信息。 -
-Wextra
:生成额外的警告信息。 -
-Wformat
:检查格式化字符串是否正确。 -
-Wshadow
:检查变量名是否与其他变量或函数名重复。 -
-Wuninitialized
:检查是否使用未初始化的变量。 -
-Wconversion
:检查类型转换是否正确。 -
-Wmissing-field-initializers
:检查结构体字段是否全部初始化。 -
-Wswitch-default
:检查 switch 语句是否包含 default 分支。 -
-Wstrict-prototypes
:检查函数声明是否严格符合 ANSI 标准。 -
-m32
:生成 32bits 程序,只适用于 x86 平台。 -
-m64
:生成 64bits 程序,只适用于 x86 平台。 -
-march=<arch>
:生成指定架构的代码,例如:-march=armv8-a,适用于 ARM 平台。 -
-mtune=<cpu>
:生成针对指定 CPU 优化的代码,例如:-mtune=cortex-a53,适用于 ARM 平台。 - 变量定义
- 规则定义
- 伪目标定义
- 指令定义
gcc 指令选项包括:
make 工具
为了方便 C 语言程序编译,在上个世纪 70 年代由 Stuart Feldman 在贝尔实验室开发了 make 自动化编译工具。make 一直是 UNIX-like 程序员最爱的程序构建(Construction)工具之一。
make 可以根据 makefile 中定义的 MakeRules 自动编译 C 程序。同时,它会通过检查 files 的修改时间,仅重新编译被修改的文件,缩短项目编译的时间。
makefile 语法
一个 makefile 通常包含以下 3 个部分的内容:
变量定义
makefile 的变量定义和 Shell 变量定义类似。变量的定义格式为:
# 定义
name=value
# 引用
${name}
- 2
- 3
- 4
- 5
主要关注 makefile build-in 的一些关键字变量。
-
$:表示引用一个变量,或执行一条指令。
- $^:表示当前规则中所有的依赖文件。
- $<:表示当前规则中的第一个依赖文件。
- $@:表示当前规则中的 target,例如:main.o: main.c 中的 main.o。
- $(shell pkg-config --exists libdpdk):执行 shell 指令。
- $(.SHELLSTATUS):获取上一条 shell 指令的执行结果。
-
%:表示任意字符串,例如:%.c、%.o 等。
-
CC:指定编译器的路径和名称,默认为 gcc。
-
CFLAGS:指定编译器的选项,包括:预处理、编译、汇编等过程的选项。
-
LD:指定链接器的路径和名称,默认为 ld。
-
LDFLAGS:指定链接器的选项,包括:要链接的库列表、库文件的搜索路径等。
-
AR:指定静态库文件生成工具的路径和名称。
-
LIBS:指定链接时需要的库文件名称,通常用于指定动态库文件名称。
-
SRC-y:指定源文件列表,用空格分割。
-
VPATH:指定源文件的搜索路径,用冒号分隔。
-
INCLUDES:指定头文件的搜索路径,用空格分隔。
-
DEPENDS:指定依赖关系文件的名称,通常用于指示源文件和头文件之间的依赖关系。
-
OBJDIR:指定目标文件的输出路径。
-
RM:指定删除文件的命令,默认为 rm -f。
规则定义
makefile 用于存放多条 MakeRules,每条 Rule 的基本格式如下:
<target>: <prerequisites>
[tab]<recipe>
- 2
<target>
:表示一个编译目标。<prerequisites>
:表示编译目标的各类文件依赖关系。<recipe>
:表示编译目标要执行的具体指令。
伪目标定义
通常会使用伪目标来定义多个 make targets,这些 target 可能是真实的编译目标,也可能希望执行的 Shell 指令集。
- .PHONY:用于声明一个伪目标,用空格分割。
指令定义
makefile 中内置了一些指令:
- ifeq / else / endif:条件判断指令。
$(shell pkg-config --exists libdpdk)
ifeq ($(.SHELLSTATUS),0)
...
else
...
ifeq ($(RTE_SDK),)
...
endif
...
endif
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- include:导入指令,用于导入其他的 Extend makefile。
makefile 示例
# 变量定义
CC = gcc
CFLAGS = -Wall -O2
# 规则定义
myprog: main.o foo.o bar.o
$(CC) -o myprog main.o foo.o bar.o
main.o: main.c
$(CC) $(CFLAGS) -c main.c
foo.o: foo.c
$(CC) $(CFLAGS) -c foo.c
bar.o: bar.c
$(CC) $(CFLAGS) -c bar.c
# 伪目标定义
.PHONY: clean
clean:
rm -f myprog *.o
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
make 指令选项
make 指令的语法如下:
make [options] [target]
-f <file>
:指定 makefile 的名称,默认为 Makefile 或 makefile。-n
:显示 make taget 要执行的命令,但不实际执行。-j <num>
:指定 make 的并行数量。-C <dir>
:指定 make 的工作目录。
其中,target 用于指定要执行的目标,通常定义在伪目标列表中。如果未指定,则默认执行第一个 Rule。
常用的 options 包括: