Linux环境基础开发工具使用(2)

news/2024/10/5 18:12:08 标签: linux, 运维, 服务器

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

Linux环境基础开发工具使用(2)

收录于专栏[Linux学习]
本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. Linux项目自动化构建工具-make/Makefile

1.1背景: 

1.2 示例代码:

1.3 依赖关系

1.4 依赖方法:

1.4 补充: 

1.5 实现原理:

2. Linux第一个小程序-进度条

2.1: \r&&\n

2.2: 缓冲区概念

2.3 进度条代码 

3. 使用git命令行

3.1 安装git

3.2 git三板斧 

3.2.1 git add

3.2.2 git commit

3.2.3 git push 

4. 使用gitee创建项目

4.1 注册账号:

4.2 创建项目:

4.3 下载到本地:

5.  Linux调试器-gdb使用

5.1 使用背景: 

​5. 2使用方法:

5.3 实例展示: 


1. Linux项目自动化构建工具-make/Makefile

1.1背景: 

1. 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力

2. 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作

3. makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

4. make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。

5. make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

1.2 示例代码:

 我们在Linux环境中新建一个proc.c文件,写入以下代码并保存:

 #include <stdio.h>
 
 int main()
 {
   printf("hellolinux!");
   printf("hello make");
   printf("hello makefile");
   return 0;
}                                                                                                                                                                                          

 我们再创建一个makefile文件,写入代码:

然后make直接运行:

这里直接我们使用make直接编译了代码,形成了可执行程序

proc: 后面的一行内容是依赖文件 另起一行的内容是依赖关系

依赖方法可以是任意指令:

 

 如何清理项目:

.PHONY(让依赖方法忽略掉时间比,对应的方法总能执行) + 对应的方法(rm -f proc)

 

1.3 依赖关系

 

上面的文件 proc它依赖proc.o,proc.o 它依赖proc.s,proc.s它依赖proc.i,proc.i它依赖 hello.c 

1.4 依赖方法:

 gcc proc.* -option proc.* ,就是与之对应的依赖方法

1.4 补充: 

% : makefile语法中的通配符

%.c : 当前目录下所有.c文件,展开到依赖列表中

gcc -c $< 依赖关系 : 右侧的依赖文件一个一个的交给gcc -c选项,形成同名文件

1. proc: proc.o
        proc : 这是一个目标(target),表示要生成的最终可执行文件的名称。
        proc.o : 这是目标的依赖文件(dependency),表示生成 proc 需要的对象文件(.o 文件)。在这个例子中,proc 依赖于 proc.o。
2. gcc proc.o - o proc
        这条命令在 proc.o 目标被创建后执行,目的是将对象文件链接成可执行文件。
        gcc : 使用 GCC 编译器。
        proc.o : 作为输入的对象文件。
        - o proc : 指定输出文件的名称为 proc。因此,执行这条命令后会生成一个名为 proc 的可执行文件。
3. % .o : % .c
        这是一个模式规则(pattern rule),用于定义如何从 C 源文件生成对应的对象文件。
        % .o : 表示任意对象文件(以.o 结尾)。
        % .c : 表示与之对应的 C 源文件(以.c 结尾)。
        例如,如果有一个源文件 example.c,那么这条规则会自动应用,生成 example.o。
4. gcc - c $ <
        这是模式规则中的命令,用于编译 C 源文件为对象文件。
        gcc - c $ < :
        -c : 选项告诉编译器只编译源文件,而不进行链接。生成的结果是目标文件(.o 文件)。
        $ < : 这是一个自动变量,代表当前规则的第一个依赖文件。在这个规则中,它将是匹配的.c 文件。例如,如果正在处理 example.c,那么 $ < 将会被替换为 example.c,所以执行的命令为 gcc - c example.c。 

1.bin = proc
        bin : 这是一个变量,定义了最终生成的可执行文件的名称为 proc。在后面的规则中,可以使用 $(bin) 来引用这个变量。
2.src = proc.o
        src : 这是另一个变量,定义了生成可执行文件所需的对象文件(在这里是 proc.o)。同样,可以在后面的规则中使用 $(src) 来引用这个变量。
