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

Keil中的gcc

文章目录

  • 一、IDE背后的命令
    • 1.1 IDE是什么
    • 1.2 IDE的背后是命令
    • 1.3 有两套主要的编译器
  • 二、准备工作
    • 2.1 arm-linux-gcc和gcc是类似的
    • 2.2 Code::Blocks
      • 2.2.1 设置windows环境变量
      • 2.2.2 命令行示例
  • 三、gcc编译过程详解
    • 3.1 程序编译4步骤
    • 3.2 gcc的使用方法
      • 3.2.1 gcc使用示例
      • 3.2.2 gcc常用选项
        • 1.手工控制编译过程
        • 2.使用后缀名决定编译过程
      • 3.2.3 指定头文件目录
      • 3.2.4 指定库文件

一、IDE背后的命令

1.1 IDE是什么

IDE指集成开发环境(Integrated Development Environment)。
我们开发STM32F103等单片机程序时使用是keil就是一种IDE。

使用IDE,很容易操作,点点鼠标就可完成:

  • 添加文件
  • 指定文件路径(头文件路径、库文件路径)
  • 指定链接库
  • 编译、链接
  • 下载、调试

1.2 IDE的背后是命令

使用CMD来查看编译结果(这里使用第一个点灯程序为例):
如图勾上该选项:
在这里插入图片描述
用Note++查看生成的BAT文件:
在这里插入图片描述
用Note++分别查看main__i、start_ia、led_c_lnp,加上上图的编译语句:
在这里插入图片描述
打开CMD,进入到led.c的文件目录
在这里插入图片描述
进入到该文件目录下后复制上面红框内整合到一起的命令,可以看到其中的输出结果与Keil编译结果一样:
在这里插入图片描述

  • 注意

    • 使用GitBash执行命令的话
      由于GitBash采用类似Linux的文件路径表示方法(比如 /d/abc,而非 d:\abc),命令行中windows格式的路径名要加上双引号,比如".\objects\main.o"
    • 使用dos命令行执行命令的话
      不需要加双引号
  • 在某个Keil工程所在目录下,打开Git Bash:
    E:\ARM\doc_and_source_for_mcu_mpu\STM32MF103\daima\led_c

  • 编译main.c
    执行命令:

    "E:\keil5\ARM\ARMCC\Bin\ArmCC" --c99 --gnu -c --cpu Cortex-M3 -D__EVAL -g -O0 --apcs=interwork --split_sections -I.\RTE\_led_c -I"C:\Users\thisway_diy\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.3.0\Device\Include" -I"C:\Keil_v5\ARM\CMSIS\Include" -D__UVISION_VERSION="527" -DSTM32F10X_HD -o ".\objects\main.o" --omf_browse ".\objects\main.crf" --depend ".\objects\main.d" "main.c"
    
  • 编译start.S
    执行命令:

    "E:\keil5\ARM\ARMCC\Bin\ArmAsm" --cpu Cortex-M3 --pd "__EVAL SETA 1" -g --apcs=interwork -I.\RTE\_led_c -I"C:\Users\thisway_diy\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.3.0\Device\Include" -I"C:\Keil_v5\ARM\CMSIS\Include" --pd "__UVISION_VERSION SETA 527" --pd "STM32F10X_HD SETA 1" --list ".\listings\start.lst" --xref -o ".\objects\start.o" --depend ".\objects\start.d" "start.s"
    
  • 链接
    执行命令:

    "E:\keil5\ARM\ARMCC\Bin\ArmLink" --cpu Cortex-M3 ".\objects\main.o" ".\objects\start.o" --ro-base 0x08000000 --entry 0x08000000 --rw-base 0x20000000 --entry Reset_Handler --first __Vectors --strict --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols --info sizes --info totals --info unused --info veneers --list ".\Listings\led_c.map" -o ".\Objects\led_c.axf"
    

在这里插入图片描述

1.3 有两套主要的编译器

  • armcc

    • ARM公司的编译器
    • keil使用的就是armcc
  • gcc

    • GNU工具链
    • Linux等开源软件经常使用gcc

后面以GNU工具链为例讲解,所涉及的知识可以平移到armcc上。

二、准备工作

2.1 arm-linux-gcc和gcc是类似的

  • arm-linux-gcc
    • 给ARM芯片编译程序
  • gcc
    • 在x86编译程序
  • 用法基本一样
  • 为方便演示,我们使用gcc
  • 为了方便在windows下演示,我们使用Code::Blocks
    • 它的安装程序自带gcc

