C编译器
gcc
GCC(GNU Compiler Collection)是Linux和macOS系统上常用的C语言编译器。Windows系统上可以使用MinGW来编译C语言程序。
常用编译命令:
编译选项 | 说明 | 示例 |
---|---|---|
-c | 只编译和汇编,不链接 | gcc -c hello.c -o hello.o |
-D | 定义宏 | gcc hello.c -DMY_MACRO=1 -o hello |
-E | 只进行预处理,不编译 | gcc -E hello.c -o hello.i |
-fPIC | 生成位置无关代码(常用于共享库) | gcc -fPIC hello.c -o hello.o |
-g | 生成调试信息 | gcc hello.c -g -o hello |
-I | 指定头文件的搜索路径 | gcc hello.c -I/path/to/headers -o hello |
-L | 指定库文件的搜索路径 | gcc hello.c -L/path/to/libs -lmylib -o hello |
-l | 链接指定的库 | gcc hello.c -lm -o hello (链接数学库) |
-O | 优化级别(0-3) | gcc hello.c -O2 -o hello |
-o | 指定输出文件名 | gcc hello.c -o hello |
-S | 只编译,不汇编和链接 | gcc -S hello.c -o hello.s |
-shared | 生成共享库 | gcc -shared hello.o -o libhello.so |
-static | 静态链接库 | gcc hello.c -static -o hello |
-std= | 指定C语言标准 | gcc hello.c -std=c11 -o hello |
-U | 取消宏定义 | gcc hello.c -UMY_MACRO -o hello |
-v | 详细输出编译过程 | gcc -v hello.c -o hello |
-Wall | 显示所有警告信息 | gcc hello.c -Wall -o hello |
优化等级说明
优化等级 | 说明 |
---|---|
-O0(无优化) | 这是默认的优化等级。编译器不会尝试进行任何优化,主要关注于生成正确且易于调试的代码。 |
-O1(基本优化) | 这个级别执行一些基本的优化,如删除未使用的变量、内联简单函数等。这些优化可以提高代码的执行效率,同时保持较快的编译速度。 |
-O2(中级优化) | 在基本优化的基础上进行更多的优化,包括更大范围的内联、循环展开、函数调用图优化等。这些优化可以显著提高代码的性能,但编译时间可能会稍长。 |
-O3(高级优化) | 在中级优化的基础上进行更深入的优化,如更大范围的内联、循环变形、自动向量化等。这些优化可以进一步提高代码的性能,但编译时间可能大幅增加。 |
-Os(优化大小) | 此级别旨在优化代码的尺寸,尽量减小可执行文件的大小。这对于在资源受限的环境中运行程序(如嵌入式系统)可能很有用。 |
-Og(优化调试) | 这个级别主要用于优化调试体验。它会在保持调试信息的同时,尽量提高代码的运行效率。 |
此外,GCC还提供了一些其他的优化选项,如 -Ofast
(更快但不安全的优化)等。
请注意,选择适当的优化等级取决于项目的需求和目标。在某些情况下,可能需要权衡代码的执行效率、编译时间和生成的代码大小等因素。
ar
ar
命令在 Linux 系统中用于创建、修改和提取静态库文件(.a
文件)。
常用编译选项:
编译选项 | 说明 | 示例 |
---|---|---|
a | 在库中的一个成员后面添加文件 | ar rv lib.a a.o b.o |
c | 创建库 | ar rc lib.a a.o b.o |
d | 从库中删除模块 | ar d lib.a a.o |
i | 在库的一个已存在的成员前面插入文件 | ar riv lib.a new.o |
m | 移动库中的成员 | ar mv lib.a a.o b.o |
p | 打印库中的文件到标准输出 | ar p lib.a |
q | 快速添加文件到库,不检查重复 | ar rq lib.a a.o |
r | 替换或添加文件到库 | ar r lib.a a.o |
s | 若库中包含了对象文件,则创建符号表 | ar rs lib.a a.o |
t | 列出库中的文件 | ar t lib.a |
v | 显示详细信息 | ar rv lib.a a.o |
x | 从库中提取文件 | ar x lib.a a.o |
ar
命令的选项可以组合使用,例如 ar rc
用于创建库并添加文件,ar rv
用于替换或添加文件并显示详细信息。
objdump
编译选项 | 说明 | 示例 |
---|---|---|
-S | 反汇编并显示源代码 | objdump -S demo.out > demo.s |
gdb
核心转储
linux中,常将“主内存”称为“核心(core)”,而“核心映像(core image)”就是“进程(process)”执行时所占用的内存。
当进程发生错误或收到信号时而终止执行时,内核会创建一个“核心映像”,并将其保存到磁盘中(用做调试)。这就是核心转储
- 可以通过设置
ulimit -c unlimited
来开启核心转储功能。
# 只要磁盘足够,不限制产生core的大小。(临时开启)
ulimit -c unlimited
# 永久开启
echo "ulimit -c unlimited" >> /etc/profile
# core 最大限制为409600字节
ulimit -c 409600
# 核心转储关闭
ulimit -c 0
- core文件生成路径 若gdb调试时,程序异常已停止执行,但是core文件没有生成,则可以查看
/proc/sys/kernel/core_pattern
文件内容。
# root用户下,实测sudo提权无效
echo "core" > /proc/sys/kernel/core_pattern
- gdb调试 测试代码示例
#include <stdio.h>
int main(int argc, char *argv[])
{
int *p = NULL;
printf("null pointer test\n");
*p = 10;
printf("hello world\n");
return 0;
}
编译并执行
gcc -g test.c -o test
./test
gdb test core