ARM_Linux中GCC编译器的使用

目录

前言:

GCC编译过程:

预处理:

编译阶段:

汇编:

链接阶段

GCC的常见使用


前言:

什么是GCC:

gcc的全称是GNU Compiler Collection,它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器(GNU C Compiler),现在除了c语言,还支持C++、java、Pascal等语言。gcc支持多种硬件平台。

特点:

  • gcc是一个可移植的编译器,支持多种硬件平台。例如ARM、X86等等。
  • gcc不仅是个本地编译器,它还能跨平台交叉编译。所谓的本地编译器,是指编译出来的程序只能够在本地环境进行运行。而gcc编译出来的程序能够在其他平台进行运行。例如嵌入式程序可在x86上编译,然后在arm上运行。
  • gcc有多种语言前端,用于解析不同的语言。
  • gcc是按模块化设计的,可以加入新语言和新CPU架构的支持。
  • gcc是自由软件。任何人都可以使用或更改这个软件。

        源文件需要经过编译才能够生成可执行文件,在Windows下进行开发的时候,只需要几个按键就可以编译,集成的开发环境(V Studio,keil,clion等)已经将各种编译工具封装好了,linux中虽然有一些集成好的编译器,但是对于嵌入式软件开发的时候,通常没有屏幕,只能通过指令进行程序的编写和调试。但是要编译出来的程序可以在ARM上运行,就必须使用交叉编译器xxx-gcc等。

GCC编译过程:

一个c/c++文件要经过四个过程才能变成可执行文件。

  • 预编译(Pre-Processing)
  • 编译(Compiling)
  • 汇编(Assembling)
  • 链接(Linking)

预处理:

预处理过程中,是对源代码文件中的包含(include)、预编译语句(以#开头的命令等)进行展开生成.i文件。

使用GCC的参数 “-E”,可以让编译器生成 .i 文件,参数 “-o”,可以指定输出文件的名字。

 # 预处理,可理解为把头文件的代码汇总成C代码,把*.c转换得到*.i文件gcc –E test1.c –o test1.i

预处理就是将要包含“#include”的文件插入到原文件中,将宏定义展开,根据条件编译命令选择要使用的代码,最后将这些东西输入到“.i”文件中等待进一步处理

编译阶段:

gcc调用不同语言的编译器,例如c语言调用编译器ccl。gcc实际上是个工具链,在编译程序的过程中调用不同的工具。而在编译阶段就是通过调用的工具将预处理后的.i文件编译成汇编语言,生成.s文件,就是把代码从C语言转为汇编语言。在这个过程,GCC会检查各个源文件的语法。

GCC可以使用-S选项,让编译程序生成汇编语言的代码文件(.s后缀)。

 # 编译,可理解为把C代码转换为汇编代码,把*.i转换得到*.s文件gcc –S hello.i –o hello.s​# 也可以直接以C文件作为输入进行编译,与上面的命令是等价的gcc –S hello.c –o hello.s

了解过汇编语言的应该知道,对于不同的芯片会由不同的汇编指令集,这个是没法通用的。所以这是为什么要使用交叉编译器的一个主要原因。

汇编:

汇编阶段,gcc调用汇编器进行汇编。将汇编语言的.s文件经过汇编生成.o文件,每一个源文件都对应一个目标文件。把汇编语言转换成机器码。

 # 汇编,可理解为把汇编代码转换为机器码,把*.s转换得到*.o,即目标文件gcc –c hello.s –o hello.o​# 也可以直接以C文件作为输入进行汇编,与上面的命令是等价的gcc –c hello.c –o hello.o

双击.o文件是打不开的,使用vim打开也是一堆乱码,这是因为Linux下生成的.o目标文件、.so动态库文件以及可执行文件都是elf格式的。可以使用“readelf”工具来查看内容。

从 readelf 的工具输出的信息,可以了解到目标文件包含ELF头、程序头、节等内容, 对于*.o目标文件或*.so库文件,编译器在链接阶段利用这些信息把多个文件组织起来。

链接阶段

最后将每个源文件对应的目标文件.o链接起来,就生成一个成执行文件了。

例如一个工程里包含了A和B两个代码文件,在链接阶段, 链接过程需要把A和B之间的函数调用关系理顺,也就是说要告诉A在哪里能够调用到fun函数, 建立映射关系,所以称之为链接。若链接过程中找不到fun函数的具体定义,则会链接报错。

虽然文章的test1例子中只有一个.c文件,但是调用了C标准代码库中的printf函数, 所以链接器会把它和printf函数链接起来,生成最终的可执行文件。

链接分为两种:

  • 动态链接:GCC编译时的默认选项。动态是指在应用程序运行时才去加载外部的代码库,不同的程序可以共用代码库。 所以动态链接生成的程序比较小,占用较少的内存。
  • 静态链接:链接时使用选项 “--static”,它在编译阶段就会把所有用到的库打包到自己的可执行程序中。 所以静态链接的优点是具有较好的兼容性,不依赖外部环境,但是生成的程序比较大。
 # 在hello.o所在的目录执行如下命令# 动态链接,生成名为hello的可执行文件​gcc hello.o –o hello​# 也可以直接使用C文件一步生成,与上面的命令等价gcc hello.c -o hello​# 静态链接,使用--static参数,生成名为hello_static的可执行文件gcc hello.o –o hello_static --static​# 也可以直接使用C文件一步生成,与上面的命令等价gcc hello.c -o hello_static --static

从图中可以看到,使用动态链接生成的hello程序才16.6KB, 而使用静态链接生成的hello_static程序则高达871.9KB。

在Ubuntu下,可以使用 ldd 工具查看动态文件的库依赖,尝试执行如下命令:

但是静态链接生成的可执行文件没有依赖外部库文件。

GCC的常见使用

//gcc使用示例
gcc hello.c // 输出一个名为 a.out的可执行程序,然后可以执行./a.out
gcc -o hello hello.c // 输出名为 hello的可执行程序,然后可以执行./hello
gcc -o hello hello.c -static // 静态链接
gcc -c -o hello.o hello.c // 先编译(不链接)
gcc -o hello hello.o // 再链接

执行“gcc -o test1 test1.c -v”的时候可以看到这写步骤

常用编译选项:

多文件编译

//一次性编译
gcc -o main  hello.c main.c //生成可执行文件main
//独立编译
gcc -Wall -c-o main.o main.c 
gcc -Wall -c -o hello.o hello.c
gcc -Wall -o main main.o hello.o

制作动态库:

静态库:

文章参考:

GCC基本使用 - 知乎 (zhihu.com)

Linux编译工具:gcc入门 - melonstreet - 博客园 (cnblogs.com)

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

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

相关文章

PgSQL - 17新特性 - 块级别增量备份

PgSQL - 17新特性 - 块级别增量备份 PgSQL可通过pg_basebackup进行全量备份。在构建复制关系时,创建备机时需要通过pg_basebackup全量拉取一个备份,形成一个mirror。但很多场景下,我们往往不需要进行全量备份/恢复,数据量特别大的…

C++面试宝典第23题:乌托邦树

题目 乌托邦树每年经历2个生长周期。每年春天,它的高度都会翻倍。每年夏天,他的高度都会增加1米。对于一颗在春天开始时种下的高为1米的树,问经过指定周期后,树的高度为多少? 输入描述:输入一个数字N(0 <= N <= 1000),表示指定周期。 比如:样例输入为3。 输出描…

helm---自动化一键部署

什么是helm?? 在没有这个helm之前&#xff0c;deployment service ingress helm的作用就是通过打包的方式&#xff0c;把deployment service ingress 这些打包在一块&#xff0c;一键式部署服务&#xff0c;类似于yum 官方提供的一个类似于安装仓库的功能&#xff0c;可以实…

基于springboot+vue新能源汽车充电管理系统

摘要 新能源汽车充电管理系统是基于Spring Boot和Vue.js技术栈构建的一款先进而高效的系统&#xff0c;旨在满足不断增长的新能源汽车市场对充电服务的需求。该系统通过整合前后端技术&#xff0c;实现了用户注册、充电桩管理、充电订单管理等核心功能&#xff0c;为用户提供便…

使用DTS实现TiDB到GaiaDB数据迁移

1 概览 本文主要介绍通过 DTS 数据迁移功能&#xff0c;结合消息服务 for Kafka 与 TiDB 数据库的 Pump、Drainer 组件&#xff0c;完成从TiDB迁移至百度智能云云原生数据库 GaiaDB。 消息服务 for Kafka&#xff1a;详细介绍参见&#xff1a;消息服务 for Kafka 产品介绍百度智…

go 语言中 json.Unmarshal([]byte(jsonbuff), j) 字节切片得使用场景

struct_tag的使用 在上面的例子看到&#xff0c;我们根据结构体生成的json的key都是大写的&#xff0c;因为结构体名字在go语言中不大写的话&#xff0c;又没有访问权限&#xff0c;这种问题会影响到我们对json的key的名字&#xff0c;所以go官方给出了struct_tag的方法去修改…

R语言rvest爬虫如何设置ip代理?

前言 在R语言中使用rvest进行网络爬虫时&#xff0c;可以使用代理服务器来隐藏真实IP地址。有一些R包可以帮助爬虫中设置代理&#xff0c;其中一个常用的包是httr。以下是一个简单的例子&#xff0c;演示如何在rvest中设置IP代理 教程 一、获取代理IP并提取 二、详情设置 l…

2024三掌柜赠书活动第四期: Next.js实战,构建现代化的可扩展Web应用

目录 摘要前言Next.js简介关于《 Next.js实战》实战示例最佳实践和进阶应用编辑推荐内容简介作者简介图书目录书中前言/序言《Next.js实战》全书速览结束语 摘要&#xff1a;本文将介绍Next.js&#xff0c;一个流行的React框架&#xff0c;以及如何在实际项目中使用Next.js构…

OSPF协议LSDB同步过程和邻居状态机

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 厦门微思网络​​​​​​ https://www.xmws.cn 华为认证\华为HCIA-Datacom\华为HCIP-Datacom\华为HCIE-Datacom Linux\RHCE\RHCE 9.0\RHCA\ Oracle O…

技术型企业如何选择安全、性价比高的FTP替代方案?

FTP作为世界上第一款文件传输协议&#xff0c;在全球范围内应用广泛&#xff0c;它解决了文件传输协议空白的问题&#xff0c;为文件传输场景提供了专业的解决方案。 但随着网络技术的演进&#xff0c;技术型企业进行文件传输的需求也更多元和复杂&#xff0c;FTP的缺陷也更多的…

CmakeList教程

一、CmakeList介绍&#xff1a; cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。它会通过写的语句自动生成一个MakeFile,从而实现高效编译 二、CmakeList的常用指令 1.指定…

【 CSS 】定位

不要因为小小的失败而放弃大大的梦想&#xff0c;每一次坚持都是通向成功的一步。- 马克吐温 1. 定位 1.1 为何使用定位 我们先来看一个效果&#xff0c;同时思考一下用标准流或浮动能否实现类似的效果&#xff1f; 场景1: 某个元素可以自由的在一个盒子内移动位置&#xff0c…

小程序学习-21

目前小程序分包大小有以下限制&#xff1a; 整个小程序所有分包大小不超过 20M单个分包/主包大小不能超过 2M 独立分包&#xff1a;"independent": true

docker compose安装milvus

下载对应版本的milvus-standalone-docker-compose.yml wget https://github.com/milvus-io/milvus/releases/download/v2.3.5/milvus-standalone-docker-compose.yml重新命令为docker-compose.yml mv milvus-standalone-docker-compose.yml docker-compose.yml启动milvus doc…

记一次 stackoverflowerror 线上排查过程

一.线上 stackOverFlowError xxx日,突然收到线上日志关键字频繁告警 classCastException.从字面上的报警来看,仅仅是类型转换异常,查看细则发现其实是 stackOverFlowError.很多同学面试的时候总会被问到有没有遇到过线上stackOverFlowError?有么有遇到栈溢出?具体栈溢出怎么来…

postman测试导入文件

01 上传文件参数 1.选择请求方式 选择post请求方式&#xff0c;输入请求地址 2.填写Headers Key&#xff1a;Content-Type &#xff1b; Value&#xff1a;multipart/form-data 如下图 3.填写body 选择form-data&#xff0c;key选择file类型后value会出现按钮&#xff0…

(十二)Head first design patterns代理模式(c++)

代理模式 代理模式&#xff1a;创建一个proxy对象&#xff0c;并为这个对象提供替身或者占位符以对这个对象进行控制。 典型例子&#xff1a;智能指针... 例子&#xff1a;比如说有一个talk接口&#xff0c;所有的people需要实现talk接口。但有些人有唱歌技能。不能在talk接…

表单的总数据为什么可以写成一个空对象,不用具体的写表单中绑定的值,vue3

<el-form :model"form" label-width"120px"><el-form-item label"Activity name"><el-input v-model"form.name" /></el-form-item> </el-form> const form ref({})from为空对象 在v-model里写form…

verde生成网格坐标

文章目录 网格坐标区域调整 Verde是Python用于地理空间数据处理的一个库&#xff0c;由于采用了一些机器学习的方法&#xff0c;所以除了科学计算三件套之外&#xff0c;还需要基于sklearn模块。考虑到依赖关系&#xff0c;这里比较推荐用conda安装。 conda install verde --c…

分布式websocket即时通信(IM)系统保证消息可靠性【第八期】

b站上面本期视频版本&#xff0c;观看视频食用更佳&#xff01;点击即可跳转,找不到视频可以直接搜索我 目前叫 呆呆呆呆梦 目前已经写的文章有。并且有对应视频版本。 git项目地址 【IM即时通信系统&#xff08;企聊聊&#xff09;】点击可跳转 sprinboot单体项目升级成sprin…