2.2 Code::Blocks

它是一款基于GCC的windows IDE,可以用来开发C/C++/Fortran。
官网地址:http://www.codeblocks.org/
在这里插入图片描述
可以使用百问网韦东山老师提供的Git仓库下载:git clone https://e.coding.net/weidongshan/noos/cortexA7_windows_tools.git
下载GIT后,在apps目录下。

2.2.1 设置windows环境变量

在Path环境变量中添加:C:\Program Files\CodeBlocks\MinGW\bin

2.2.2 命令行示例

事先写好一个hello.c放在E盘,启动Git Bash,编译程序hello.c:
在这里插入图片描述

#include <stdio.h>int main(void)
{printf("hello, world!\n");return 0;
}

编译、运行命令如下:

gcc -o hello  hello.c
./hello.exe

在这里插入图片描述

三、gcc编译过程详解

3.1 程序编译4步骤

在这里插入图片描述
我们经常使用“编译”泛指上面的4个步骤之一,甚至有时候会囊括这四个步骤。

3.2 gcc的使用方法

gcc  [选项]   文件名

3.2.1 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       // 再链接

3.2.2 gcc常用选项

1.手工控制编译过程
选项功能
-v查看gcc编译器的版本,显示gcc执行时的详细过程
-o 指定输出文件名为file,这个名称不能跟源文件名同名
-E只预处理,不会编译、汇编、链接t
-S只编译,不会汇编、链接
-c编译和汇编,不会链接

一个c/c++文件要经过预处理、编译、汇编和链接才能变成可执行文件。
(1)预处理
C/C++源文件中,以“#”开头的命令被称为预处理命令,如包含命令“#include”、宏定义命令“#define”、条件编译命令“#if”、“#ifdef”等。预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到一个“.i”文件中等待进一步处理。
(2)编译
编译就是把C/C++代码(比如上述的“.i”文件)“翻译”成汇编代码。
(3)汇编
汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现为ELF目标文件(OBJ文件)。“反汇编”是指将机器代码转换为汇编代码,这在调试程序时常常用到。
(4)链接
链接就是将上步生成的OBJ文件和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。

hello.c(预处理)->hello.i(编译)->hello.s(汇编)->hello.o(链接)->hello
详细的每一步命令如下:

gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o

上面一连串命令比较麻烦,gcc会对.c文件默认进行预处理操作,使用-c再来指明了编译、汇编,从而得到.o文件,
再将.o文件进行链接,得到可执行应用程序。简化如下:

gcc -c -o hello.o hello.c
gcc -o hello hello.o

我们事先写了一个hello.c,通过调用gcc指令查看编译细节:

#include <stdio.h>#define   MAX  20 
#define   MIN  10 #define  _DEBUG
#define   SetBit(x)  (1<<x) int main(int argc, char* argv[])
{printf("Hello World \n");printf("MAX = %d,MIN = %d,MAX + MIN = %d\n",MAX,MIN,MAX + MIN); #ifdef _DEBUGprintf("SetBit(5) = %d,SetBit(6) = %d\n",SetBit(5),SetBit(6));printf("SetBit( SetBit(2) ) = %d\n",SetBit( SetBit(2) ));		
#endif    return 0;
}

直接编译运行如下:
在这里插入图片描述
但此时我们输入以下命令会发现有所不同:

gcc -o hello hello.c -v

在这里插入图片描述
会发现出现了很多信息,但其中主要的是以下几条:
在这里插入图片描述
执行预处理命令:

gcc -E -o hello.i hello.c//预处理

可见对应的宏会被包含进来,同时define中的代码也会直接使用:
在这里插入图片描述
观察去掉define后的输出结果:
在这里插入图片描述
若在mian.c中输入其他错误代码,观察是否有报错现象:
在这里插入图片描述
执行编译命令:

gcc -S -o hello.s hello.i//编译

可见编译时会报错:
在这里插入图片描述
去除掉报错字符,观察结果:
可见删除之后编译通过,不会有报错。
在这里插入图片描述
执行汇编命令:

gcc -c -o hello.o hello.s

执行链接指令:

gcc -o hello hello.o

在这里插入图片描述

2.使用后缀名决定编译过程

