【Linux】基本开发工具的使用-yumvimgcc/g++git

news2025/1/16 9:12:59

文章目录

  • Linux 软件包管理器-yum
      • 什么是软件包
      • window和Linux互传文件的工具: lrzsz
      • yum注意事项
      • 查看软件包
        • 注意事项
      • 如何安装软件
        • 注意事项
      • 如何卸载软件
    • 好玩的指令
      • sl 小火车
      • cowsay 打印一只说话的小牛
      • boxes 打印一个ASCII的动画
      • linux_logo 显示linux系统的logo
      • curl http://wttr.in 显示天气情况
  • Linux编辑器-vim使用
      • 基本概念
      • vim的基本操作
      • vim命令模式命令集
      • vim底行模式命令集
      • vim操作总结
      • 批量注释和批量去注释
      • 使用vim替换字符
      • 不退出vim使用手册man
      • 简单vim配置
        • 配置文件的位置:
        • 常用配置选项
      • 把用户加入到信任列表中
  • Linux编译器-gcc/g++使用
      • 背景知识
      • gcc/g++语法
      • gcc选项
      • 预处理(进行宏替换)
      • 编译(生成汇编)
      • 汇编(生成机器可以识代码)
      • 链接(生成可执行文件或库文件)
      • 静态库和动态库
  • Linux调试器-gdb使用
      • 背景
      • 指令
  • Linux项目自动化构建工具-make/Makefile
      • 背景
      • 关于依赖关系和依赖方法
      • 多文件编译时:
      • make原理
      • 项目清理
  • 回车与换行
      • 倒计时程序
  • Linux下的进度条小程序
      • 需要注意的细节:
  • 关于git
      • 第一招:git add
      • 第二招:git commit
      • 第三招:git push
      • 配置免密码上传
  • 用vim写其它语言的代码

Linux 软件包管理器-yum

什么是软件包

  • 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序
  • 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.
  • 软件包和软件包管理器, 就好比 “App” 和 “应用商店” 这样的关系
  • yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat,
    Centos等发行版上

必须安装的东西:

  • man手册: sudo yum install -y man-pages
  • 安装拓展元 sudo yum install -y epel-release

window和Linux互传文件的工具: lrzsz

这个工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件,安装完毕之后可以通过拖拽的方式将文件上传过去

  • 需要先安装:sudo yum install lrzsz
image-20220406200847249 image-20220406200903988

当然了,也可以直接输入指令来上传 rz -E 接收:云服务可接受本地及其上传的指定文件

image-20220406201205030

sz 文件名 发送:可将云服务器上的文件发送到本地机器的指定位置

image-20220406201144006

yum注意事项

1.关于 yum 的所有操作必须保证主机(虚拟机)网络畅通 2.centor里面,只能有一个yum在运行,即一次只能安装一个软件