3.$(bin) : $(src)
        这是一个目标(target)定义,表示要生成的可执行文件 $(bin) 依赖于对象文件 $(src)。
        $(bin) : 这将被替换为 proc。
        $(src) : 这将被替换为 proc.o。
4.gcc $ ^ -o $@
        这是目标 $(bin) 的命令行,负责将对象文件链接为可执行文件。
        gcc : 使用 GCC 编译器进行链接。
        $ ^ : 自动变量,代表当前目标的所有依赖文件(在这个例子中是 proc.o)。在只有一个依赖的情况下,它的值就是 proc.o。
        - o $@ :
        -o : 用于指定输出文件的名称。
        $@ : 自动变量,代表当前目标的名称。在这个例子中,$@ 的值为 proc。
        整体上,这一行的命令为 gcc proc.o - o proc,用于生成可执行文件 proc。
5.% .o : % .c
       这是一个模式规则(pattern rule),用于定义如何从 C 源文件生成对应的对象文件。
       % .o : 代表任意对象文件(以.o 结尾)。
       % .c : 代表与之对应的 C 源文件(以.c 结尾)。
       例如,如果有一个源文件 example.c,那么这条规则将应用,生成 example.o。
6.gcc - c $ <
       这是模式规则的命令,负责编译 C 源文件为对象文件。
       gcc - c $ < :
      -c : 选项告诉编译器只编译源文件,而不进行链接,生成目标文件(.o 文件)。
       $ < : 自动变量,代表当前规则的第一个依赖文件。在这个规则中,它将是匹配的.c 文件。例如,如果正在处理 example.c,那么 $ < 将会被替换为 example.c,所以实际执行的命令将为 gcc - c example.c。 

1.5 实现原理:

1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“proc”这个文件,并把这个文件作为最终的目标文件。
3. 如果proc文件不存在,或是proc所依赖的后面的proc.o文件的文件修改时间要比proc这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成proc这个文件。
4. 如果proc所依赖的proc.o文件不存在,那么make会在当前文件中找目标为proc.o文件的依赖性,如果找到则再根据那一个规则生成proc.o文件。(这有点像一个堆栈的过程)
5. 当然,你的C文件和H文件是存在的啦,于是make会生成 proc.o 文件,然后再用 proc.o 文件声明make的终极任务,也就是执行文件proc了。
6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

 总结:
1. makefile文件,会被make从上到下开始扫描,第一个目标名,是缺省要形成的.如果我们想执行其他组的依赖关系和依赖方法,make name

2. make makefile在执行gcc命令的时候,如果发生了语法错误,就会终止推到过程

3. make解释makefile的时候,是会自动推导的,一直推导,推导过程不执行依赖方法,直到推导到依赖文件存在,然后在逆向执行所有的依赖方法

4. make默认只形成一个可执行程序

2. Linux第一个小程序-进度条

2.1: \r&&\n

回车(CR)
定义:回车是指将光标或打印头移到当前行的起始位置。它的控制字符表示为 \r。
用途:在某些情况下(如老旧的打印机和某些文本格式),回车用于将文本移动到行首,但不会换到下一行。
换行(LF)
定义:换行是指将光标移动到下一行的相同位置。其控制字符表示为 \n。
用途:换行通常用于开始一行新的文本。  

2.2: 缓冲区概念

在 Linux 和其他操作系统中,缓冲区是用于临时存储数据的内存区域。它在数据传输或处理的过程中发挥着重要作用,能够提高系统的性能和效率。 

缓冲区(Buffer)是计算机内存中的一块区域,用于暂时存放数据。在数据处理、传输或 I/O 操作中,缓冲区可以减少 CPU 等待 I/O 操作的时间,提高整体效率。 

代码示例:

#include <stdio.h>
int main()
{
	printf("hello Makefile!\n");
	sleep(3);
	return 0;
}

1. 输出格式:这个程序在打印 "hello Makefile!" 后添加了换行符(\n)。
2. 缓冲行为:
printf 默认使用行缓冲,这意味着输出将被缓存在内部,直到遇到换行符、缓冲区满或显式刷新(如使用 fflush)时才会显示。由于输出中包含换行符,因此在 sleep(3) 之前,信息会立即被打印到终端。
3. 结果:程序会在终端上立即显示 hello Makefile!,然后暂停 3 秒后退出。

