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

news2024/11/23 17:01:05

个人主页: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.coloradmin.cn/o/2188533.html

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

相关文章

微服务_3.微服务保护

文章目录 一、微服务雪崩及解决方法1.1、超时处理1.2、仓壁模式1.3、断路器1.4、限流 二、Sentinel2.1、流量控制2.1.1、普通限流2.1.2、热点参数限流 2.2、线程隔离2.3、熔断降级2.3.1、断路器状态机2.3.2、断路器熔断策略2.3.2.1、慢调用2.3.2.2、异常比例&#xff0c;异常数…

Redis --- 第三讲 --- 通用命令

一、get和set命令 Redis中最核心的两个命令 get 根据key来取value set 把key和value存储进去 redis是按照键值对的方式存储数据的。必须要先进入到redis客户端。 语法 set key value &#xff1a; key和value都是字符串。 对于上述这里的key value 不需要加上引号&#…

GIS发展趋势与国产GIS现状

地理信息系统&#xff08;GIS&#xff09;作为获取、管理、分析和可视化地理空间数据的重要工具&#xff0c;在多个领域发挥着至关重要的作用。随着技术的不断进步&#xff0c;GIS正朝着更高效、更智能的方向发展。 GIS发展趋势 1. 3D GIS与虚拟现实&#xff08;VR&#xff0…

滑动窗口--(上篇)

滑动窗口 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度**。**如果不存在符合条件的子数组&#xff0c;返回 0 。 …

LLM Visualization

Brendan Bycroft的网站&#xff0c;提供了交互式的可视化工具&#xff0c;展示了大型语言模型&#xff08;LLMs&#xff09;的内部机制 通过这个 链接 https://bbycroft.net/llm 访问 借助这个交互可视化&#xff0c;能够加深对模型结构和行为的了解

国庆更新|芒果YOLOv8改进181:即插即用,最新注意力机制EMA:具有跨空间学习的高效多尺度注意力模块,ICCASSP论文

💡本篇内容:芒果YOLOv8改进135:最新注意力机制EMA:即插即用,具有跨空间学习的高效多尺度注意力模块,ICCASSP 论文 **EMA|具有跨空间学习的高效多尺度注意力模块 | 即插即用 该模块通常包括多个并行的注意力子模块,每个子模块关注于输入数据的不同尺度或分辨率。这些子模块…

【SpringCloud】优雅实现远程调⽤-OpenFeign