可以通过 ping 指令验证

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yq6VMi6a-1675492841935)(https://mangoimage.oss-cn-guangzhou.aliyuncs.com/ping%E6%8C%87%E4%BB%A4.png)]


查看软件包

sudo yum list 默认列出所有的软件, 但是数目有很多,我们可以使用管道| 和 行过滤指令grep进行过滤搜索

以sl小火车为例:sudo yum list | grep sl

例子:

yum list | grep lrzsz

image-20220330082235104


注意事项

  • 软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构
  • “x86_64” 后缀表示64位系统的安装包, “i686” 后缀表示32位系统安装包. 选择包时要和系统匹配
  • “el7” 表示操作系统发行版的版本. “el7” 表示的是 centos7/redhat7. “el6” 表示 centos6/redhat6
  • 最后一列, base 表示的是 “软件源” 的名称, 类似于 “小米应用商店”, “华为应用商店” 这样的概念

如何安装软件

通过 yum, 我们可以通过很简单的一条命令完成 gcc 的安装. sudo yum install lrzsz

yum 会自动找到都有哪些软件包需要下载, 这时候敲 “y” 确认安装->出现 “complete” 字样, 说明安装完成

例子:

image-20220404205423180


注意事项

  • 安装软件时由于需要向系统目录中写入内容, 一般需要 sudo 或者切到 root 账户下才能完成
  • yum安装软件只能一个装完了再装另一个. 正在yum安装一个软件的过程中, 如果再尝试用yum安装另外一个软件, yum会报错

如何卸载软件

sudo yum remove 软件名

例子: sudo yum remove lrzsz 加上-y 选项 -> 不询问直接安装/卸载


好玩的指令

sl 小火车

  • 安装: sudo yum install -y sl 执行: sl

image-20220404210324289

参数:

  • -c 显示有故障的小火车 -F 由下而上的小火车

cowsay 打印一只说话的小牛

  • 安装:sudo yum install -y cowsay 执行: cowsay 字符串

image-20220404210553811

boxes 打印一个ASCII的动画

  • 安装:sudo yum install -y boxes 执行: echo “要显示的内容” |boxes -d dog 或者: echo “要显示内容” |boxes -d cat
image-20220404210859198

linux_logo 显示linux系统的logo

  • 安装: sudo yum install -y linux_logo 执行:linux_logo
image-20220404214029506

参数:

  • -a 取消颜色输出

  • -L +数字 后面跟着数字,输入不同系统的logo


curl http://wttr.in 显示天气情况

image-20220404213949794

Linux编辑器-vim使用

vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面.例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于x window、 mac os、windows.


基本概念

主要了解vim的三种模式: 命令模式(command mode)插入模式(Insert mode)和底行模式(last line mode)


  • 正常/普通/命令模式(Normal mode)
    • 控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode
  • 插入模式(Insert mode)
    • 只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式.该模式是我们后面用的最频繁的编辑模式.
  • 底行模式(last line mode)
    • 文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作. 在命令模式下,shift+: 即可进入该模式.要查看你的所有模式:打开vim,底行模式直接输入

在底行模式中输入:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f4Z0C6MD-1675492841943)(https://mangoimage.oss-cn-guangzhou.aliyuncs.com/%E6%9F%A5%E7%9C%8Bvim%E7%9A%84%E6%A8%A1%E5%BC%8F.png)]

可以查看到vim的模式有什么:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oh95vtKT-1675492841944)(https://mangoimage.oss-cn-guangzhou.aliyuncs.com/vim%E7%9A%84%E6%A8%A1%E5%BC%8F.png)]


vim的基本操作

进入vim,在系统提示符号输入vim及文件名称后,就进入vim全屏幕编辑画面

例如:vim test.c

vim后面跟的文件名,如果该文件不存在,则会自动创建文件然后打开, 如果存在,则直接打开 注意:进入vim之后,是处于[正常模式],你要切换到[插入模式]才能够输入文字.


vim命令模式命令集

  • 按「i」切换进入插入模式「insert mode」,按“i”进入插入模式后是从光标当前位置开始输入文件;
  • 按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;
  • 按「o」进入插入模式后,是插入新的一行,从行首开始输入文字.
  • 从插入模式切换为命令模式 : 按esc键
  • 移动光标
    • vim可以直接用键盘上的光标来上下左右移动,但正规的vim是用小写英文字母「h」、「j」、「k」、「l」,分别控制光标左、下、上、右移一格
      • 记忆方式: h键在做左侧,l在左右侧 表示左右 j:jump 往下跳 k:king 高高在上
    • 按「G」:移动到文章的最后
    • 按「shift+ $ 」:移动到光标所在行的“行尾”
    • 按「shift+^」:移动到光标所在行的“行首”
    • 按照单词为单位进行前后光标移动
      • 按「w」:光标跳到下个单词的开头
      • 按「e」:光标跳到下个单词的字尾
      • 按「b」:光标回到上个字词的开头
    • 按[gg]:进入到文本开始 (跳到起始行)
    • 按[shift+g]:进入文本末端 (跳到结束行)
      • n+shift+g :跳到指定行
    • 按「ctrl」+「b」:屏幕往“后”移动一页
    • 按「ctrl」+「f」:屏幕往“前”移动一页
    • 按「ctrl」+「u」:屏幕往“后”移动半页
    • 按「ctrl」+「d」:屏幕往“前”移动半页

  • 删除文字
    • 「x」:小写的x, 每按一次,删除光标所在位置的一个字符 (小写的x:从左向右删除)
      • 支持nx 删除光标所在位置,及其往后的n个字符
    • 「#x」:例如,「6x」表示删除光标所在位置的“后面(包含自己在内)”6个字符
    • 「X」:大写的X,每按一次,删除光标所在位置的“前面”一个字符 (大写的x:从右向左删除)
      • 支持nX 删除光标所在位置,及其往前的n个字符
    • 「#X」:例如,「20X」表示删除光标所在位置的“前面”20个字符
    • 「dd」:删除光标所在行
      • 支持ndd 一次删除n行,包括当前行
    • 「#dd」:从光标所在行开始删除#行
  • 复制
    • 「yw」:将光标所在之处到字尾的字符复制到缓冲区中.

    • 「#yw」:复制#个字到缓冲区

    • 「yy」:复制光标所在行到缓冲区.

    • 「#yy」:例如,「6yy」表示拷贝从光标所在的该行“往下数”6行文字.

      • nyy 表示拷贝从光标所在的该行“往下数”n行文字,包括当前行
    • 「p」:将缓冲区内的字符贴到光标所在位置.

      • np:一次重复粘贴n行

      • 注意:所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能.

      • 先yy,然后直接np:在光标位置往后复制n行

      • dd之后再p :剪切

  • 替换
    • 「r」:替换光标所在处的字符
      • 支持nr 往后替换n个字符
    • 「R」:替换光标所到之处的字符,直到按下「ESC」键为止
    • shift + r 替换模式,直接进行多个内容的替换
  • 撤销上一次操作
    • 「u」:撤销误操作,如果您误执行一个命令,可以马上按下「u」,回到上一个操作.按多次“u”可以执行多次恢复
    • 「ctrl + r」: 撤销的恢复
  • 更改
    • 「cw」:删除从光标处到单词结尾的文本并进入到插入模式
    • 「c#w」:例如,「c3w」表示删除3个字
    • shift + ~ :快速大小写切换
  • 跳至指定的行
    • 「ctrl」+「g」列出光标所在行的行号
    • 「#G」:例如,「15G」,表示移动光标至文章的第15行行首

vim底行模式命令集

在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式

  • 列出行号
    • 「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号
    • set nonu:取消行号
  • 跳到文件中的某一行
    • 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行
  • 查找字符
    • 「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止.
    • 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往前寻找到您要的关键字为止.
  • 保存文件
    • 「w」: 在冒号输入字母「w」就可以将文件保存起来
  • 离开vim
    • 「q」:按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim
    • 「wq」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件
  • 强转 !
    • w! 强制退出 wq! 强制保存退出 q! 强制保存
  • vs文件: 多文件操作 [ctrl+w+w]

如何左右分屏:

在底行模式下, vs 文件名 可以不断分屏,往左侧分屏,如果vs后面的文件名不存在,则会默认先创建,再打开

image-20220404222550299

如何快速切换屏幕:

在底行模式下 按ctrl +w +w , 光标在哪里闪动,就说明哪个文件被选中,在该文件底行模式输入wq保存退出,保留的就是另外的文件


vim操作总结

主要使用三种模式:底行模式,命令模式,插入模式 vim操作:打开,关闭,查看,查询,插入,删除,替换,撤销,复制

image-20220404215611081

a i o都能进入插入模式

  • a:光标向后移动一个字符 i: o:在下面新起一行

验证:

image-20220404223606505

底行和插入不能直接跳转!!!


批量注释和批量去注释

批量化注释:

  • 在命令模式下 : ctrl + v 然后用l,j,k,h选中区域,然后按大写的I,会跳到第一个位置,输入//注释,然后按esc按键

批量化去注释:

  • 在命令模式下 : ctrl + v 然后用l,j,k,h选中区域,注意:要选中两个// 然后按小写的i,然后按d

使用vim替换字符

在底行模式下: :%s/你要替换的内容/替换成什么

  • 最好使用:%s/你要替换的内容xxx/替换成yyy/g才是将xxx全部替换为yyy 如果用上面的可能xxx.cc 不会替换为yyy.cc

image-20221005163939817


不退出vim使用手册man

如何不退出vim查看手册?

在底行模式下: !man 查询内容 按q退出,回到vim当中 例子: !man fork


简单vim配置

用户在配置vim的配置文件中,只会影响自己(用户)的操作, root有自己的vim配置文件,也只会影响自己(root)


配置文件的位置:

  • 在目录 /etc/ 下面,有个名为vimrc的文件,这是系统中公共的vim配置文件,对所有用户都有效.
  • 而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为:“.vimrc”
  • 例如,/root目录下,通常已经存在一个.vimrc文件,如果不存在,则创建之
  • 切换用户成为自己执行 su ,进入自己的主工作目录,执行 cd ~
  • 打开自己目录下的.vimrc文件,执行 vim .vimrc

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iLNI87Tz-1675492841950)(https://mangoimage.oss-cn-guangzhou.aliyuncs.com/.vimrc.png)]

注意:要在自己的工作目录(~)下创建.vimrc文件,最基本的vim的配置都写在.vimrc文件中,想要配置vim,只需要在.vimrc文件中添加内容即可


常用配置选项

只需在.vimrc文件中写入对应的内容即可:

  • 设置语法高亮: syntax on 显示行号: set nu 设置缩进的空格数为4: set shiftwidth=4

自动配置vim:

直接输入如下命令

curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh
image-20220404224555439

然后按照提示输入root密码,然后等待安装配置,最后手动执行source ~/.bashrc.配置完成后,类似自动补全、行号显示以及自动缩进等功能就有了


把用户加入到信任列表中

  • 首先需要在root用户下操作
  • 修改文件的内容: vim /etc/suduers
  • 下翻到具体位置,在插入模式下,按格式把用户添加到信任列表
image-20220514132402733

Linux编译器-gcc/g++使用

背景知识

gcc和g++分别是GNU的C和C++的编译器,gcc和g++在执行编译的时候一般有以下四个步骤
1)预处理(头文件展开、去注释、宏替换、条件编译)
2)编译(C代码翻译成汇编语言)
3)汇编(汇编代码转为二进制目标代码,生成机器可识别代码)
4)链接(将汇编过程产生的二进制代码进行链接,生成可执行文件或库文件)

