嵌入式Linux学习第二天

今天学习linuxC编程。首先要熟悉linux下编写c程序的过程。

编写程序Hello World!

首先创建存放程序的文件夹,如下图所示:
在这里插入图片描述
接下来在创建一个文件夹来保存这节要编写的代码。指令:mkdir 3.1
在这里插入图片描述
接下来我们要设置VIM编辑器的一些配置,比如设置tab的字符数为4、以及设置VIM编辑器的行号。在文件/etc/vim/vimrc 中添加代码:

set nu
set ts=4

然后创建main.c文件。
在这里插入图片描述
编写程序完事后,使用“gcc main.c –o main”来编译 main.c 文件,使用参数“-o”来指定编译生成的可执行文件名字。
在这里插入图片描述

GCC编译器

gcc 命令

在上一小节我们已经使用过 GCC 编译器来编译 C 文件了,我们使用到是 gcc 命令,gcc 命令格式如下:

gcc [选项] [文件名字]
主要选项如下:
-c:只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。
-o:<输出文件名>用来指定编译结束以后的输出文件名,如果不使用这个选项的话 GCC 默
认编译出来的可执行文件名字为 a.out。
-g:添加调试信息,如果要使用调试工具(如 GDB)的话就必须加入此选项,此选项指示编
译的时候生成调试所需的符号信息。
-O:对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进
行优化,这样产生的可执行文件执行效率就高。
-O2:比-O 更幅度更大的优化,生成的可执行效率更高,但是整个编译过程会很慢。

编译流程

GCC 编译器的编译流程是:预处理、编译、汇编和链接。预处理就是展开所有的头文件、替换程序中的宏、解析条件编译并添加到文件中。编译是将经过预编译处理的代码编译成汇编代码,也就是我们常说的程序编译。汇编就是将汇编语言文件编译成二进制目标文件。链接就是将汇编出来的多个二进制目标文件链接在一起,形成最终的可执行文件,链接的时候还会涉及到静态库和动态库等问题。上一小节演示的例程都只有一个文件,而且文件非常简单,因此可以直接使用 gcc 命令生成可执行文件,并没有先将 c 文件编译成.o 文件,然后再链接在一起。

Makefile 基础

当文件有几十、上百甚至上万个的时候用终端输入 GCC 命令的方法显然是不现实的。如果我们能够编写一个文件,这个文件描述了编译哪些源码文件、如何编译那就好了,每次需要编译工程的时只需要使用这个文件就行了。这种问题怎么可能难倒聪明的程序员,为此提出了一个解决大工程编译的工具:make,描述哪些文件需要编译、哪些需要重新编译的文件就叫做 Makefile,Makefile 就跟脚本文件一样,Makefile 里面还可以执行系统命令。使用的时候只需要一个 make命令即可完成整个工程的自动编译,极大的提高了软件开发的效率。如果大家以前一直使用 IDE来编写 C 语言的话肯定没有听说过 Makefile 这个东西,其实这些 IDE 是有的,只不过这些 IDE对其进行了封装,提供给大家的是已经经过封装后的图形界面了,我们在 IDE 中添加要编译的
C 文件,然后点击按钮就完成了编译。在 Linux 下用的最多的是 GCC 编译器,这是个没有 UI的编译器,因此 Makefile 就需要我们自己来编写了。

Makefile 语法

Makefile 规则格式
Makefile 里面是由一系列的规则组成的,这些规则格式如下:

目标…... : 依赖文件集合……
命令 1
命令 2
……
main : main.o input.o calcu.o
 gcc -o main main.o input.o calcu.o

第一行定义了一个规则,它告诉make命令如何构建目标main。在这里,main是一个目标(通常是最终要生成的程序或文件),而main.o、input.o和calcu.o是这个目标的依赖项,意味着在构建main之前,必须首先存在或构建这些依赖项。

