当前位置: 首页 > news >正文

Linux嵌入式自学笔记(基于野火EBF6ULL):4.gcc

一、常见问题

        比如你想安装一下vim,结果显示如下结果:

            输入:

ps aux | grep -E 'apt|dpkg' 

        查看下面进程,比如我的显示结果为:

        理论上这种系统自动更新进程,等待个5-10分钟就能结束,但是我的等待后依旧不停,那就只能手动代码关掉进程了

sudo kill -9 4086
sudo kill -9 4090

        关掉之后发现还是安装不了,再重新输入:ps aux | grep -E 'apt|dpkg' ,发现只剩下自身这一个进程了:

        接下来要删除锁文件,输入下面命令:

sudo rm /var/lib/dpkg/lock
sudo rm /var/lib/dpkg/lock-frontend
sudo rm /var/lib/apt/lists/lock
sudo rm /var/cache/apt/archives/lock

        输入正确之后是没回复的

        最后修复 dpkg 状态:

sudo dpkg --configure -a

        并更新apt:

sudo apt update

        这会再安装就可以发现可以正常安装了

二、GCC

        首先,先安装gcc包

suda apt install gcc

        首先,创建一个工作目录:workdir/example

mkdir -p ~/workdir/example/hello_c #创建hello_c目录

        然后打卡虚拟机中对应文件夹位置

        然后桌面上新建一个hello.c,

        hello.c里的内容可以如下:

/* $begin hello */#include <stdio.h>int main(){printf("hello, world! This is a C program.\n");for(int i=0;i<10;i++ ){printf("output i=%d\n",i);}return 0;}/* $end hello */

3. GCC和Hello World — [野火]嵌入式Linux基础与应用开发实战指南——基于i.MX6ULL开发板 文档https://doc.embedfire.com/linux/imx6/linux_base/zh/latest/linux_app/gcc_hello_world/gcc_hello_world.html        然后直接把这个.c文件从windows桌面拖入虚拟机对应文件夹中

        再在终端中输入命令进入这个文件夹:

cd ~/workdir/example/hello_c

        可以输入代码看看hello.c里是否正确

vim hello.c

        

也可以用ls命令看看文件在不在

可以运行下面代码看看输出结果:

./hello

三、原理

        在 Linux 环境下,GCC 的工作可以分为四个主要阶段:预处理编译汇编链接。以下详细解释每个阶段的原理和作用:

1. 预处理

        预处理是 GCC 编译的第一步,处理源代码文件(通常是 .c 文件)。这一阶段主要完成以下任务:

  • 处理文件包含:将 #include 指定的头文件内容插入到源代码中,例如标准库的函数声明。
  • 展开宏定义:将 #define 定义的宏替换为实际内容,例如将常量或简单函数展开。
  • 处理条件编译:根据 #ifdef 或 #ifndef 等指令,决定哪些代码需要保留或删除。
  • 去除注释:删除源代码中的注释,简化后续处理。

        预处理后的结果是一个纯文本文件,通常以 .i 为后缀,包含展开后的代码,为后续编译做准备。

2. 编译

        编译阶段将预处理后的代码转换为汇编语言(.s 文件)。这是 GCC 的核心步骤,涉及以下子过程:

  • 词法分析:将代码分解为一个个词法单元(token),如关键字、变量名、运算符等。
  • 语法分析:检查代码是否符合 C 语言的语法规则,构建抽象语法树(AST)。
  • 语义分析:验证代码的语义是否正确,例如变量是否已声明、类型是否匹配。
  • 生成中间代码:将高级语言转换为中间表示,便于优化和跨平台处理。
  • 代码优化:对中间代码进行优化,例如删除冗余计算、循环展开等,以提高程序性能。

        这一阶段的输出是汇编语言文件,包含针对目标硬件(如 ARM 架构)的低级指令。

3. 汇编

        汇编阶段将汇编语言文件(.s)转换为机器码,生成可重定位目标文件(.o 文件)。这一过程由汇编器(通常是 GNU 的 as 工具)完成:

  • 汇编器将汇编指令翻译为二进制机器码。
  • 生成的目标文件包含代码段、数据段等,但尚未指定内存地址(因此称为“可重定位”)。
  • 这些文件还包含符号表,记录函数和变量的引用,供后续链接使用。