image-20220409195717248


gcc/g++语法

格式 gcc/g++ [选项] 要编译的文件 [选项] [目标文件]

gcc选项

  • -E 只进行预处理,这个不生成文件,你需要把它重定向到一个输出文件里面,否则将把预处理后的结果打印到屏幕上
  • -S 编译到汇编语言,不进行汇编和链接,即只进行预处理和编译
  • -c 编译到目标代码
  • -o 将处理结果输出到指定文件,该选项后需紧跟输出文件名
  • -static 此选项对生成的文件采用静态链接
  • -g 生成调试信息,如果不带该选项,默认生成的是release版本.
  • -shared 此选项将尽量使用动态库,所以生成文件比较小
  • -O0/-O1/-O2/-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
  • -w 不生成任何警告信息.
  • -Wall 生成所有警告信息.

预处理(进行宏替换)

gcc -E test.c -o test.i

  • 预处理功能主要包括宏定义,文件包含,条件编译,去注释等.
  • 预处理指令是以#号开头的代码行.
  • 选项“-E”,该选项的作用是让 gcc/g++ 在预处理结束后停止编译过程.
  • 选项“-o”是指目标文件,“xxx.i”文件为已经过预处理的原始程序.
image-20220405202741423

编译(生成汇编)

gcc -S test.i -o test.s

  • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc/g++ 把代码翻译成汇编语言.
  • 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码.
  • 选项“-o”是指目标文件,“xxx.s”文件为已经过编译的原始程序