参考《嵌入式Linux应用开发完全手册》
在这里插入图片描述

  • 总结
    • 输入文件的后缀名和选项共同决定gcc到底执行那些操作
    • 在编译过程中,最后的步骤都是链接
      • 除非使用了-E、-S、-c选项
      • 或者编译出错阻止了完整的编译过程

3.2.3 指定头文件目录

头文件在哪里?

  • 系统目录

    • 系统目录在哪?工具链里的某个include目录

    • 怎么确定?

      echo 'main(){}'| gcc -E -v -  // 它会列出头文件目录、库目录(LIBRARY_PATH)
      
    • 可以不使用系统include目录吗?可以,编译时指定参数-nostdinc

  • 可以自己指定头文件目录

-I <头文件目录>

3.2.4 指定库文件

库文件在哪里?

  • 系统目录

    • 系统目录在哪?工具链里的某个lib目录

    • 怎么确定?

      echo 'main(){}'| gcc -E -v -  // 它会列出头文件目录、库目录(LIBRARY_PATH)
      
    • 可以不使用系统lib目录吗?可以,编译时指定参数-nostdlib

  • 可以自己指定库文件目录

-L <库文件目录>
  • 指定库文件
-l  <abc>   // 链接 libabc.so 或 lib.a

相关文章:

Keil中的gcc

文章目录 一、IDE背后的命令1.1 IDE是什么1.2 IDE的背后是命令1.3 有两套主要的编译器 二、准备工作2.1 arm-linux-gcc和gcc是类似的2.2 Code::Blocks2.2.1 设置windows环境变量2.2.2 命令行示例 三、gcc编译过程详解3.1 程序编译4步骤3.2 gcc的使用方法3.2.1 gcc使用示例3.2.2…...

bilibili 哔哩哔哩小游戏SDK接入

小游戏的文档 简介 bilibili小游戏bilibili小游戏具有便捷、轻量、免安装的特点。游戏包由云端托管&#xff0c;在哔哩哔哩APP内投放和运行&#xff0c;体验流畅&#xff0c;安全可靠。https://miniapp.bilibili.com/small-game-doc/guide/intro/ 没想过接入这个sdk比ios还难…...

springboot523基于Spring Boot的大学校园生活信息平台的设计与实现(论文+源码)_kaic

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本大学校园生活信息平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…...

【YOLO算法改进】ALSS-YOLO:无人机热红外图像|野生动物小目标检测

目录 论文信息 论文创新点 1.自适应轻量通道分割和洗牌&#xff08;ALSS&#xff09;模块 2.轻量坐标注意力&#xff08;LCA&#xff09;模块 3.单通道聚焦模块 4.FineSIOU损失函数 摘要 架构设计 轻量高效网络架构 - ALSS模块 LCA模块 单通道聚焦模块 损失函数优…...

XML解析

一&#xff0c;XML概述 1.什么是XML XML即为可扩展的标记语言&#xff08;eXtensible Markup Language&#xff09; XML是一套定义语义标记的规则&#xff0c;这些标记将文档分成许多部件并对这些部件加以标识 2.XML和HTML不同之处 XML主要用于说明文档的主题&#xff0c;而…...

PlasmidFinder:质粒复制子的鉴定和分型

质粒&#xff08;Plasmid&#xff09;是一种细菌染色体外的线性或环状DNA分子&#xff0c;也是一种重要的遗传元素&#xff0c;它们具有自主复制能力&#xff0c;可以在细菌之间传播&#xff0c;并携带多种重要的基因(如耐药基因与毒力基因等)功能。根据质粒传播的特性&#xf…...

PTA数据结构作业一

6-1 链表的插入算法 本题要求实现一个插入函数&#xff0c;实现在链表llist中的元素x之后插入一个元素y的操作。 函数接口定义&#xff1a; int InsertPost_link(LinkList llist, DataType x, DataType y); 其中 llist是操作的链表&#xff0c;x是待插入元素y的前驱节点元素…...

2024年总结【第五年了】

2024年总结 北国绕院扫雪&#xff0c;南方围炉烹茶&#xff0c;且饮一杯无? 执笔温暖不曾起舞日子里的点点滴滴&#xff0c;誊写一段回忆&#xff0c;还以光阴一段副本。 那么你要听一支新故事吗&#xff1f;第五年总结的片碎。 衣单天寒&#xff0c;走趟流星孤骑&#xf…...

java实现一个kmp算法

