多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

linux基础:开发工具(上)

linux基础:开发工具(上) 文章目录Linux基础开发工具完全入门1 yum软件包管理器1.1 什么是软件包与yum1.2 yum常用操作CentOS1.2.1 查看软件包1.2.2 安装软件1.2.3 卸载软件1.2.4 软件源相关2 Vim编辑器2.1 vi与vim区别2.2 Vim三大核心模式2.3 基础打开保存退出2.4 命令模式高频命令2.4.1 切换插入模式2.4.2 光标移动2.4.3 删除2.4.4 复制粘贴2.4.5 撤销与反撤销2.4.6 查找2.5 Vim简单配置3 gcc/g编译器3.1 程序编译4个完整阶段3.2 分步编译示例3.2.1 预处理 -E3.2.2 编译生成汇编 -S3.2.3 汇编生成目标文件 -c3.2.4 链接生成可执行程序3.2.4 比较3.3 静态链接与动态链接3.4 gcc常用选项汇总4 Makefile与make工具4.1 为什么需要Makefile4.2 最简单Makefile示例4.3 多文件项目Makefile4.4 make的工作原理5 综合代码实操多文件C项目实战5.1 项目需求5.1.1 规范创建项目目录5.2 踩坑1编译缺少main函数 / 重复定义main错误命令1只编译code1.c code2.c不带main.c错误命令2如果code2.c里面不小心写了一个main函数✔正确编译命令带上全部源文件包含main.c5.3 踩坑2Linux命令小坑来自你的操作记录5.4 升级给多文件项目写Makefile5.5 扩展练习任务课后实操小结Linux基础开发工具完全入门面向Linux初学者讲解yum包管理器、vim编辑器、gcc/g编译器、Makefile自动化构建工具附带大量可直接复制的示例命令。1 yum软件包管理器1.1 什么是软件包与yum在Linux下安装软件有两种方式下载源代码手动编译步骤繁琐还要处理大量依赖使用软件包开发者提前编译好程序类似Windows的安装包存放在服务器。yum就是CentOS/RHEL系列的软件包管理器类比手机的应用商店自动帮我们下载软件、解决依赖、安装、卸载。补充Ubuntu/Debian使用apt作为包管理器功能逻辑一致只是命令不一样。软件包之间会存在依赖A软件运行需要B、C库如果没有包管理器要手动一个个装依赖yum会自动处理这套关系。国内镜像源国外服务器访问慢可以切换阿里云、清华镜像源提升下载速度。1.2 yum常用操作CentOS⚠️注意yum操作网络必须通畅部分操作需要管理员权限sudo不能同时执行多个yum安装任务。1.2.1 查看软件包# 列出所有包结合grep过滤想要找的软件yum list|greplrzsz包名字段解读x86_6464位CPU架构i686代表32位el7代表CentOS7系统最后一列代表这个软件来自哪个软件源1.2.2 安装软件# -y 自动确认安装不用手动输入ysudoyuminstall-ylrzsz必须加sudo安装要修改系统目录输出出现complete代表安装成功。1.2.3 卸载软件sudoyum remove-ylrzsz1.2.4 软件源相关CentOS源配置文件目录/etc/yum.repos.d/CentOS‑Base.repo基础官方源epel.repo扩展软件源很多第三方软件在这里安装扩展源sudoyuminstall-yepel-releaseUbuntu对应命令参考aptsearch lrzsz#搜索软件sudoaptinstall-ylrzsz#安装sudoaptremove-ylrzsz#卸载2 Vim编辑器2.1 vi与vim区别vim是vi的升级版本完全兼容vi指令增加语法高亮、可视化操作等新特性我们日常开发直接用vim。vim是多模式编辑器这是和记事本最大区别最核心掌握3种模式。2.2 Vim三大核心模式命令模式普通模式 Normal打开vim默认进入此模式控制光标、复制、删除、切换其他模式不能直接输入文字。插入模式Insert真正写代码、输入文字的模式。底行模式末行模式 Last‑line保存、退出、查找、设置行号输入冒号:进入。模式切换逻辑命令模式 → 插入模式按i/a/o插入模式 → 命令模式按ESC命令模式 → 底行模式按shift ;也就是:底行模式 → 命令模式按ESC2.3 基础打开保存退出#打开/新建文件 test.cvimtest.c底行模式常用指令:w #保存 :wq #保存并退出 :q! #强制退出不保存修改 :set nu #显示行号2.4 命令模式高频命令2.4.1 切换插入模式按键作用i光标当前位置开始输入a光标下一个字符位置输入o新开一行行首输入2.4.2 光标移动h 左 j 下 k 上 l 右 gg #跳到文档开头 G #跳到文档末尾 ^ #跳到当前行行首 $ #跳到当前行行尾 w #跳到下一个单词开头 b #跳到上一个单词开头 ctrlf 向下翻页 ctrlb 向上翻页 15G #直接跳转到第15行2.4.3 删除x #删除光标所在字符 dd #删除光标整行 5dd #从当前行开始向下删除5行2.4.4 复制粘贴yy #复制当前一整行 6yy #复制向下6行 p #粘贴缓冲区内容到光标下方 yw #复制一个单词2.4.5 撤销与反撤销u #撤销上一步操作 ctrl r #撤销的反向操作恢复被撤销的内容2.4.6 查找进入底行模式/hello #向下搜索hellon跳转到下一个匹配 ?hello #向上搜索hellon跳转到上一个匹配2.5 Vim简单配置vim分为系统全局配置和用户私有配置全局配置所有用户生效/etc/vimrc用户私有配置只对当前用户生效家目录下.vimrc配置自己的vim#回到家目录cd~#编辑私有配置文件没有就自动创建vim.vimrc写入下面配置syntax on 开启语法高亮 set nu 显示行号 set shiftwidth4 缩进4个空格 set expandtab tab转为空格保存退出重新打开vim配置立刻生效。高阶可以安装插件初学者先掌握原生配置。3 gcc/g编译器gcc编译C语言g编译Cgcc也可以编译Cg也能编译C。3.1 程序编译4个完整阶段C/C源代码到可执行程序一共4步完整流程预处理(-E)宏替换、去掉注释、展开头文件生成.i预处理文件编译(-S)语法检查翻译成汇编语言生成.s汇编文件汇编(-c)汇编转为机器二进制生成.o目标文件链接把多个目标文件 系统库合并生成最终可执行程序平时直接gcc test.c -o test会一次性走完4个步骤。3.2 分步编译示例源码hello.c#includestdio.hintmain(){printf(hello gcc\n);return0;}3.2.1 预处理-Egcc-Ehello.c-ohello.i执行结束得到hello.i里面是展开头文件、去掉注释后的C代码。3.2.2 编译生成汇编-Sgcc-Shello.i-ohello.s输出.s汇编代码文件可以看懂汇编指令。3.2.3 汇编生成目标文件-cgcc-chello.s-ohello.o.o是二进制目标文件机器可以识别但还不能直接运行。3.2.4 链接生成可执行程序gcc hello.o-ohello#运行程序./hello3.2.4 比较两套Makefile对比表对比项上方分步版本4阶段下方注释单命令版本编译命令拆分4条gcc-E预处理、-S汇编、-c编译、链接1条gcc -o myproc myproc.cgcc内部完成全部四阶段磁盘中间文件生成myproc.i、myproc.s、myproc.o不产生.i/.s/.o中间文件仅输出myproc依赖关系链式依赖myproc→o→s→i→c增量编译修改某一级只执行后续步骤直接依赖myproc:myproc.c源码改动就完整编译一次clean删除内容rm -f *.i *.s *.o myproc清理全部中间文件可执行文件rm -f myproc仅删除最终可执行程序运行结果最终生成的myproc可执行程序功能完全一致和左侧运行效果一模一样适用场景学习gcc四阶段完整流程观察每一步输出文件日常实际项目使用简洁高效两套完整代码片段分步版本上方myproc:myproc.o gcc myproc.o -o myproc myproc.o:myproc.s gcc -c myproc.s -o myproc.o myproc.s:myproc.i gcc -S myproc.i -o myproc.s myproc.i:myproc.c gcc -E myproc.c -o myproc.i .PHONY:clean clean: rm -f *.i *.s *.o myproc单命令版本下方注释myproc:myproc.c gcc -o myproc myproc.c .PHONY:clean clean: rm -f myproc核心结论最终可执行程序运行效果完全相同区别只在于是否把预处理、汇编、编译的中间产物输出到磁盘上。3.3 静态链接与动态链接程序调用库函数如printf函数实现不在我们写的代码中来自系统库链接阶段把库和我们的程序结合。动态库.so【gcc默认】程序运行的时候才加载库文件多个程序共用一份库磁盘占用小缺点运行环境必须存在这个库。查看程序依赖哪些动态库ldd hello静态库.a编译链接时直接把库代码拷贝进可执行程序。优点程序移植方便运行不依赖外部库缺点生成程序体积大多个程序会有多份库副本。编译使用静态链接加‑static参数gcc hello.c-ohello_static-staticCentOS默认没有C/C静态库需要安装sudoyuminstallglibc-static libstdc-static-y3.4 gcc常用选项汇总参数作用-E只做预处理-S编译到汇编代码-c汇编生成目标.o文件-o指定输出文件名-g加入调试信息供gdb调试使用-static静态链接-Wall开启全部警告写代码建议带上-O0 ~ O3编译优化级别O0无优化O3最高优化4 Makefile与make工具4.1 为什么需要Makefile如果项目有几十个.c文件每次手动敲一大段gcc编译命令非常麻烦。make是一个命令工具Makefile写编译规则的文本文件二者配合实现自动化构建。只需要执行make一条命令自动完成编译还会智能判断哪些文件修改了只重新编译改动的文件提升编译效率。4.2 最简单Makefile示例项目main.c生成可执行文件myproc新建名字叫Makefile的文件大小写敏感M大写#目标:依赖文件 myproc:main.c gcc -o myproc main.c #伪目标清理编译产物 .PHONY:clean clean: rm -f myproc⚠️注意gcc前面必须是Tab缩进不能用空格使用make#执行编译生成myprocmakeclean#执行清理删除生成的可执行程序解读myproc是最终目标依赖main.c如果main.c比myproc新就执行后面gcc命令重新编译.PHONY:clean声明clean是伪目标不要去磁盘找叫clean的文件永远执行clean下面的命令伪目标不会被make自动执行需要手动make clean调用。.PHONY 是直接忽略时间戳时间轴判断逻辑而直接执行下方黄色发亮字体有解释4.3 多文件项目Makefile假设项目有main.c test.c两个源码需要分别编译成.o再链接。#变量定义 CCgcc OBJmain.o test.o BINapp #最终可执行程序依赖所有目标文件 $(BIN):$(OBJ) $(CC) -o $ $^ #通用规则所有.c生成同名.o %.o:%.c $(CC) -c $ -o $ .PHONY:clean clean: rm -f $(OBJ) $(BIN)自动变量说明Makefile内置$代表冒号左边的目标$^代表冒号右边全部依赖$代表第一个依赖文件执行makemakeclean4.4 make的工作原理执行make在当前目录寻找Makefile/makefile找到文件读取第一个目标作为最终要生成的产物判断目标文件是否存在或者依赖文件的修改时间比目标更新如果需要更新执行对应命令如果依赖本身不存在递归寻找规则生成依赖如果中途找不到依赖文件直接报错终止。make依靠目标文件与依赖文件的Modify修改时间(mtime)判断是否已经make过当目标产物存在且所有依赖源码的修改时间都早于目标产物的修改时间就代表源码自上次编译后没有改动输出xxx is up to date不再执行编译若源码被修改其mtime更新晚于产物则触发重新编译make只比对mtime不比对文件实际内容。这里touch可重新更改时间touch文件就行。优势只编译修改过的文件大型项目节省大量编译时间。5 综合代码实操多文件C项目实战基于你终端真实操作日志模拟一个多文件C语言项目体验项目目录规划、gcc编译报错排错、多文件编译理解链接阶段常见错误。5.1 项目需求我们写一个多文件小项目code1.c/code1.h实现函数fun1()code2.c/code2.h实现函数fun2()main.c程序唯一入口main()调用fun1()、fun2()5.1.1 规范创建项目目录实操命令可以直接复制运行#回到家目录cd~# 创建标准项目目录结构project/src存放源代码mkdir-pproject/src# 切换进入源码目录cdproject/src创建各个源码文件内容code1.h#pragmaoncevoidfun1();code1.c#includecode1.h#includestdio.hvoidfun1(){printf(hi fun1());}code2.h#pragmaoncevoidfun2();code2.c#includecode2.h#includestdio.hvoidfun2(){printf(hi fun2());}main.c唯一main函数程序入口#includecode1.h#includecode2.hintmain(){fun1();fun2();return0;}目录结构执行tree查看tree输出. ├── code1.c ├── code1.h ├── code2.c ├── code2.h └── main.c 0 directories, 5 files5.2 踩坑1编译缺少main函数 / 重复定义main错误命令1只编译code1.c code2.c不带main.cgcc code1.c code2.c-ocode报错/usr/bin/ld: undefined reference to main collect2: error: ld returned 1 exit status✅错误原因链接阶段找不到程序入口main函数Linux C程序必须要有且仅有1个main作为入口。code1.c code2.c只是功能模块没有main。错误命令2如果code2.c里面不小心写了一个main函数gcc code1.c code2.c-ocode报错multiple definition of main; multiple definition of fun1✅错误原因重复定义整个项目只能存在一份main函数同一个全局函数不能多处实现。业务功能写在code1/code2main只允许写在main.c。✔正确编译命令带上全部源文件包含main.cgcc main.c code1.c code2.c-ocode#运行程序./code输出结果hi fun1()hi fun2()5.3 踩坑2Linux命令小坑来自你的操作记录touch project1touch创建普通文件不是文件夹不能cd进去。touchproject1cdproject1# 报错 Not a directory✔创建文件夹用mkdirmkdir -p project1/src递归创建多级目录。相对路径问题# 当前在 ~/project/libcdsrc bash: cd: src: No suchfileor directory当前在lib文件夹src是lib的同级不是子目录。进入同级srccd ../src../代表上级目录./代表当前目录5.4 升级给多文件项目写Makefile在~/project/src下面创建Makefile# 指定编译器 CC gcc # 获取当前目录下所有的.c源文件 SRC : $(wildcard *.c) # 将所有.c文件名替换为.o目标文件 OBJ : $(SRC:.c.o) # 最终生成的可执行程序名 BIN : code # 最终目标可执行文件依赖所有.o目标文件 $(BIN): $(OBJ) # $ 代表目标文件($(BIN))$^代表全部依赖文件($(OBJ)) $(CC) -o $ $^ # 通用模式规则所有 .c 文件编译生成对应的 .o 文件 %.o: %.c # $ 代表第一个依赖文件即对应的.c源码 $(CC) -c $ # 声明clean为伪目标不生成磁盘文件总是执行 .PHONY: clean # 清理规则删除所有目标文件和可执行程序 clean: rm -f $(OBJ) $(BIN)使用Makefile编译项目#一键编译全部文件make#运行./code#清理编译产物makeclean5.5 扩展练习任务课后实操修改fun1、fun2里面printf内容重新执行make观察make只会重新编译改动的.c文件使用gcc分步编译把每个.c编译为.o目标文件再手动链接故意在code2.c写多一个main复现multiple definition链接报错理解链接期错误故意删掉main.c中的main函数复现undefined reference to main。小结yum/apt负责软件安装卸载解决软件依赖切换国内镜像加速下载vim核心掌握三种模式记住常用移动、删除、复制命令可以配置.vimrc美化编辑器gcc编译四阶段预处理→编译→汇编→链接区分动态链接、静态链接调试编译必须加‑gMakefile定义编译规则make命令自动化编译伪目标.PHONY用来做项目清理学会内置自动变量简化脚本。多文件项目实操重点整个C项目有且只能有1个main()函数放在main.cgcc编译需要把所有用到的.c全部参与编译链接链接报错大多是缺少函数实现、重复定义、缺少main入口mkdir创建目录touch创建普通文件../代表上级目录。
返回列表