image-20220405202506828

汇编(生成机器可以识代码)

gcc -c test.s -o test.o

  • 汇编阶段是把编译阶段生成的“xxx.s”文件转成目标文件
  • 读者在此可使用选项“-c”就可看到汇编代码已转化为“xxx.o”的二进制目标代码了
image-20220405202900054

链接(生成可执行文件或库文件)

gcc test.o -o test

image-20220405203052187

  • 在成功编译之后,就进入了链接阶段.
  • 链接的主要任务就是将生成的各个“xxx.o”文件进行链接,生成可执行文件.
  • gcc/g++不带-E、-S、-c选项时,就默认生成预处理、编译、汇编、链接全过程后的文件.
  • 若不用-o选项指定生成文件的文件名,则默认生成的可执行文件名为a.out.

image-20220405203116212


注意:链接后生成的也是二进制文件

image-20220405203203785

如果想直接生成可执行程序:

gcc test.c -o test 或者: gcc -o mytest mytest.c也行 ,生成名字为mytest的可执行程序


静态库和动态库

上面涉及到一个重要的概念:函数库

  • 我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢
    • 答案是:系统把这些函数实现都写到名为 libc.so.6 的库中,在没有指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,然后链接到 libc.so.6 库,去,这样就有printf函数的实现了,而这也就是链接的作用

函数库一般分为静态库和动态库两种: windows下:静态库后缀名一般为.lib 动态库后缀名一般为:.dll


  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了.静态库后缀名一般为“.a”

  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销.动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库.gcc 在编译时默认使用动态库完成了链接之后,gcc 就可以生成可执行文件.

  • gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证.

    • file命令:查看文件的详细信息

    image-20220405203435092

  • gcc/g++默认采用动态链接,如果想要使用静态链接 -> 带上**-static**选项

image-20220405203827153


动态链接:
优点:省空间(磁盘的空间,内存的空间),bin体积小,加载速度快. 缺点:依赖动态库,程序可移植性较差.
静态链接:
优点:不依赖第三方库,程序的可移植性较高. 缺点:浪费空间.


验证:

image-20220405204016828

静态链接的文件大小>动态链接的文件的大小 , 这也证明了动态链接节省空间,而静态链接比较浪费空间


注:如果上面的内容报错了,就需要安装静态库 g++ 和gcc的选项、动静态库链接没有任何差别,可能需要下载静态库libc.a

安装C静态库 & C++静态库指令如下:

sudo yum install glibc-static sudo yum install libstdc++-static


Linux调试器-gdb使用

背景

gdb后面跟可执行程序的名字

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

image-20220405204450002


Centos中,默认生成的二级制程序是release版本的,没有调试信息

image-20220406201838069


对同一份代码分别生成其release版本和debug版本的可执行程序,可以看到,debug版本发布的可执行程序的大小比release版本发布的可执行程序的大小要大,其原因就是以debug版本发布的可执行程序当中包含了调试信息