目标(target):main是这条规则的目标,也就是这条规则想要构建或更新的文件。
依赖(dependencies):main.o、input.o和calcu.o是目标的依赖项,这意味着在尝试构建main之前,make会确保所有的依赖项都是最新的。
gcc是GNU编译器集合中的C编译器,用于编译C语言程序。-o main选项告诉gcc将链接生成的可执行文件命名为main。main.o、input.o和calcu.o是gcc需要链接的对象文件。这些对象文件之前已经由gcc从相应的源文件编译生成。
命令列表中的每条命令必须以 TAB 键开始,不能使用空格!
make 命令会为 Makefile 中的每个以 TAB 开始的命令创建一个 Shell 进程去执行。了解了 Makefile 的基本运行规则以后我们再来分析一下 3.3 节中“示例代码 3.3.2.6”中的Makefile,代码如下:、在这里插入图片描述
上述代码中一共有 5 条规则,1~2 行为第一条规则,3~4 行为第二条规则,5~6 行为第三条规则,7~8 行为第四条规则,10~12 为第五条规则,make 命令在执行这个 Makefile 的时候其执行步骤如下:首先更新第一条规则中的 main,第一条规则的目标成为默认目标,只要默认目标更新了那么就认为 Makefile 的工作。在第一次编译的时候由于 main 还不存在,因此第一条规则会执行,第一条规则依赖于文件 main.o、input.o 和 calcu.o 这个三个.o 文件,这三个.o 文件目前还都没有,因此必须先更新这三个文件。make 会查找以这三个.o 文件为目标的规则并执行。以 main.o为例,发现更新 main.o 的是第二条规则,因此会执行第二条规则,第二条规则里面的命令为“gcc–c main.c”,这行命令很熟悉了吧,就是不链接编译 main.c,生成 main.o,其它两个.o 文件同理。最后一个规则目标是 clean,它没有依赖文件,因此会默认为依赖文件都是最新的,所以其对应的命令不会执行,当我们想要执行 clean 的话可以直接使用命令“make clean”,执行以后就会删除当前目录下所有的.o 文件以及 main,因此 clean 的功能就是完成工程的清理,
总结一下 Make 的执行过程:
1、make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
2、当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件。
3、当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比目标文件晚)的话就会执行后面的命令来更新目标。
在这里插入图片描述
原子文档总结的很形象。具体执行的过程就如上图所示:

Makefile 变量

跟 C 语言一样 Makefile 也支持变量的,先看一下前面的例子:

 main: main.o input.o calcu.o
 gcc -o main main.o input.o calcu.o

上述 Makefile 语句中,main.o input.o 和 calcue.o 这三个依赖文件,我们输入了两遍,我们这个 Makefile 比较小,如果 Makefile 复杂的时候这种重复输入的工作就会非常费时间,而且非常容易输错,为了解决这个问题,Makefile 加入了变量支持。不像 C 语言中的变量有 int、char等各种类型,Makefile 中的变量都是字符串!类似 C 语言中的宏。使用变量将上面的代码修改,修改以后如下所示:

1 #Makefile 变量的使用
2 objects = main.o input.o calcu.o
3 main: $(objects)
4 gcc -o main $(objects)

第 1 行是注释,Makefile 中可以写注释,注释开头要用符号“#”,不能用 C 语言中的“//”或者“/**/”!第 2 行我们定义了一个变量 objects,并且给这个变量进行了赋值,其值为字符串“main.o input.o calcu.o”,第 3 和 4行使用到了变量 objects,Makefile 中变量的引用方法是“ ( 变量名 ) ”,比如本例中的“ (变量名)”,比如本例中的“ (变量名),比如本例中的(objects)”就是使用变量 objects。在“示例代码 3.4.2.1”中我们在定义变量 objects 的时候使用“=”对其进行了赋值,Makefile变量的赋值符还有其它两个“:=”和“?=”,我们来看一下这三种赋值符的区别:
1、赋值符“=”
示例代码 3.4.2.1 赋值符"="使用

1 name = zzk
2 curname = $(name)
3 name = zuozhongkai
4
5 print:
6 @echo curname: $(curname)

2、赋值符“:=”
赋值符“:=”不会使用后面定义的变量,只能使用前面已经定义好的,这就是“=”和“:=”两个的区别。
3、赋值符“?=”
“?=”是一个很有用的赋值符,比如下面这行代码:

curname ?= zuozhongkai

上述代码的意思就是,如果变量 curname 前面没有被赋值,那么此变量就是“zuozhongkai”,
如果前面已经赋过值了,那么就使用前面赋的值。
4、变量追加“+=”
Makefile 中的变量是字符串,有时候我们需要给前面已经定义好的变量添加一些字符串进
去,此时就要使用到符号“+=”,比如如下所示代码:

objects = main.o input.o
objects += calcu.o

一开始变量 objects 的值为“main.o input.o”,后面我们给他追加了一个“calcu.o”,因此变量 objects 变成了“main.o input.o calcu.o”,这个就是变量的追加。

Makefile 模式规则

模式规则中,至少在规则的目标定定义中要包涵“%”,否则就是一般规则,目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的文件,类似与通配符,a.%.c 就表示以 a.开头,以.c 结束的所有文件。
当“%”出现在目标中的时候,目标中“%”所代表的值决定了依赖中的“%”值,

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【简单介绍下Debian常用命令】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

AI部署指南

部署指南 建议大家尽可能的自己去部署&#xff0c;如果实在懒得搞&#xff0c;可以找我来帮你部署&#xff0c;详情参考 服务器代部署说明。 由于时间仓促&#xff0c;文档可能尚未详尽&#xff0c;我将在后续逐步补充详细的说明文档。 架构草图 项目依赖 必选依赖 MySQ…

DS二叉搜索树

前言 我们在数据结构初阶专栏已经对二叉树进行了介绍并用C语言做了实现&#xff0c;但是当时没有对二叉搜树进行介绍&#xff0c;而是把他放到数据结构进阶构专栏的第一期来介绍&#xff0c;原因是后面的map和set&#xff08;红黑树&#xff09;是基于搜索树的&#xff0c;这里…

Java-(乘法表之后)增强for循环

这里我们先做个了解&#xff0c;之后我会在数组中进行详细介绍Java5引入了一种主要用于数组或集合的增强型for循环Java增强型for循环语法格式如下 For(声明语句&#xff1a;表达式&#xff09;{ //代码语句 } 声明语句&#xff1a;声明新的局部变量&#xff0c;该变量的类型…

Windows中安装的PostgreSQL 数据库如何重启

1. 使用Windows服务管理器 打开“运行”对话框&#xff08;按WinR键&#xff09;。输入services.msc并按回车&#xff0c;这将打开服务列表。在服务列表中找到PostgreSQL服务。它通常命名为“PostgreSQL”后面跟着版本号和实例名称&#xff0c;例如“PostgreSQL 13 - mydb”。…

【云原生】Pod 的生命周期(一)

【云原生】Pod 的生命周期&#xff08;一&#xff09;【云原生】Pod 的生命周期&#xff08;二&#xff09; Pod 的生命周期&#xff08;一&#xff09; 1.Pod 生命期2.Pod 阶段3.容器状态3.1 Waiting &#xff08;等待&#xff09;3.2 Running&#xff08;运行中&#xff09;3…

后缀表达式

什么是后缀表达式&#xff1f; 在计算机科学和数学领域&#xff0c;表达式求值是一项基本且频繁的任务。我们熟知的中缀表达式&#xff08;如 7 15 ∗ 1 4 ∗ 1&#xff09;直观易读&#xff0c;但在计算机处理时却需要复杂的栈或递归算法来解析。相比之下&#xff0c;后缀表…

深度学习中的优化算法:选择现有的还是自创?

深度学习中的优化算法 深度学习中的优化算法&#xff1a;选择现有的还是自创&#xff1f;现有优化算法的优势**优点包括**&#xff1a; 开发新的优化算法的考虑**开发新算法的原因**&#xff1a;**开发新算法的风险**&#xff1a; 实用建议结论 深度学习中的优化算法&#xff1…

RabbitMQ 是如何做延迟消息的 ?——Java全栈知识(15)

RabbitMQ 是如何做延迟消息的 &#xff1f; 1、什么是死信&#xff1f; 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xff08;dead letter&#xff09;&#xff1a; 消费者使用 basic.reject 或 basic.nack 声明消费失败&#xff0c;并且消息的 reque…

