长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Cmake 基本使用
  • Linux和Windows常用命令对比
  • Nginx的使用方法
  • Bash常用语法
  • 使用PlantUml画时序图
  • 使用PlantUML画类图
  • 编译工具链
  • gcc工具的概述和使用
    • gcc工具概述
      • gcc与g++的比较
      • gcc支持的文件
      • 用gcc编译程序时,分为四个阶段
      • gcc的常用选项
    • gcc使用举例
      • 编译单文件
      • 编译多个文件
      • gcc的库依赖
      • gcc的警告与提示
      • gcc的优化选项
  • 自动化构建工具——Make/Makefile
  • 使用开源AI模型Whisper为视频生成字幕
  • MySQL基础操作
  • 工具
DC Wang
2023-03-23
目录

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
$ gcc hello.c -o hello
$ ./hello
hello world
1
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
$ gcc main.c fun.c -o main
$ ./main
in fun()
1
2
3

用一条gcc命令编译多源文件程序的缺点:每个文件都要重新编译。

# gcc的库依赖

函数库:头文件(.h)+库文件(.so、.a)

系统能够识别的默认路径

​ 头文件:/usr/include

​ 库文件:/usr/lib

使用非默认路径的文件需在编译时指定路径

​ 头文件用-I

​ 库文件用-L

以上面编译多个文件的代码为例

$ gcc -fPIC -shared fun.c -o libfun.so
1
  1. -fPIC选项表示生成位置独立的代码(Position Independent Code),即编译生成的代码可以在任意地址执行,不依赖于特定的内存地址。这是生成动态链接库所必须的选项,因为动态链接库在运行时需要被加载到进程的任意内存地址。
  2. -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
$ 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

使用-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
# 优化前
$ 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
编辑 (opens new window)
#编译#gcc
上次更新: 2023/03/31, 22:34:04
编译工具链
自动化构建工具——Make/Makefile

← 编译工具链 自动化构建工具——Make/Makefile→

最近更新
01
ESP32-网络摄像头方案
06-14
02
ESP32-PWM驱动SG90舵机
06-14
03
ESP32-实时操作系统freertos
06-14
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式