image-20220405204523915


指令

我们先编写一段代码:

image-20220406202538818

退出gdb调试: ctrl + d 或 quit

关于显示代码:

  • list/l 行号:显示文件的源代码,接着上次的位置往下列,每次列10行.
  • list/l 函数名:列出某个函数的源代码.

image-20220406202837620

关于断点

  • break(b) 行号:在某一行设置断点 按行设置断点
  • info break :查看断点信息
  • delete 删除所有断点
  • delete n:删除序号为n的断点 ,使用断点对应的编号删除

image-20220406203532676

  • disable breakpoints:禁用断点 ,使用断点对应的编号禁用
  • enable breakpoints:启用断点 使用断点对应的编号启用

image-20220406203732685


break 函数名:在某个函数开头设置断点

image-20220406204407317

这个断点默认打在了函数的第一条代码处


程序运行时的操作:

  • r或run:运行程序 (相当于VS下的ctrl+F5)
  • n 或 next:单条执行,逐过程,相当于VS下的F10

image-20220406204052191

  • s或step:进入函数调用,逐语句,相当于VS下的F11

image-20220406204213370


finish vs continue vs until

  • finish:执行到当前函数返回,然后停下来等待命令

image-20220406204737327

  • continue(或c): 直接跳到下一个断点,如果后面没有断点,直接运行到程序结束
  • until X行号:跳至X行 跳转到指定行

image-20220406204906092


  • print§:打印表达式的值,通过表达式可以修改变量的值或者调用函数
  • p 变量:打印变量值.

image-20220406205520942

  • set var:修改变量的值

image-20220409201706875

  • display 变量名:跟踪查看一个变量,每次停下来都显示它的值,常显示 其中也可以查看变量的地址

image-20220406205330828

  • undisplay 序号:取消对先前设置的那些变量的跟踪

image-20220406205422440


  • breaktrace(或bt):查看各级函数调用及参数

    image-20220406205537641

  • info(i) locals:查看当前栈帧局部变量的值

image-20220406205612766

  • quit:退出gdb

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

背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make.可见,makefile都成为了一种在工程方面的编译方法.
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建.

关于依赖关系和依赖方法

在使用make/Makefile前我们首先应该理解各个文件之间的依赖关系以及它们之间的依赖方法

依赖关系: 文件A的变更会影响到文件B,那么就称文件B依赖于文件A

  • 例如,test.o文件是由test.c文件通过预处理、编译以及汇编之后生成的文件,所以test.c文件的改变会影响test.o,所以说test.o文件依赖于test.c文件

依赖方法: 如果文件B依赖于文件A,那么通过文件A得到文件B的方法,就是文件B依赖于文件A的依赖方法

  • 例如,test.o依赖于test.c,而test.c通过gcc -c test.c -o test.o指令就可以得到test.o, 那么test.o依赖于test.c的依赖方法就是gcc -c test.c -o test.o

多文件编译时:

我们可以直接使用gcc指令对多个源文件进行编译,进而生成可执行程序

image-20220409205708495


但进行多文件编译的时候一般不使用源文件直接生成可执行程序,而是先用每个源文件各自生成自己的二进制文件,然后再将这些二进制文件通过链接生成可执行程序

image-20220409210000856

  • 若是直接使用源文件生成可执行程序,那么其中一个源文件进行了修改,再生成可执行程序的时候就需要将所以的源文件重新进行编译链接
  • 而若是先用每个源文件各自生成自己的二进制文件,那么其中一个源文件进行了修改,就只需重新编译生成该源文件的二进制文件,然后再将这些二进制文件通过链接生成可执行程序即可

但是问题来了:如果源文件有很多,我们每次重新生成可执行程序时,所需输入的gcc指令的长度与个数也会随之增加这时我们就需要使用make和Makefile了,这将大大减少我们的工作量

image-20220409210359053

可以简写成:

@ 表示依赖关系中的目标文件 ∗ ∗ ∗ ∗ @ 表示依赖关系中的目标文件** ** @表示依赖关系中的目标文件^ 表示依赖关系中的依赖文件列表 $< 表示依赖关系中的第一个依赖文件

image-20221023115815680

注意:gcc/g++携带-c选项时,若不指定输出文件的文件名,则默认输出文件名为xxx.o,所以这里也可以不用指定输出文件名.


make原理

我们首先创建一个普通文件Makefile或者makefile,里面写我们的依赖关系和依赖方法

.PHONY:修饰对应符号,让符号变成伪目标(伪目标:总是可以执行的)也确实观察到如果没有对文件进行修改,执行make命令是没有效果的(底层是通过对比修改时间和可执行时间实现的),然而make clean 即便刚刚执行过,也可以随便执行

image-20220406213635612

mytest的生成依赖mytest.c ,前者依赖后者


