[Linux]Linux编译器-gcc/g++

news2024/11/18 3:26:50

🥁作者华丞臧.
📕​​​​专栏:【LINUX】
各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞+收藏+关注)。如果有错误的地方,欢迎在评论区指出。
推荐一款刷题网站 👉 LeetCode刷题网站


文章目录

  • 前言
  • gcc
    • gcc如何完成编译
    • 预处理(进行宏替换)
    • 编译(生成汇编)
    • 汇编(生成机器可识别代码)
    • 链接(生成可执行文件)
    • 静态链接和动态链接
      • 静态链接
      • 动态链接
      • 动静态链接测试
    • gcc选项


前言

程序的编译过程:

  1. 预处理(进行宏替换)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别代码)
  4. 链接(生成可执行文件或库文件)

gcc

在这里插入图片描述

具体的编译过程请看👉编译和预处理详解

gcc如何完成编译

gcc的使用格式如下:

gcc [选项] [要编译的文件] [选项] [生成的目标文件名]

//gcc格式不只有一种
gcc [选项] [选项] [要编译的文件] [生成的目标文件名]

预处理(进行宏替换)

  • 预处理功能主要包括宏定义、文件包含、条件编译、去注释等;
  • 预处理指令是以#号开头的代码行;
  • 选项“-E”,该选项的作用是让gcc在预处理结束后停止编译过程;
  • 选项“-o”,指明生成的目标文件,“-i”文件为已经经过预处理的C原始程序。

gcc进行预处理的指令如下:

gcc -E hello.c -o hello.i
//从现在开始,进行程序的翻译,当将预处理做完,就停下来

测试代码如下(后面的编译过程使用的都是这个代码):

#include <stdio.h>

#define N 100

int main()
{
    //注释测试
    printf("hello world1!\n");
   // printf("hello world2!\n");
   // printf("hello world3!\n");
   // printf("hello world4!\n");
   // printf("hello world5!\n");
    printf("hello world6!\n");

    //条件编译
#ifdef S
    printf("S!\n");
#else
    printf("hello!\n");

    //宏测试
    printf("N:%d\n", N);
    return 0;
}

在这里插入图片描述

注意:Linux当中文件的后缀相对于Linux系统没有意义,但是对于用户是有意义的。

使用vim打开test.i文件,定位到文件结尾;在文件当中我们可以看到头文件会被拷贝到test.i文件中。

头文件的意义:

  1. 写代码;
  2. 支持代码自动补齐。

在这里插入图片描述
我们还可以使用编译器进行传参,使用“-D”选项即可:
在这里插入图片描述

编译(生成汇编)

  • 在这个阶段中,gcc首先要检查代码的规范性,是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言;
  • 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

gcc指令如下:

gcc -S test.i -o test.s
//从现在开始,进行程序的翻译,做完编译工作,变成汇编之后,就停下来

在这里插入图片描述
打开test.s文件可以看到,已经变成了汇编代码(汇编不能被执行):
在这里插入图片描述

汇编(生成机器可识别代码)

  • 汇编阶段是把编译阶段生成的“.s”文件转成目标文件;
  • 使用“-c”选项可以看到汇编代码转化为“.o”的二进制目标代码了。

gcc指令如下:

gcc -c test.s -o test.o
//从现在开始,进行程序的翻译,做完汇编工作,变成可重定向目标二进制,就停下来 

在这里插入图片描述
使用vim打开test.o文件,可以看到里面已经不是我们能看懂的了,test.o文件已经把汇编代码转化成二进制代码了(ttest.o文件也不能被执行)。

链接(生成可执行文件)

  • 在成功编译之后,就进入了链接阶段;
  • 这个阶段会把你写的代码和C标准库中的代码结合起来(链接过程)。

gcc指令如下:

gcc test.o -o test

//也可以如下
gcc test.o //默认生成a.out

在这里插入图片描述

静态链接和动态链接

静态链接

静态链接是指在编译链接时,把库文件的代码全部加入到可执行文件中;因此生成的文件比较大,但在运行时也就不再需要库文件了一定程度上提高了执行速度。静态链接链接静态库,其后缀一般为.a

优势:形成的可执行程序体积小,很好地节省资源(网络、磁盘、内存);
劣势:受库升级或者被删除的影响。

动态链接

动态链接与静态相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库文件。动态链接链接动态库,其后缀一般为.so

优势:不受库升级或者被删除的影响;
劣势:形成的可执行程序体积太大,浪费资源(可能在网络、磁盘、内存上占用了很大的资源)。

动静态链接测试

