gcc工具的概述和使用
# gcc工具的概述和使用
在GCC(GNU Compiler Collection)套件中,gcc是其中最核心的一个工具,它是GNU C Compiler的缩写。
# gcc工具概述
# gcc与g++的比较
程序 g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。通过遵循源码的命名规范并指定对应库的名字,用 gcc 来编译链接 C++ 程序是可行的。
# gcc支持的文件
后缀名 | 所支持的文件 |
---|---|
.c | C源程序 |
.C | C++源程序 |
.cc | C++源程序 |
.cxx | C++源程序 |
.m | Objective C源程序 |
.i | 经过预处理的C源程序 |
.ii | 经过预处理的C++源程序 |
.s | 汇编语言源程序 |
.S | 汇编语言源程序 |
.h | 头文件 |
.o | 目标文件 |
.a | 存档文件 |
# 用gcc编译程序时,分为四个阶段
编译阶段 | 分步编译命令举例 |
---|---|
预处理(pre-processing) | gcc –E hello.c –o hello.i |
编译(compiling) | gcc –S hello.c –o hello.s |
汇编(assembling) | gcc –c hello.c –o hello.o |
链接(linking) | gcc hello.c –o hello |
程序员可以根据需要在任何一阶段停止。
# gcc的常用选项
选项 | 功能 |
---|---|
-c | 指示gcc生成目标文件,而不是生成可执行文件(取消了连接步骤)。 |
-S | 要求编译程序生成来自源代码的汇编程序输出。 |
-o | 指定生成的可执行文件或目标文件的名称。 |
-g | 生成包含调试信息的可执行文件或目标文件,便于调试程序。 |
-Wall | 开启警告信息输出,可以帮助发现潜在的问题。 |
-Werror | 将警告信息视为错误,编译过程中出现警告会导致编译失败。 |
-std | 指定使用的C/C++语言标准,如-std=c99、-std=c++11等。 |
-IDIRNAME | 将DIRNAME加入到头文件搜索的路径中。 |
-LDIRNAME | 将DIRNAME加入到库文件搜索的路径中。 |
-llibrary | 提示连接程序在创建最终可执行文件时包含指定的库。 |
-O,-O2,-O3 | 将优化状态打开,该选项不能与-g选项联合使用。 |
-D | 定义宏变量,可以在源代码中使用#ifdef 进行条件编译。 |
-static | 对库文件进行静态链接(不加默认进行动态链接)。 |
# gcc使用举例
# 编译单文件
// hello.c
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
$ gcc hello.c -o hello
$ ./hello
hello world
1
2
3
2
3
# 编译多个文件
// fun.h
#ifndef FUN_H
#define FUN_H
void fun();
#endif //FUN_H
// fun.c
#include <stdio.h>
void fun()
{
printf("in fun()\n");
}
// main.c
#include <stdio.h>
#include "fun.h"
int main()
{
fun();
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ gcc main.c fun.c -o main
$ ./main
in fun()
1
2
3
2
3
用一条gcc命令编译多源文件程序的缺点:每个文件都要重新编译。
# gcc的库依赖
函数库:头文件(.h)+库文件(.so、.a)
系统能够识别的默认路径
头文件:/usr/include
库文件:/usr/lib
使用非默认路径的文件需在编译时指定路径
头文件用-I
库文件用-L
以上面编译多个文件的代码为例
$ gcc -fPIC -shared fun.c -o libfun.so
1
-fPIC
选项表示生成位置独立的代码(Position Independent Code),即编译生成的代码可以在任意地址执行,不依赖于特定的内存地址。这是生成动态链接库所必须的选项,因为动态链接库在运行时需要被加载到进程的任意内存地址。-shared
选项表示生成动态链接库,而不是可执行文件。动态链接库包含了可重用的代码和数据,可以在多个进程中共享,减少内存占用并提高程序运行效率。
$ gcc main.c -o main -L. -lfun
1
编译生成可执行文件main并链接到./
下的动态库libfun.so
。
# gcc的警告与提示
选项 | 描述 |
---|---|
-Wcomment | 如果出现注释嵌套则警告(/* 后又出现/* ) |
-Wformat | 如果传递给printf的参数与指定格式不匹配则警告 |
-Wmain | 如果main的返回类型不是int或者调用main时参数不正确则警告 |
-Wparentheses | 根据上下文推断,如果把(n==10)写作(n=10)则警告 |
-Wswitch | 如果switch中少了一个或多个case分支(仅对enum适用)则警告 |
-Wunused | 变量声明了但未使用,或static类型函数未被调用则警告 |
-Wuninitialized | 使用的自动变量没有初始化则警告 |
-Wundef | 如果在#if宏中使用了未定义的变量做判断则警告 |
-Winline | 函数不能被内联则警告 |
-Wmissing-declarations | 如果定义了全局函数但却没有在任何头文件中声明则警告 |
-Wlong-long | 使用了long long类型则警告 |
-Werror | 把所有警告转变为错误 |
// warn.c
int main()
{
int a = 0;
return 0;
}
1
2
3
4
5
6
2
3
4
5
6
$ gcc -Wall warn.c
warn.c: In function ‘main’:
warn.c:3:9: warning: unused variable ‘a’ [-Wunused-variable]
int a = 0;
^
1
2
3
4
5
2
3
4
5
使用-Wall
选项打开所有编译警告,上面代码编译时会报"变量未使用"的警告。
# gcc的优化选项
gcc代码优化采用“-On”选项
- -O、 -O1:同时减小代码的长度和执行时间
- -O2:包括-O的功能,以及指令调度等调整工作
- -O3:包括-O2的功能,以及循环展开等工作
// optimize.c
#include <stdio.h>
int main()
{
double counter;
double result;
double temp;
for(counter=0; counter<3000.0*3000.0*2000.0/20.0+2023; counter+=(8-3-2+1)/4)
{
temp=counter/1234;
result=counter;
}
printf("the result is %1f\n",result);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 优化前
$ gcc optimize.c
$ time ./a.out
the result is 900002022.000000
real 0m2.718s
user 0m2.703s
sys 0m0.000s
#优化后
$ gcc -O optimize.c
$ time ./a.out
the result is 900002022.000000
real 0m0.657s
user 0m0.641s
sys 0m0.016s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
编辑 (opens new window)
上次更新: 2023/03/31, 22:34:04
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05