5-在Linux上部署各类软件

1. MySQL 数据库安装部署 1.1 MySQL 5.7 版本在 CentOS 系统安装 注意&#xff1a;安装操作需要 root 权限 MySQL 的安装我们可以通过前面学习的 yum 命令进行。 1.1.1 安装 配置 yum 仓库 # 更新密钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022# 安装Mysql…

rk3588局域网推流

最近无意间看见在网上有使用MediaMtx插件配合ffmpeg在Windows来进行推流&#xff0c;然后在使用其他软件进行拉流显示数据图像的&#xff0c;既然windows都可以使用 &#xff0c;我想linux应该也可以&#xff0c;正好手上也有一块RK3588的开发板&#xff0c;就测试了一下&#…

iOS ------ JSONModel源码

一&#xff0c;JSONModel的基本使用 1&#xff0c;基本使用方法 - (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError **)err; - (instancetype)initWithData:(NSData *)data error:(NSError **)error; - (instancetype)initWithString:(NSString *)str…

Linux网络-部署YUM仓库及NFS共享服务

目录 一.YUM仓库服务 1.YUM概述 1.1.YUM&#xff08;Yellow dog Updater Modified&#xff09; 2.准备安装源 2.1.软件仓库的提供方式 2.2.RPM软件包的来源 2.3.构建CentOS 7 软件仓库 2.4.在软件仓库中加入非官方RPM包组 3.一键安装软件包的工具&#xff1a; 好处&a…

申请Sectigo证书流程详解

Sectigo&#xff08;前身为Comodo CA&#xff09;&#xff0c;是目前主流SSL证书的一种&#xff0c;目前全球范围内应用度也非常广泛&#xff0c;是目前众多品牌中市场份额最大的一个品牌了&#xff0c;在全球证书市场份额占比约为40%。 其超高的市场份额占比主要还是基于其超…

021、Python+fastapi,第一个Python项目走向第21步:ubuntu 24.04 docker 安装mysql8集群、redis集群(二)

系列文章目录 pythonvue3fastapiai 学习_浪淘沙jkp的博客-CSDN博客https://blog.csdn.net/jiangkp/category_12623996.html 前言 安装redis 我会以三种方式安装&#xff0c;在5月4号修改完成 第一、直接最简单安装&#xff0c;适用于测试环境玩玩 第二、conf配置安装 第三…

【Leetcode 42】 接雨水

基础思路&#xff1a; &#xff08;1&#xff09;需要将问题最小化&#xff0c;首先计算第i个位置最多容纳多少雨水&#xff08;细长的一条水柱&#xff09;&#xff0c;然后求和就是总的雨水量&#xff1b; &#xff08;2&#xff09;第i个位置容纳雨水量 min(左侧最高, 右…

​《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制德国每日风能和太阳能产量3D线图

在MATLAB中&#xff0c;要绘制3D线图&#xff0c;可以使用 plot3 函数。 在《MATLAB科研绘图与学术图表绘制从入门到精通》书中通过绘制德国每日风能和太阳能产量3D线图解释了如何在MATLAB中绘制3D线图。 购书地址&#xff1a;https://item.jd.com/14102657.html

牛客热题:单链表排序

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;单链表排序题目链接方法一&…

【XR806开发板试用】基于MQTT与Cjson库的花式点灯

一、项目介绍 久闻openharmony大名&#xff0c;一直没有机会接触&#xff0c;感谢极术社区和全志社区的这次活动&#xff0c;让我能够了解并上手这个系统。 openhamony 1.1的内核是基于liteos内核系统进行构建的&#xff0c;liteos作为物联网系统&#xff0c;结合xr806小型开…

美团KV存储squirrel和Celler学习

文章目录 美团在KV存储squirrel优化和改进在水平方向1、对Gossip协议进行优化 在垂直扩展方面1、forkless RDB数据复制优化2、使用多线程&#xff0c;充分利用机器的多核能力 在高可用方面 美团持久化kv存储celler优化和改进水平扩展优化1、使用bulkload进行数据导入2、线程模型…
最新文章