测试代码如下:

#include <stdio.h>

int main()
{
  printf("Hello world!\n");
  return 0;
}

Linux当中默认的是动态链接:
指令如下:

//编译指令
gcc test1.c -o test

//查看可执行程序是否为动态链接
//可以使用file指令查看
file test1

//查看动态链接的动态库
ldd test1

在这里插入图片描述
在这里插入图片描述
在Linux下库的命名:
在这里插入图片描述

Linux下静态链接需要使用静态库,而操作系统中可能没有对应的静态库,如果没有需要下载。

//使用如下指令下载C标准静态库
sudo yum install -y glibc-static

//使用如下指令下载C++标准静态库
sudo yum install -y libstdc++-static

//使用如下指令下载g++
sudo yum install -y gcc-c++

//gcc静态链接编译需要在后面加上 -static
gcc test1.c -o teststatic -static

查看可执行程序是否为动态链接
file teststatic

在这里插入图片描述

可以看到同一个程序通过动态链接和静态链接形成的可执行文件体积大小差别很大,甚至从上图看到达到了100倍。

系统本身,为了支持我们编程,给我们提供了什么?
系统给我们提供标准库的.h(告诉我们怎么用),标准的动静态库.so/.a。(告诉我们,方法实现库里面有,有需要去找对应的库)

gcc选项

  • -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面;
  • -S 编译到汇编语言不进行汇编和链接;
  • -c 编译到目标代码;
  • -o 文件输出到 文件;
  • -static 此选项对生成的文件采用静态链接;
  • -g 生成调试信息。GNU 调试器可利用该信息;
  • -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库;
  • -O0
  • -O1
  • -O2
  • -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高;
  • -w 不生成任何警告信息;
  • -Wall 生成所有警告信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot+Redis(官方案例)

在线文档项目结构 1.源码克隆&#xff1a;git clone https://github.com/spring-guides/gs-messaging-redis.git 2.包含两个项目initial和complete&#xff0c;initial可以根据文档练习完善&#xff0c;complete是完整项目 3.功能描述&#xff1a;构建应用程序&#xff0c;使用…

【谷粒商城基础篇】商品服务:商品维护

谷粒商城笔记合集 分布式基础篇分布式高级篇高可用集群篇简介&环境搭建项目简介与分布式概念&#xff08;第一、二章&#xff09;基础环境搭建&#xff08;第三章&#xff09;整合SpringCloud整合SpringCloud、SpringCloud alibaba&#xff08;第四、五章&#xff09;前端知…

xxx.lua入门编程

lua入门级编程,openresty的前置技能lua入门级编程,openresty的前置技能 看上图 lua示例&#xff1a; 入门示例 print("hello world!") local arr {"java","mysql","oracle"}; local map {usernamezhangsan,password123}; local fu…

Debezium 同步 PostgreSQL 数据到 RocketMQ 中

1.RocketMQ Connect概览 RocketMQ Connect是RocketMQ数据集成重要组件&#xff0c;可将各种系统中的数据通过高效&#xff0c;可靠&#xff0c;流的方式&#xff0c;流入流出到RocketMQ&#xff0c;它是独立于RocketMQ的一个单独的分布式&#xff0c;可扩展&#xff0c;可容错系…

字节二面:Redis 的大 Key 对持久化有什么影响?

Redis 的持久化方式有两种&#xff1a;AOF 日志和 RDB 快照。 所以接下来&#xff0c;针对这两种持久化方式具体分析分析。 大 Key 对 AOF 日志的影响 先说说 AOF 日志三种写回磁盘的策略 Redis 提供了 3 种 AOF 日志写回硬盘的策略&#xff0c;分别是&#xff1a; Always&am…

Git(四) - Git 分支操作

​​​​​​​ 一、什么是分支 在版本控制过程中&#xff0c;同时推进多个任务&#xff0c;为每个任务&#xff0c;我们就可以创建每个任务的单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来&#xff0c;开发自己分支的时候&#xff0c;不会影响主线分支…

前端面试常考 | js原型与原型链

文章目录一. 什么是原型?二. 什么是原型链?一. 什么是原型? 在js中所有的引用类型都有一个__proto__(隐式原型)属性&#xff0c;属性值是一个普通的对象。 而在js中的引用类型包括&#xff1a;Object&#xff0c;Array&#xff0c;Date&#xff0c;Function 而所有函数都有…

基于K8s的DevOps平台实践(二)