4. 链接

        链接阶段将多个可重定位目标文件(.o)和库文件组合,生成最终的可执行文件。链接分为两种方式:静态链接动态链接,GCC 通过调用链接器(通常是 ld)完成这一步骤。

  • 静态链接

    • 在编译时,将程序所需的所有库(如 glibc 的标准库函数)直接打包到可执行文件中。
    • 优点:生成的可执行文件独立运行,不依赖外部库,兼容性强。
    • 缺点:文件体积较大,且多个程序无法共享库代码,浪费内存。
  • 动态链接

    • 在编译时,仅在可执行文件中记录所需库的引用,实际库代码在运行时由动态链接器(ld-linux.so)加载。
    • 优点:可执行文件体积小,多个程序可共享同一库,节省内存;库更新无需重新编译程序。
    • 缺点:运行时需要确保系统中有正确的库版本,依赖外部环境。

        链接器的工作包括:

  • 符号解析:将代码中的函数调用和变量引用与实际地址关联。
  • 重定位:为代码和数据分配最终的内存地址。
  • 生成可执行文件:输出 ELF(Executable and Linkable Format)格式的可执行文件,包含程序的完整结构。

        在 Linux 系统中,编译后的可执行文件通过以下步骤运行,体现了 GCC 编译结果与操作系统的协作:

  1. 进程创建:用户在终端输入运行命令(如 ./program),Shell 使用 fork() 创建新进程。
  2. 程序加载:通过 execve() 系统调用,内核的 do_execve() 函数加载可执行文件到内存。
  3. 动态链接(若适用):动态链接器 ld-linux.so(glibc 的一部分)加载共享库,完成符号解析和地址绑定。
  4. 初始化与执行:glibc 的 _start 函数作为程序入口,调用 __libc_start_main() 进行初始化(如设置堆栈、环境变量),然后执行用户程序的主函数。
  5. 程序终止:执行完成后,调用 glibc 的 _exit() 函数结束进程。

        GCC 的编译过程直接影响程序的执行效率和兼容性。例如,动态链接的程序依赖 glibc 的动态链接器,而静态链接的程序则包含所有依赖,适合在不同 Linux 系统间移植。

http://www.dtcms.com/a/391332.html

相关文章:

  • Mellanox网卡寄存器PPCC
  • [vibe code追踪] 应用状态管理 | 交互式点击 | 共享白板
  • SG-TCP232-110 单通道串口服务器,一键实现串口与以太网双向转换
  • 零基础入门神经网络:从数学公式到通俗理解
  • 坤驰科技诚邀您参加——第十三届中国光纤传大会
  • 如何找到高质量的Java项目教程?
  • 无声的战场:AUTOSAR AP日志里的谍影重重(1)
  • ThinkPHP在使用nginx反向代理后如何获取真实的Ip地址
  • LeetCode 分类刷题:2439. 最小化数组中的最大值
  • Git最佳实践(Golang示例项目)
  • 20250919在荣品RD-RK3588-MID开发板的Android13系统下使用TF卡刷机解决竖屏横用的时候的竖屏提示的问题
  • Makefile学习(三)- CFLAGS和LDFLAGS
  • React 新闻发布系统 NewSandBox侧边栏与顶部栏布局
  • ppt视频极致压缩参数
  • 49.Mysql多实例部署
  • java 上传文件和下载/预览文件 包括音频调进度条
  • 部署你的 Next.js 应用:Vercel、Netlify 和自托管选项
  • 从产品经理视角:小智AI的产品介绍与分析
  • 解决:导包红色波浪线但正常运行及其后续问题
  • webrtc弱网-LinkCapacityEstimator类源码分析与算法原理
  • vue el-autocomplete输入框自动匹配优化,建议项按高度相似降序
  • 十分钟了解@Version注解
  • vue3+ts+uniapp H5微信小程序app有截止日期的日期date-pcicker组件
  • 设计模式-观察者模式详解
  • centos7--安装海量数据库Vastbase M100
  • Apache Commons DBCP连接池生产环境配置推荐
  • 【11/20】实时数据基础:WebSocket 在 Express 和 Vue 中的整合,实现简单聊天功能
  • 五传输层-TCP UDP慢启动-真题
  • ARM基础知识
  • 从零开始的指针(5)