1、什么是KMP算法 Kmp 算法是由D.E.Knuth&#xff0c;J.H.Morris和V.R.Pratt提出的&#xff0c;改进字符串匹配的算法&#xff1b; Kmp 算法的核心是利用匹配失败的信息&#xff0c;尽量减少模式串与主串的匹配次数&#xff0c;以达到 快速匹配的目的&#xff1b; Kmp 算法的时…...

强化学习方法分类详解

强化学习方法分类详解 引言 强化学习&#xff08;Reinforcement Learning, RL&#xff09;是一种通过智能体与环境互动来学习如何做出最佳决策的方法。根据不同的优化中心、策略特性、环境模型、奖励函数、动作空间类型以及行为策略和目标策略的一致性&#xff0c;RL可以分为…...

雅思真题短语(二十八)

真题短语收录在合辑。 541法律官员 work as a solicitor 542前卫 a radical and expensive scheme 543反对者们 objectors 544破坏 demolishing buildings 545蒸汽机车 steam locomotives 546冷凝 steam could be condensed 547烟雾 smoke and fumes 548通风井 ventilation sh…...

在Linux系统中使用字符图案和VNC运行Qt Widgets程序

大部分服务器并没有GUI&#xff0c;运行的是基础的Linux系统&#xff0c;甚至是容器。如果我们需要在这些系统中运行带有GUI功能的Qt程序&#xff0c;一般情况下就会报错&#xff0c;比如&#xff1a; $ ./collidingmice qt.qpa.xcb: could not connect to display qt.qpa.plu…...

Python基于EasyOCR进行路灯控制箱图像文本识别项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 随着城市化进程的加快&#xff0c;智能城市建设成为了现代社会发展的重要方向。路灯作为城市基础设…...

Github 2024-12-28 Rust开源项目日报 Top10

根据Github Trendings的统计,今日(2024-12-28统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10TypeScript项目1Python项目1egui: 一个简单、快速且高度可移植的 Rust GUI 库 创建周期:1903 天开发语言:Rust协议类型:Apache Li…...

提升生产力工具

VSCODE插件 干货&#xff1a;用好这13款VSCode插件&#xff0c;工作效率提升10倍 - 程序员柠檬 - 博客园 Sourcetrail Sourcetrail 是一个开源且免费的源码阅读工具&#xff0c;以其强大的代码导航、可视化及跨平台支持特性&#xff0c;成为开发者理解复杂代码库的得力助手。…...

【蓝桥杯——物联网设计与开发】系列前言

前言 本系列博客是博主为准备2024年第十五届蓝桥杯大赛物联网设计与开发赛道而写&#xff0c;经过4个月学习备战&#xff0c;最终获得全国一等奖。 从第十六届蓝桥杯大赛开始&#xff0c;物联网赛道更换竞赛实训平台。之前的博客&#xff0c;可以借鉴代码思想&#xff0c;但引脚…...

【Java基础】02.Java数据类型

目录 Java 数据类型 3.1 java程序中 “” 号的使用 3.2 java中的数据类型 3.2.1 基本数据类型&#xff1a;数值型 &#xff08;1&#xff09;整数类型 &#xff08;2&#xff09;浮点&#xff08;小数&#xff09;类型 3.2.2 基本数据类型&#xff1a;字符型 3.2.3 基本…...

Python爬虫(一)- Requests 安装与基本使用教程

文章目录 前言一、简介及安装1. 简介2. 安装 Requests2.1 安装2.2 检查安装是否成功 二、使用 Requests 发送 HTTP 请求1. 发送 GET 请求2. 发送 POST 请求3. 发送 PUT 请求4. 发送 DELETE 请求5. 发送 HEAD 请求6. 发送 OPTIONS 请求 三、传递参数1. GET 请求传递 URL 参数1.1…...

线段树保姆级教程

买水果 Description 水果姐今天心情不错&#xff0c;来到了水果街。 水果街有n家水果店&#xff0c;呈直线结构&#xff0c;编号为1~n&#xff0c;每家店能买水果也能卖水果&#xff0c;并且同一家店卖与买的价格一样。 学过oi的水果姐迅速发现了一个赚钱的方法&#xff1a…...

logback之自定义过滤器

logback有两种过滤器&#xff0c;一种是context中的过滤器叫TurboFilter&#xff0c;是一个全局的过滤器&#xff0c;会影响所有的日志记录。另一种是Appender中的过滤器&#xff0c;只对所在的append有效。两者大同小异&#xff0c;这里我们以Appender的过滤器为例。 &#x…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...