文章目录1. 流水线入门&#x1f351; 流水线基础语法&#x1f351; 脚本示例&#x1f351; 脚本解释&#x1f351; Blue Ocean2. Jenkinsfile实践&#x1f351; 演示一&#x1f351; 演示二&#x1f351; 演示三&#x1f351; 演示四&#x1f351; 总结3. 多分支流水线实践&…

BEV视觉3D感知算法梳理

1. 基于BEV空间的自动驾驶感知任务 最近&#xff0c;基于BEV空间下的感知任务已经涌现出了众多优秀算法&#xff0c;并在多个自动驾驶公开数据集&#xff08;KITTI&#xff0c;Waymo&#xff0c;nuScenes&#xff09;上取得了非常不错的成绩。根据自动驾驶汽车上安装的传感器类…

【从零开始学习深度学习】37. 深度循环神经网络与双向循环神经网络简介

目录1. 深度循环神经网络2. 双向循环神经网络总结1. 深度循环神经网络 之前介绍的循环神经网络只有一个单向的隐藏层&#xff0c;在深度学习应用里&#xff0c;我们通常会用到含有多个隐藏层的循环神经网络&#xff0c;也称作深度循环神经网络。下图演示了一个有LLL个隐藏层的…

数字化时代,全方位解读商业智能BI

商业智能BI是一种通用的数据类技术解决方案&#xff0c;不会因为行业BI没有进行针对性开发而出现不适配、无法使用的情况。同时&#xff0c;也正因为商业智能BI核心是数据&#xff0c;只要企业有数据沉淀&#xff0c;不管是哪些行业BI商业智能都能发挥出作用。 不过考虑到不同…

文件IO操作开发笔记(一):使用Qt的QFile对磁盘文件存储进行性能测试以及测试工具

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/128438303 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

portraiture2023智能磨皮修饰滤镜插件中文版

在人像后期修图的时候免不了需要进行磨皮处理&#xff0c;很多人在挑选磨皮软件的时候都不知道该如何选择&#xff0c;今天的文章就来带大家看看磨皮软件哪个好&#xff0c;能磨皮的修图软件和插件!借助磨皮软件即使是新手也能做出高级的人像图片&#xff0c;下面挑选了几款好用…

Java 并发编程知识总结【五】

6. 线程中断与 LockSupport 6.1 线程中断机制 大厂&#xff08;蚂蚁金服&#xff09;面试题&#xff1a; 什么是中断&#xff1f; 首先&#xff0c;一个线程不应该由其他线程来强制中断或停止&#xff0c;而是应该由线程自己自行停止。所以&#xff0c;Thread.stop, Thread.…

Exynos_4412——中断控制器

目录 一、中断控制器 中断控制器的作用&#xff1a; 二、Exynos_4412下的中断控制器 它支持三种类型的中断 可以编程设置&#xff1a; 三、中断控制器详解 四、中断控制器编程 一、中断控制器 外设产生的中断信号&#xff0c;先要经过中断控制器&#xff0c;中断是异常…

如何解决软件项目管理中的冲突?

1、项目干系人间的良好沟通 项目干系人之间保持良好的沟通交流&#xff0c;是减少项目管理中冲突的重要手段。甲乙双方签订合同后&#xff0c;为保障项目的成功&#xff0c;在项目发生矛盾和困难时&#xff0c;需要双方相互理解和沟通&#xff0c;共同协商解决问题。 为了及时解…

Git(八) - IDEA 集成 GitHub

一、设置 GitHub 账号 二、分享工程到 GitHub 来到GitHub中发现已经帮我们创建好了git-test的远程仓库。 三、push 推送本地库到远程库 注意&#xff1a;push是将本地库代码推送到远程库&#xff0c;如果本地库代码跟远程库代码版本不一致&#xff0c; push的操作是会被拒绝的…

go 性能分析pprof和trace

runtime/pprof&#xff1a;采集程序&#xff08;非 Server&#xff09;的运行数据进行分析&#xff0c;用于可结束的代码块&#xff0c;如一次编解码操作等net/http/pprof&#xff1a;采集 HTTP Server 的运行时数据进行分析。用于不可结束的代码块&#xff0c;如 web 应用等 使…

​工程师如何对待开源

工程师如何对待开源 本文是笔者作为一个在知名科技企业内从事开源相关工作超过 20 年的工程师&#xff0c;亲身经历或者亲眼目睹很多工程师对待开源软件的优秀实践&#xff0c;也看到了很多 Bad Cases&#xff0c;所以想把自己的一些心得体会写在这里&#xff0c;供工程师进行…

linux的shell的概述

Shell 教程 Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问操作系统内核的服务。 Ke…