C 语言编程 — GCC 自动化编译工具集

目录

文章目录

  • 目录
  • gcc 工具
    • C 程序编译文件类型
    • gcc 指令选项
  • make 工具
    • makefile 语法
      • 变量定义
      • 规则定义
      • 伪目标定义
      • 指令定义
      • makefile 示例
    • make 指令选项

gcc 工具

gcc 是一款广泛使用的 C 语言编译器,可以根据需要生成 .o 目标文件、.a 静态库文件、.so 动态库文件以及 ELF 可执行文件等。

C 程序编译文件类型

  • .c:C 语言源代码文件;

  • .h:头文件;

  • .o:编译后的目标文件;

  • .a:由 .o 目标文件构成的静态库文件,用于静态链接。

  • .so:共享库文件,用于动态链接;

  • .i:已经预处理过的文件,不需要再对其执行预处理;

  • .s:汇编代码文件;

  • .S:经过预处理的汇编代码文件;

gcc 指令选项

gcc 指令的格式如下

gcc [options] file1 file2 ...

gcc 指令选项包括

  • -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:定义一个宏,可以使用多次,例如:gcc -DDEBUG -DVERSION=1.0 file.c。

  • -U:取消定义一个宏,例如:gcc -UDEBUG file.c。

  • -c:指示只编译、不链接,通常用于编译不包含 main 主程序的子程序文件。

  • -E:指示只进行预处理操作,生成预处理结果,可以使用该选项查看预处理后的代码。

  • -S:指示只进行编译操作,生成汇编代码文件。

  • -fPIC:生成位置无关的代码,生成共享库时使用。

  • -fno-stack-protector:禁用栈保护,可以提高程序性能。

  • -O:指定编译和链接的优化等级,级别从 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=:生成指定架构的代码,例如:-march=armv8-a,适用于 ARM 平台。

  • -mtune=:生成针对指定 CPU 优化的代码,例如:-mtune=cortex-a53,适用于 ARM 平台。

make 工具

为了方便 C 语言程序编译,在上个世纪 70 年代由 Stuart Feldman 在贝尔实验室开发了 make 自动化编译工具。make 一直是 UNIX-like 程序员最爱的程序构建(Construction)工具之一。

make 可以根据 makefile 中定义的 MakeRules 自动编译 C 程序。同时,它会通过检查 files 的修改时间,仅重新编译被修改的文件,缩短项目编译的时间。

makefile 语法

一个 makefile 通常包含以下 3 个部分的内容:

  1. 变量定义
  2. 规则定义
  3. 伪目标定义
  4. 指令定义

变量定义

makefile 的变量定义和 Shell 变量定义类似。变量的定义格式为:

# 定义
name=value

# 引用
${name}

主要关注 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>
  • :表示一个编译目标。
  • :表示编译目标的各类文件依赖关系。
  • :表示编译目标要执行的具体指令。

伪目标定义

通常会使用伪目标来定义多个 make targets,这些 target 可能是真实的编译目标,也可能希望执行的 Shell 指令集。

  • .PHONY:用于声明一个伪目标,用空格分割。

指令定义

makefile 中内置了一些指令:

  • ifeq / else / endif:条件判断指令。
$(shell pkg-config --exists libdpdk)
ifeq ($(.SHELLSTATUS),0)
...
else
...

ifeq ($(RTE_SDK),)
...
endif

...
endif
  • 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

make 指令选项

make 指令的语法如下:

make [options] [target]

其中,target 用于指定要执行的目标,通常定义在伪目标列表中。如果未指定,则默认执行第一个 Rule。

常用的 options 包括:

  • -f :指定 makefile 的名称,默认为 Makefile 或 makefile。
  • -n:显示 make taget 要执行的命令,但不实际执行。
  • -j :指定 make 的并行数量。
  • -C :指定 make 的工作目录。

你可能感兴趣的:(C,语言,c语言,自动化,开发语言)