如果多次执行编译:

编译一个源文件到可执行程序,如果再次编译,当系统检测到源文件没有做任何修改,不用重新编译,所以这就是只有第一次执行,不具备总是被执行的特点

image-20220406213513388

image-20220406213737149

写法:

目标文件:依赖文件
	依赖方法			

注意:上面的也可以写成这样:

  • $@:目标文件 $^:文件列表

image-20220406213956424

make:相当于VS中的生成解决方案 make clean :相当于VS中的清理解决方案

image-20220406214256713


例子2:

make是如何工作的,在默认的方式下,也就是我们只输入make命令之后发生了什么?

make会根据你编写的依赖关系,自动推导程序的执行

make会在当前目录下找名字叫Makefile或makefile的文件 然后它会默认找文件中的第一个目标文件(target),并把这个文件作为最终的目标文件
在如下代码中,mytest所依赖的mytest.o不存在或是被修改,就会执行对应的依赖方法,mytest的依赖关系中mytest.o又不存在,那么make会在Makefile文件中寻找目标为test.o文件的依赖关系,如果找到则再根据其依赖方法生成test.o文件,以此类推.(类似于堆栈的过程),总之,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件.

image-20220406215335203


项目清理

  • 工程是需要被清理的
  • 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行.即命令——“make clean”,以此来清除所有的目标文件,以便重编译.
  • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的.

注意:make执行的指令和makefile中的顺序有关!make扫描makefile文件的时候,默认只会形成一个目标依赖关系,一般是第一个

image-20220406220836202

make默认执行的是第一个

image-20220406220931903


回车与换行

首先明确两个概念

  • 回车\r:回到当前行的最开始 换行\n:列不变,新起一行

键盘上的Enter键实际上就等价于\n+\r


倒计时程序

\r是使光标回到本行行首,那么如果我们向显示器上写了一个数之后再让光标回到本行行首,然后再写一个数,就相当于将前面一个数字覆盖,

问:不使用’\n’进行换行怎么将缓冲区当中数据进行打印

使用fflush函数,刷新缓冲区,即将缓冲区当中的数据刷新当显示器当中.


image-20220409211415740

效果:

倒计时


在Linux下对下述两个代码的执行结果分析:

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

执行结果:先打印,然后休眠3s,然后程序结束

image-20220406221215801


#include <stdio.h>
#include <unistd.h> //为了使用sleep函数

int main()
{
     printf("hello makefile");
     sleep(3);
     return 0;
}

此时发现:是先休眠3s,然后打印 ,

image-20220406221330640

而它与上面代码的区别,仅仅只是打印时是否带了\n


问题: 这意味着sleep休眠先于printf执行吗?绝对不是!

解释:只是printf不带\n在向显示器打印时,数据不会立即刷新,而是会暂时保存用户C语言级别缓冲区中(文件系统详谈),显示器的刷新策略就是行刷新,即\n即进行刷新.带了\n会把我们的数据立即刷新出来


解决办法: 如果我们不想换行,又想刷新,可以调用库函数fflush,进行刷新显示

fflush(stdout)

image-20220406221656824


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

此时我们看到的结果就是先打印,然后再休眠3s

image-20220406221858202


Linux下的进度条小程序

【百度笔试题】进度条: 不进行换行,从左至右依次变长

  • 为进度条程序编写了makefile文件,这样直接make就可以直接生成可执行程序了
proc:proc.c
	gcc -o $@ $^
.PHONY:clean
clean:
	rm -rf proc

代码:

#include<stdio.h>
#include<string.h> //使用memset函数
#include<unistd.h> //使用usleep函数

#define NUM 100 //进度是100
int main()
{
    char bar[NUM+1];//多开一个空间放\0
    memset(bar,0,sizeof(bar));//初始化为0
    int i = 0;
    const char* label = "|/-\\"  //用于旋转,表示程序正在运行
    while(i<=100)
    {
        printf("[%-100s][%3d%%][%c]\r",bar,i,label[i%4]);
        fflush(stdout);//因为没有带\n,所以要及时刷新缓冲区
        usleep(50000);//休眠一段时间
        bar[i] ='='
        i++;
    }
    printf("\n");
    reutrn 0;
}

