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

个人主页: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 实例展示: 

 

 

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

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

相关文章

VS开发 - 静态编译和动态编译的基础实践与混用

目录 1. 基础概念 2. 直观感受一下静态编译和动态编译的体积与依赖项目 3. VS运行时库包含哪些主要文件&#xff08;从VS2015起&#xff09; 4. 动态库和静态库混用的情况 5. 感谢清单 1. 基础概念 所谓的运行时库&#xff08;Runtime Library&#xff09;就是WINDOWS系统…

防反接电路设计

方案1 串联二极管&#xff0c; 优点&#xff1a;成本低、设计简单 缺点&#xff1a;损耗大&#xff0c;P ui 方案2 串联自恢复保险丝 当电源反接的时候&#xff0c;D4导通&#xff0c;F2超过跳闸带你留&#xff0c;就会断开&#xff0c;从而保护了后级电路 方案3 H桥电路…

解决DHCP服务异常导致设备无法获取IP地址的方法

DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数&#xff0c;可以简化网络配置过程。但是&#xff0c;如果DHCP服务出现异常时&#xff0c;设备可能无法正常获取IP地址&#xff0c;会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…

No.2 笔记 | 网络安全攻防:PC、CS工具与移动应用分析

引言 在当今数字化时代,网络安全已成为每个人都应该关注的重要话题。本文将总结一次关于网络安全攻防技术的学习内容,涵盖PC端和移动端的恶意程序利用,以及强大的渗透测试工具Cobalt Strike的使用。通过学习这些内容,我们不仅能够了解攻击者的手法,更能提高自身的安全意识和防…

Java编码方式:Base64编码与解码

1、Base64 算法介绍 Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。它主要用于在不支持二进制数据的场合&#xff08;如电子邮件、URL、文件系统名等&#xff09;传输二进制数据。严格来说 Base64 并不是一种加密/解密算法&#xff0c;而是一种编码方式。Bas…

基于Springboot+Android的的电子书阅读器系统的设计与实现(含源码+数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 该系统…

二分查找一>山脉数组的峰顶索引

1.题目&#xff1a; 2.解析&#xff1a; 代码&#xff1a; public int peakIndexInMountainArray(int[] arr) {int left 1, right arr.length-2;while(left < right) {int mid left (right-left1) / 2;if(arr[mid] > arr[mid-1]) left mid;else right mid-1;}ret…

openpnp - 视觉原点的位置要离设备的软限制点远一点

文章目录 openpnp - 视觉原点的位置要离设备的软限制点远一点笔记备注END openpnp - 视觉原点的位置要离设备的软限制点远一点 笔记 最开始的视觉原点&#xff0c;是在设备X 0, Y 0的附近位置&#xff0c;粘了一块20x20x20的铝块&#xff0c;铝块上面贴着用黑塑料皮打印的1…

esp8266 at指令链接wifi时一直connect disconnest

那是你的连接wifi的名字密码有误或者热点有问题&#xff0c;看看热点是不是把设备拉入黑名单或者设置为5G或者连了校园网或者设置了最多链接设备

IntelliJ IDEA 2024.2 新特性概览

文章目录 1、重点特性:1.1 改进的 Spring Data JPA 支持1.2 改进的 cron 表达式支持1.3 使用 GraalJS 作为 HTTP 客户端的执行引擎1.4 更快的编码时间1.5 K2 模式下的 Kotlin 性能和稳定性改进 2、用户体验2.1 改进的全行代码补全2.2 新 UI 成为所有用户的默认界面2.3 Search E…

C++模拟实现vector容器【万字模拟✨】

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; 学习专栏C语言_Stark、的博客-CSDN博客 项目实战C系列_Stark、的博客-CSDN博客 数据结构与算法_Stark、的博客-CSDN博客 座右铭&#xff1a;梦想是一盏明灯&#xff…

设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)

文章目录 设计模式概述1、原型模式2、原型模式的使用场景3、优点4、缺点5、主要角色6、代码示例7、总结题外话关于使用序列化实现深拷贝 设计模式概述 创建型模式&#xff1a;工厂方法、抽象方法、建造者、原型、单例。 结构型模式有&#xff1a;适配器、桥接、组合、装饰器、…

深度学习中的结构化概率模型 - 结构化概率模型的深度学习方法篇

序言 在深度学习的广阔领域中&#xff0c;结构化概率模型&#xff08; Structured Probabilistic Model \text{Structured Probabilistic Model} Structured Probabilistic Model&#xff09;扮演着至关重要的角色。这类模型利用图论中的图结构来表示概率分布中随机变量之间的…

Spring Boot ⽇志

目录 1.⽇志使⽤ 2.⽇志级别 3.⽇志配置 3.1配置⽇志级别 3.2⽇志持久化 3.3配置⽇志⽂件分割 4.更简单的⽇志输出 1.⽇志使⽤ 在使用之前我们先来了解一下为什么要使用&#xff1f; ⽇志的⽤途 1.系统监控 我们可以通过⽇志记录这个系统的运⾏状态&#xff0c;对数…

20款奔驰CLS300升级原厂抬头显示HUD 23P智能辅助驾驶 触摸屏人机交互系统

以下是为您生成的一份关于 18 款奔驰 CLS 老款改新款的改装文案&#xff1a; 18 款奔驰 CLS 老款改新款&#xff1a;科技升级&#xff0c;畅享极致驾驶体验 在汽车改装的世界里&#xff0c;每一次的升级都是对卓越的追求。今天&#xff0c;让我们一同探索 18 款奔驰 CLS 老款改…

在登陆功能中添加Redis缓存

目录 基于Redis实现短信登录 实现流程图 实现代码 解决登录状态刷新问题 初始方案思路&#xff1a; 实现代码 发送验证码 登陆实现 如果是新用户则自动创建 运行测试 基于Redis实现短信登录 实现流程图 实现代码 Overridepublic Result login(LoginFormDTO loginForm…

Thinkphp/Laravel旅游景区预约系统的设计与实现

目录 技术栈和环境说明具体实现截图设计思路关键技术课题的重点和难点&#xff1a;框架介绍数据访问方式PHP核心代码部分展示代码目录结构解析系统测试详细视频演示源码获取 技术栈和环境说明 采用PHP语言开发&#xff0c;开发环境为phpstudy 开发工具notepad并使用MYSQL数据库…

【深度学习】— 多层感知机介绍、 隐藏层、从线性到非线性、线性模型的局限性

【深度学习】— 多层感知机介绍 4.1 多层感知机4.1.1 隐藏层线性模型的局限性引入隐藏层 4.2 从线性到非线性线性组合的局限性引入非线性堆叠更多隐藏层 4.1 多层感知机 在第 3 节中&#xff0c;我们介绍了 softmax 回归&#xff0c;并实现了其从零开始的实现和基于高级 API 的…

如何在dblp官网下载外文文献

文章目录 零、dblp官网一、直接下载pdf二、Zotero 零、dblp官网 ①老域名&#xff1a;https://dblp.uni-trier.de/ ②简化域名&#xff1a;dblp.org 一、直接下载pdf 1.举例&#xff0c;搜索 image matching 2.直接点击红色的PDF按钮 (可能会因为卡&#xff0c;点了没反应。…

No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史

大家好&#xff01;作为一个喜欢探索本质的INTP&#xff0c;我整理了一份简明易懂的Web安全笔记。希望能帮助你轻松掌握这个领域的核心知识。 这份笔记涵盖了Web发展的历程&#xff0c;从静态的Web 1.0到智能化的Web 3.0。我们将探讨URL和HTTP协议&#xff0c;揭示它们在网络中…