#include <stdio.h>
int main()
{
	printf("hello Makefile!");
	sleep(3);
	return 0;
}

1. 输出格式:此程序在打印 "hello Makefile!" 时没有添加换行符。
2. 缓冲行为:
由于没有换行符,printf 将使用行缓冲,但输出不会立即显示,因为没有触发输出的条件。
在 sleep(3) 期间,程序仍然会在缓冲区中保存输出,而不会将其显示到终端。
3. 结果:在 3 秒后,程序将退出。取决于环境的实现(例如某些 IDE 或终端模拟器),可能会在程序结束时输出 hello Makefile!,但在 3 秒内不会看到任何输出。这可能会让用户感觉程序没有任何反应。

#include <stdio.h>
int main()
{
	printf("hello Makefile!");
	fflush(stdout);
	sleep(3);
	return 0;
}

1. 输出格式:与第二个代码片段一样,没有换行符。
2. 缓冲行为:
在调用 fflush(stdout) 后,程序会强制刷新标准输出缓冲区,将任何已缓存的内容立即输出到终端。
因此,尽管没有换行符,printf 的内容会在 sleep(3) 之前被显示。
3. 结果:程序将立即显示 hello Makefile!,然后在 3 秒后退出。通过使用 fflush,程序的行为与第一个代码片段类似,输出将及时呈现给用户。

总结:

第一个代码片段:由于使用了换行符,输出立即显示,之后程序暂停 3 秒。
第二个代码片段:没有换行符,输出在程序结束时才显示,造成用户认为程序没有响应。
第三个代码片段:使用了 fflush(stdout) 强制刷新,确保输出在 3 秒的等待之前显示。 

2.3 进度条代码 

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int i = 0;
    char bar[101]; // 只需 100 个字符 + 1 个结束符
    memset(bar, 0, sizeof(bar)); // 初始化数组
    const char* label = "|/-\\"; // 动画字符

    while (i <= 100) {
        // 使用 `i` 作为进度条的填充字符数
        printf("[%-100s][%d%%][%c]\r", bar, i, label[i % 4]);
        fflush(stdout);

        // 在这里更新进度条
        if (i < 100) {
            bar[i] = '#'; // 更新当前进度位置
        }

        usleep(100000); // 睡眠 100 毫秒
        i++; // 更新进度
    }

    // 输出完成后的进度条
    printf("[%-100s][100%%][✔️]\n", bar);
    return 0;
}

输出当前状态:

printf("[%-100s][%d%%][%c]\r", bar, i, label[i % 4]); :
% -100s:格式化字符串,显示当前 bar 的内容(最多 100 个字符,左对齐)。
% d % %:输出当前进度百分比 i,并显示 % %作为百分号。
% c:输出当前动画字符。
\r:回到当前行的开头,允许在同一行更新输出。
fflush(stdout); :确保缓冲区的内容立即输出到终端,而不是等到缓冲区满或程序结束。 

 效果展示:

3. 使用git命令行

3.1 安装git

yum install git

3.2 git三板斧 

这里就拿我Linux上传gitee代码为例:

3.2.1 git add

3.2.2 git commit

 git commit -m "这里写备注(也就是你做了什么)"

3.2.3 git push 

 push之后,我们就成功将我们今天的linux2上传到了gitee

 大家在尝试之前一定要确保: 1. 你在gitee上已经创建好了项目 2. 你上传的文件是你gitee创建项目的克隆(这个大家不要着急下面有相关讲解)

4. 使用gitee创建项目

4.1 注册账号:

登录gitee官网直接跟流程注册就行

gitee官网 -- Gitee - 基于 Git 的代码托管和研发协作平台

4.2 创建项目:

点击加号新建仓库

 前面的仓库名称和介绍大家可以根据自己项目取名

一般我们都会选择开源,然后自己选择语言,模板和许可证可以不填,模板方面选择Readme文件,最后分支一个一般使用单分支模型 

最后点击创建即可 

4.3 下载到本地:

点击自己已将创建好的仓库,右上角有克隆/下载的方块

点击复制你仓库的地址

创建好一个放置代码的目录.然后使用命令

git clone [你自己仓库的地址]

5.  Linux调试器-gdb使用