需要注意的细节:

  • 进度条从0 到100]:不换行 ->\r 且能刷新->fflush库函数.
  • 休眠函数usleep,需要引用头文件:#include<unistd.h> 单位是微秒
  • 因为字符串数组最后要放\0,所以数组开辟NUM+1个空间,最初都初始化为0,这样不需要在字符串末尾手动添加\0
  • [%-100s]打印进度条,这样就预留了100个字符的空间,并且是从左向右输出,即左对齐
    • image-20220406225321132
  • label旋转光标,表示当前进度条处于工作状态,每个字符都要轮流变化,所以下标变化为: i%4
  • 关于转义字符:
    • 注意\为特殊字符需要转义 \\代表的就是\
    • %也是特殊字符,也需要转义 %%代表的就是%

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZUXw6CxV-1675492842007)(https://mangoimage.oss-cn-guangzhou.aliyuncs.com/%E8%BF%9B%E5%BA%A6%E6%9D%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F.gif)]


关于git

安装yum install git , 先创建仓库,然后找到仓库的链接:

image-20220406205837878

在Linux下把仓库加入进去: git clone url 其中url就是上面箭头指的仓库的链接


第一招:git add

把代码放到仓库中, git add 文件名 将需要用 git 管理的文件告知 git

第二招:git commit

git commit -m "日志信息"

  • 提交改动到本地,最后的 . 表示当前目录 提交的时候应该注明提交日志, 描述改动的详细内容.

第三招:git push

同步到远端服务器上,需要填入用户名密码. 同步成功后, 刷新 gitee页面就能看到代码改动了

image-20220406210300320

如果中途出现下述情况:

image-20220408202931235

根据它的提示输入即可:

git config --global user.email "xx"  
git config --global user.name "xx"

配置免密码上传

git本地免密码和账号pull、push_CamilleZJ的博客-CSDN博客


其它指令:

git status 查看目前状态 git log查看日志信息

image-20220406210333402

用vim写其它语言的代码

注意:在Linux下要编写编程语言:

c语言的后缀: .c

  • 如果想要使用一些c99特性 ,如:for(int i = 0;…) ,在for循环内初始化, 则需要写成: gcc test.c -o test -std=c99

C++的后缀: .cc

python的后缀: .py

  • 需要在第一行选择版本:#!/usr/bin/python3

  • 如何执行?

    python test.py

    image-20220530204848027

Shell脚本的后缀: .sh


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

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

相关文章

2021美赛D题艺术家思路整理

问题整理 使用influence_data数据集或其部分创建音乐影响力的&#xff08;多个&#xff09;定向网络&#xff0c;其中影响者与关注者相连。开发捕捉此网络中“音乐影响的参数”。通过创建定向影响网络的子网络来探索音乐影响力的子集。描述这个子网络。你的“音乐影响”指标在…

((蓝桥杯 刷题全集)【备战(蓝桥杯)算法竞赛-第3天】( 从头开始重新做题,记录备战竞赛路上的每一道题 )距离蓝桥杯还有64天

&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6; 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&a…

PMP知识点1

根据PMBOK和参考书籍自己总结的一些不熟悉知识点&#xff0c;当做笔记放这复习。 1. 项目战略管理、组合管理、项目及管理、项目管理区别 战略管理项目组合管理项目集管理项目管理工作内容明确组织战略目标选择有利于实现战略目标的项目分析并利用各项目之间有机联系规范有序…

RAS《Research on Offense and Defense of DDos Based on Evolutionar Game Theory》

Read abstract and personal Summary of《Research on Offense and Defense of DDos Based on Evolutionar Game Theory》Ⅰ&#xff1a;Read abstract(阅读摘要)0&#xff1a;Proper noun interpretation&#xff08;专有名词解释&#xff09;1&#xff1a;The question raise…

windows 休眠后风扇狂转的解决方法

windows 休眠后风扇狂转的解决方法 问题描述&#xff1a; 在Windows电脑接入usb设备后进入休眠状态时&#xff0c;风扇立刻最大功率运行&#xff0c;在拔出usb/唤醒电脑后风扇会恢复正常。 解决方法&#xff1a; 使用powercfg 查询唤醒电脑的设备&#xff0c;然后移除此设备…

C语言基础(五)—— 数组、数组地址(步长+1)、字符串输入输出、随机数

1. 概述在程序设计中&#xff0c;为了方便处理数据把具有相同类型的若干变量按有序形式组织起来——称为数组。数组就是在内存中连续的相同类型的变量空间。同一个数组所有的成员都是相同的数据类型&#xff0c;同时所有的成员在内存中的地址是连续的。数组属于构造数据类型&am…

从Manifold到SNE再到t-SNE再回到Manifold

在介绍t-SNE之前&#xff0c;要从流形开始讲起。 流形Manifold 将流形引入到机器学习领域主要有两个用途&#xff1a; 改进原本欧式空间中的算法&#xff0c;使它能作用到流形上&#xff0c;直接或者间接地利用和流行的性质和构造。将流形映射到欧式空间中&#xff0c;令欧式…

软件测试面试:年后就拿到了5个offer,希望也能助你拿下满意的offer

求职&#xff0c;就像打仗&#xff0c;不仅是一场挑战自己的战斗&#xff0c;也是一场与用人单位的较量。 而求职者只有准备足够充分&#xff0c;才能在这场毫无硝烟的“战场”上取得胜利。 那么软件测试面试需要做哪些准备以及软件测试面试需要哪些技巧呢&#xff1f; 1、熟…

ThreadLocal 适合用在哪些实际生产的场景中?

在通常的业务开发中&#xff0c;ThreadLocal有两种典型的使用场景 场景1&#xff0c;ThreadLocal 用作保存每个线程独享的对象&#xff0c;为每个线程都创建一个副本&#xff0c;这样每个线程都可以修改自己所拥有的副本, 而不会影响其他线程的副本&#xff0c;确保线程安全 …

【内网安全-隧道搭建】内网穿透_Frp上线、测试

目录 Frp&#xff08;简易上线&#xff09; 1、简述&#xff1a; 2、工具&#xff1a; 3、使用&#xff1a; 1、准备&#xff1a; 2、服务端&#xff08;公网&#xff09;&#xff1a; 2、客户端&#xff08;内网&#xff09;&#xff1a; 3、测试方法&#xff1a; 4、…

【Linux】基础IO --- 软硬链接、acm时间、动静态库制作、动静态链接、动静态库加载原理…

我用执着烧死了所有的幼稚和任性&#xff0c;那片荒野慢慢长出了理智冷漠和清醒。 文章目录一、软硬链接1.软硬链接的区别&#xff08;是否具有独立的inode&#xff09;2.软硬链接的作用2.1 软链接作用&#xff08;建立快捷方式&#xff09;2.2 硬链接作用&#xff08;防止误删…

PLC信号处理系列之滤波器设计(MATLAB滤波器设计工具箱介绍)

在学习和应用滤波器解决工程问题之前,需要了解一定的信号处理相关基础知识,有关信号和系统的学习笔记可以参看下面的专栏: https://blog.csdn.net/m0_46143730/article/details/128788864https://blog.csdn.net/m0_46143730/article/details/128788864命令行窗口输入>&g…

排序模型进阶-FTRL

5.8 排序模型进阶-FTRL 学习目标 目标 无应用 无 5.8.1 问题 在实际项目的时候&#xff0c;经常会遇到训练数据非常大导致一些算法实际上不能操作的问题。比如在推荐行业中&#xff0c;因为DSP的请求数据量特别大&#xff0c;一个星期的数据往往有上百G&#xff0c;这种级别…

combit Report Server 28

combit Report Server 28 Added Microsoft SharePoint Online task action.Added support for PostgreSQL 15.Added support for Microsoft SQL Server 2022.Added new option to Microsoft Excel export template. Converting texts starting with “” into Excel formula.Im…

力扣:除自身以外数字的乘积(详解)

前言&#xff1a;本期是关于除自身以外数字的乘积的详解&#xff0c;内容包括四大模块&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读&#xff0c;今天你c了吗&#xff1f; 题目&#xff1a; 给你一个整数数组 nums&#xff0c;返回 数组 ans…

【javaEE】文件

目录 文件概念 文件路径 绝对路径 相对路径 文件类型 文本文件 二进制文件 Java中对文件的操作 对文件系统的操作 get相关方法 文件类型判断和创建 文件删除 文件目录的创建 文件重命名 对文件内容的操作 字符流(操作字符数据) 代码例子 删除文件 复制文件 …

算法刷题-求素数、数据流的中位数、不同的二叉搜索树

求素数、数据流的中位数、不同的二叉搜索树求素数数据流的中位数不同的二叉搜索树求素数 求1-100内的素数&#xff1a; public static void main(String[] args){for(int i0;i<100;i) {checkPrime(i);}}private static void checkPrime(int x){boolean isPrime true;if(x…

nodejs+vue大学生提问论坛系统vscode

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 前端技术&#xff1a;nodejsvueelementui,视图层其实质就是vue页面&#xff0c;通过编写vue页面从而展示在浏览器中&#xff0c;编写完成的vue页面…

Linux-时间和日期、磁盘信息和进程信息

为了方便通过远程终端维护服务器时&#xff0c;查看服务器上当前系统日期和时间 /磁盘空间占用情况/程序执行情况&#xff0c;本节基本都是查询命令时间和日期datecal磁盘和目录空间dfdu进程信息pstopkill1.时间和日期序号命令作用01cal查看一个月日历&#xff0c; -y选项可以查…

consul集群解决单注册弊端

consul集群前面我们用consul注册发现服务&#xff0c;这里的弊端显而易见&#xff0c;单机版如果挂掉&#xff0c;就无法正常使用。consul的集群是复制模式&#xff0c;每个节点的信息一致。当其中一个挂掉&#xff0c;其他正常运行。consul官网建议最好是3个节点&#xff0c;其…