OpenFeign 1. RestTemplate存在问题2. OpenFeign介绍Spring Cloud Feign 3. 代码获取 1. RestTemplate存在问题 观察咱们远程调⽤的代码 RequestMapping("/{orderId}")public OrderInfo getOrderInfoById(PathVariable("orderId") Integer id) {OrderInfo…

Ascend C 自定义算子开发:高效的算子实现

Ascend C 自定义算子开发&#xff1a;高效的算子实现 在 Ascend C 平台上&#xff0c;开发自定义算子能够充分发挥硬件的性能优势&#xff0c;帮助开发者针对不同的应用场景进行优化。本文将以 AddCustom 算子为例&#xff0c;介绍 Ascend C 中自定义算子的开发流程及关键技术…

Java中for循环控制

for循环控制 基本语法说明执行流程注意事项练习 基本语法 for(循环变量初始化;循环条件;循环遍历迭代){循环操作&#xff08;可以多条语句&#xff09;; }说明 1.for关键字&#xff0c;表示循环控制 2.for有四要素&#xff1a;&#xff08;1&#xff09;循环变量初始化 &…

Python+Matplotlib奇偶函数简单示例可视化

偶函数 定义&#xff1a;如果对于定义域内的任意 x&#xff0c;都有 f(-x) f(x)&#xff0c;则称 f(x) 为偶函数。 特点&#xff1a;偶函数的图像关于 y 轴对称。 奇函数 定义&#xff1a;如果对于定义域内的任意 x&#xff0c;都有 f(-x) -f(x)&#xff0c;则称 f(x) 为奇函…

【计算机网络】详解UDP协议格式特点缓冲区

一、UDP 协议端格式 16 位 UDP 长度, 表示整个数据报(UDP 首部UDP 数据)的最大长度&#xff1b;如果16位UDP检验和出错&#xff0c;报文会被直接丢弃。 1.1、检验和出错的几种常见情况 数据传输过程中的比特翻转&#xff1a;在数据传输过程中&#xff0c;由于物理介质或网络设…

COMSOL金属氢化物吸氢过程膨胀、应力

话不多说&#xff0c;先上效果图。事先说明&#xff1a;由于做吸氢膨胀和应力相关的文献很少&#xff0c;而且文献中很多细节、参数的地方也没怎么说&#xff0c;因此有些地方是笔者按自己理解编的&#xff0c;算是抛砖引玉&#xff0c;希望能给读者带来些许思路启发&#xff0…

【Simulink仿真】混合储能系统光储直流微网下垂控制

摘要 混合储能系统&#xff08;HESS&#xff09;结合光伏发电和储能技术&#xff0c;已成为提高直流微网系统稳定性和能效的有效手段。本文基于Simulink平台&#xff0c;仿真研究了光储直流微网中的下垂控制策略。仿真模型涵盖了电池储能和超级电容储能&#xff0c;采用下垂控…

11. 异步编程

计算机的核心部分&#xff0c;即执行构成我们程序的各个步骤的部分&#xff0c;称为处理器。我们迄今为止看到的程序都会让处理器忙个不停&#xff0c;直到它们完成工作。像操作数字的循环这样的程序的执行速度几乎完全取决于计算机处理器和内存的速度。但是&#xff0c;许多程…

【C++差分数组】2406. 将区间分为最少组数|1731

本文涉及知识点 C差分数组 LeetCode2406. 将区间分为最少组数 给你一个二维整数数组 intervals &#xff0c;其中 intervals[i] [lefti, righti] 表示 闭 区间 [lefti, righti] 。 你需要将 intervals 划分为一个或者多个区间 组 &#xff0c;每个区间 只 属于一个组&#…

HTB:Included[WriteUP]

目录 连接至HTB服务器并启动靶机 1.What service is running on the target machine over UDP? 2.What class of vulnerability is the webpage that is hosted on port 80 vulnerable to? 3.What is the default system folder that TFTP uses to store files? 4.Whic…

TCP --- 确认应答机制以及三次握手四次挥手

序言 在前一篇文章中&#xff0c;我们介绍了 UDP协议 (点击查看)&#x1f448;&#xff0c;该协议给我们的感觉就两个字 — 简单&#xff0c;只是将我们的数据进行简单的添加报头然后发送。当然使用起来虽然简单&#xff0c;但是否能送到目的地&#xff0c;那就要看网络的状态了…

【算法系列-链表】链表相交 环形链表II

【算法系列-链表】链表相交&环形链表 文章目录 【算法系列-链表】链表相交&环形链表1. 链表相交1.1 思路分析&#x1f3af;1.2 解题过程&#x1f3ac;1.3 代码示例&#x1f330; 2. 环形链表II2.1 思路分析&#x1f3af;2.2 代码示例&#x1f330; 1. 链表相交 【题目…

C/C++:内存管理

文章目录 前言一、内存分区1. 内存划分情况2. 最大内存计算 二、malloc/calloc/realloc 与 free1. malloc2. calloc3. realloc4. free5. 差异对比6. 失败处理 三、内存分配题目1. 题目2. 内存区域划分 四、C内存管理方式1. new 与 delete2. new/delete操作内置类型3. new和dele…

数据科学基础复习(简)

可视化、数据可视化 在狭义上&#xff0c;数据可视化是与信息可视化&#xff0c;科学可视化和可视分析学平行的概念&#xff0c;而在广义上数据可视化可以包含这3类可视化技术。 数据科学的主要任务 数据科学研究目的与任务 大数据及其运动规律的揭示从数据到智慧的转化数据…