5.1 使用背景: 

程序的发布方式有两种,debug模式和release模式
Linux gcc / g++出来的二进制程序,默认是release模式
要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 - g 选项 

 5. 2使用方法:

gdb binFile 退出: ctrl + d 或 quit 
调试命令:

list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
list/l 函数名:列出某个函数的源代码。
r或run:运行程序。
n 或 next:单条执行。
s或step:进入函数调用
break(b)行号:在某一行设置断点
break 函数名:在某个函数开头设置断点
info break :查看断点信息。
finish:执行到当前函数返回,然后挺下来等待命令
print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
p 变量:打印变量值。
set var:修改变量的值
continue(或c):从当前位置开始连续而非单步执行程序
run(或r):从开始连续而非单步执行程序
delete breakpoints:删除所有断点
delete breakpoints n:删除序号为n的断点
disable breakpoints:禁用断点
enable breakpoints:启用断点
info(或i) breakpoints:参看当前设置了哪些断点
display 变量名:跟踪查看一个变量,每次停下来都显示它的值
undisplay:取消对先前设置的那些变量的跟踪
until X行号:跳至X行
breaktrace(或bt):查看各级函数调用及参数
info(i) locals:查看当前栈帧局部变量的值
quit:退出gdb

5.3 实例展示: 

 

 


http://www.niftyadmin.cn/n/5691139.html

相关文章

如何快速学习K8s

1.背景 最近在学习k8s相关&#xff0c;也写了相关的一些技术文。有童鞋私信我是怎么学k8s。我今天分享下相关的学习历程。 2.过程 工欲善其事必先利其器&#xff0c;除了电脑&#xff0c;还要有完整配套的资料去参考学习。所以大家应该先找一些比较完整的k8s资料去看&#xf…

Oracle SQL语句没有过滤条件,究竟是否会走索引??

答案是&#xff1a;可能走索引也可能不走索引&#xff0c;具体要看列的值可不可为null&#xff0c;Oracle不会为所有列的nullable属性都为Y的sql语句走索引。 例子&#xff1a; create table t as select * from dba_objects; CREATE INDEX ix_t_name ON t(object_id, objec…

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据量&#xff1a;3k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种…

python中的函数介绍

文章目录 1.函数1.1 语法格式1.2 函数参数1.3 函数的返回值1.4 变量作用域1.5 函数的执行过程1.6 链式调用1.7 嵌套调用1.8 函数栈帧1.9 函数递归1.10 参数默认值1.11 关键词参数 1.函数 无论是编程中的函数还是数学中的函数&#xff0c;本质都是差不多的&#xff0c;丢给函数…

软件设计师——数据结构

本博文所有内容来自于B站up主zst_2001 目录 时间复杂度 常规数据结构 链表 栈与队列 ​编辑 串 数组 树 卡特兰数&#xff1a; 平衡二叉树 哈夫曼 图 AOV 排序 顺序 折半 哈希 时间复杂度 常规数据结构 链表 栈与队列 串 找i位置前面的字符串&#xff0c…

优优嗨聚集团:债务纠纷下的个人财务困境揭秘

在当今社会&#xff0c;随着经济活动的日益频繁与复杂化&#xff0c;债务问题已成为许多人生活中难以回避的挑战之一。债务纠纷&#xff0c;作为这一问题的直接体现&#xff0c;不仅关乎金钱的得失&#xff0c;更深刻地影响着个人的生活方方面面&#xff0c;从心理健康、家庭关…

电器自动化入门08:隔离变压器、行程开关介绍及选型

视频链接&#xff1a;3.4 电工知识&#xff1a;三相交流异步电动机自动往返行程控制及控制变压器选型_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p8&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.隔离&#xff08;控制&#xff09;变压器 2.行程开…

win11无法输入中文,任务栏中输入法消失

一、问题描述 今日起了个大早&#xff0c;一打开电脑&#xff0c;王德发&#xff0c;我的输入法呢&#xff1f;&#xff1f;&#xff1f;我没了输入法就像西方没了耶路撒冷&#xff0c;刚睡醒懵笔的我瞬间懵笔了┏┛墓┗┓…(((m -__-)m 二、解决办法 心急如焚的我立马上网…