目录

前言

Part1. Makefile

Part1.1. 基础语法

Part1.2. .PHONY

Part1.3. Make增量编译原理

Part1.4. 多文件递归编译示例

Part1.5. Makefile变量

Part1.6. 内置函数

Part1.7. 模式规则

Part1.8. 完整模板

Part2. C语言缓冲区原理

Part3. Git常用基础命令

Part4. cgdb调试器

Part5. 操作系统基础理解

Part5.1. 为什么需要内存

Part5.2. 数据流动

Part5.3. 操作系统四大核心功能

Part5.4. 内核态、用户态

Part5.5. 操作系统对数据的管理

Part6. 结语


前言

 对于开发工具的熟练使用和Linux操作系统的理解是非常重要的,来跟随小编的视角来看看吧。


let's go!!!!!!!!


Part1. Makefile

Part1.1. 基础语法

目标: 依赖
    命令
示例:
code: code.c
    gcc -o code code.c

逻辑:如果code.c修改过,则执行gcc编译,生成可执行文件code。


Part1.2. .PHONY

.PHONY: clean
clean:
    rm -f code

<1> .PHONY声明这是伪目标直接执行命令

<2> 执行清理:make clean


Part1.3. Make增量编译原理

make依靠文件修改时间戳判断要不要执行规则:

<1> 依赖文件更新时间 > 目标文件更新时间:执行编译。

<2> 依赖没有改动,多次make:输出nothing to be done,不会重复编译

<3> touch filename修改文件的三个时间戳可以欺骗make,强制触发编译


Part1.4. 多文件递归编译示例

A:A.o
    gcc A.o -o A

A.o:A.s
    gcc -c A.s -o A.o

A.s:A.c
    gcc -E A.c -o A.s

make自上而下扫描递归解析依赖一层层生成中间文件


Part1.5. Makefile变量

B = code
test:
    echo $(B)

取值语法:$(变量名)

自动化变量各个变量含义:


<1> $@ 当前规则的目标 


<2> $^ 全部依赖文件列表 


<3> $< 第一个依赖文件 


命令前加@:执行命令,不在终端打印这条shell命令。

例:@echo "linking $^ -> $@"

Part1.6. 内置函数

<1> wildcard:匹配一批文件

SRC := $(wildcard *.c)

Part1.7. 模式规则

%.o:%.c
    $(CC) $(CFLAGS) -c $< -o $@
//含义:任意.o,由同名.c编译生成。

Part1.8. 完整模板

BIN = app
SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o)
CC = gcc

$(BIN): $(OBJ)
    $(CC) -o $@ $^

%.o:%.c
    $(CC) -c $< 

.PHONY:clean
clean:
    rm -f $(BIN) $(OBJ)

Part2. C语言缓冲区原理

<1> 行缓冲:标准输出stdout是行缓冲,遇到\n换行才刷新缓冲区打印到屏幕
 

printf("hello");
sleep(3);
// 不会立刻打印,sleep结束才输出

printf("hello\n");
sleep(3);
// \n触发刷新,立刻打印

<2> fflush(stdout)强制刷新缓冲区,不需要换行,直接输出内容


<3> 格式化输出对齐

%xd:右对齐,占x字符宽度

%-xd:左对齐,占x字符宽度


Part3. Git常用基础命令

<1> git add .                  # 将所有修改加入暂存区

<2> git status                  # 查看仓库当前状态

<3> git commit -m "提交描述"         # 暂存区提交到本地仓库

<4> git push                   # 推送到远程仓库

<5> git clone 远程仓库地址        # 克隆远程仓库到本地

p.s. 暂存区:可以多次修改,多次add,统一一次commit、push。


Part4. cgdb调试器

gcc -g test.c -o test
cgdb test

GDB常用指令表


>>指令   功能 


q    退出gdb 


l     列出源代码 


l 行号   从指定行展示源码 


b 行号 设置断点 


b main      在main函数打断点 


r         运行程序 


c         继续运行,到下一个断点停下 


n 单步       跳过函数调用 


s 单步      进入函数内部 


bt         打印函数调用栈backtrace 


finish        跑完当前函数,返回调用处 


p 变量名      打印变量值 


info b       查看全部断点信息 


disable 断点编号   临时禁用断点 


enable 断点编号   启用断点 


until 行号       直接运行到指定行停下 


display 变量       持续监视变量,每次暂停自动打印 


undisplay 编号      取消监视 


info locals      打印当前函数所有局部变量 


watch 变量        变量被修改,程序自动停下 


set var x=y     gdb内部修改变量的值 


condition 断点号 条件    条件断点,满足条件才停


Part5. 操作系统基础理解

Part5.1. 为什么需要内存

  CPU只能直接读写内存,不能直接读写磁盘。 


  磁盘速度很慢,CPU运算速度极快内存作为中间高速缓存,用来匹配CPU和外设的速度差距。

程序运行过程:

<1> 可执行文件存放在磁盘。

<2> 运行程序,操作系统把程序加载到内存

<3> CPU从内存读取指令、数据执行


Part5.2. 数据流动

磁盘 → 内存 → CPU运算 → 内存 → 网卡(输出外设),发给对方

对方网卡接收,放入内存处理,最后写入磁盘保存


所有外设都不和CPU直接打交道,数据必经内存中转


Part5.3. 操作系统四大核心功能

<1> 进程管理

<2> 内存管理

<3> 文件管理

<4> 驱动设备管理


Part5.4. 内核态、用户态

应用程序跑在用户态,不能直接访问硬件、内存、设备

• 想要操作硬件,必须调用系统调用陷入内核态,由操作系统内核完成硬件操作。

高内聚低耦合上层应用只调用接口,底层驱动封装硬件细节


Part5.5. 操作系统对数据的管理

操作系统把各式各样来自硬件的数据,统一抽象成数据结构,完成增删查改


通过结构体描述管理对象(进程PCB、文件描述符等),保存元信息,完成管理


Part6. 结语

  这篇文章我们认识到了Linux开发工具和操作系统的相关知识,接下来,小编还会带来更多Linux相关的知识,敬请期待~

 最后,祝大家可以:春风得意马蹄疾,一日看尽长安花!

 最后的最后,要是觉得本文还可以的话,可以点点赞,关注小编一波,谢谢大家!~

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