首页 > 数据库技术 > 详细

03-Linux命令基础-第03天(makefile、静态库、动态库、gdb调试工具)

时间:2019-04-26 18:54:34      阅读:195      评论:0      收藏:0      [点我收藏+]

01- 复习

 

tar tvf xxx 查看压缩包内容

 

技术分享图片

 

区分前后台: 是否能和用户交互

 

Vmware选桥接模式 会给系统虚拟一个和外部相同网段的ip

 

技术分享图片

 

 技术分享图片

 

 技术分享图片

 

 技术分享图片

 

 

 

02- vim扩展操作

因为不是做嵌入式开发的 所以这些东西不是特别重要

简单过一遍

 

技术分享图片

 

缩进:

 

右缩进 两个>>

左缩进 两个<<

 

4行右缩进  4>>

 

 

 

想把m变量改成n:

技术分享图片

 

 

15,17s /f/m/g

 

 

 

r替换当前字符

R 替换当前光标后的字符

 

 

 

[d 查看宏:

 

 技术分享图片

(这个宏是在上面定义的)

 

 

在程序中使用man page:

光标移动到函数身上按K 

示例:

技术分享图片

 

 

这里应该按 3K 查看函数手册页面

 

 

 

在vim里执行shell命令:

 

!ls(在末行模式下)

 

:!ls

 

 

:!cp

 

 

:!man

例如: :!man 2 read

 

 

 

分屏操作:

 

比如我经常在文档开头和文档结尾处编辑 这个时候可以借助分屏

 

ctrl+ww

 

:sp 分屏 (末行模式)

ctrl +w  w

 

 

:vsp 竖分屏

 

 

ctrl +w  hjkl 选择性的切换分屏

 

 

:wqall 将所有窗口一次性退出

 

分屏打开另外的文件

:vsp aaa.h

 

 

 

 技术分享图片

配置文件:

/etc/vim/vimrc

这个配置文件配置的是整个操作系统 对所有用户生效

 

 

~/.vimrc 默认是一个隐藏文件

技术分享图片

… …(如果想设置 自己百度)

(把vim打造成很强的ide)

 

 

03- gcc编译工具和工具链

技术分享图片

-I 指定头文件的位置:

 

hello.c

hello.h

 

mv hello.h ..

 

gcc hello.c –I ..

这样就能编译成功了

 

 

 

-c只编译 不进行链接

 技术分享图片

 

最耗时的操作是编译

因为编译要一行一行的去检查语法错误

 

预处理和汇编都不会检查错误

汇编只是简单的翻译

 

 

-g 先不讲 后面讲gdb开发再讲

 

-On 驱动开发才经常会用

 

技术分享图片

翻译成汇编的时候会直接删除这段代码

 

 

技术分享图片

 

 

这段代码指定优化会把中间的没用步骤优化掉

 

 

-Wall ( warning all 提示完整的警告信息)

例如:

代码中加了一个不会被使用的变量

 

技术分享图片

 

 

然后gcc hello.c –Wall

技术分享图片

 

 

 

技术分享图片

 

gcc本来就是一个工具链

 

GNU编译工具集合器

 

技术分享图片

 

 

 

技术分享图片

 

技术分享图片

 

符号: 全局变量和函数

 

技术分享图片

 

gcc hello.c

 

然后可以nm a.out

 

技术分享图片

 

技术分享图片

描述符T(表示在内存TEXT段内部已经实现的)

 

 

技术分享图片

D 是在data段

 

 

技术分享图片

U未实现

 

gcc –c hello.c

得到目标文件 hello.o

 

nm hello.o

 

技术分享图片

 

目标文件比可执行文件 符号少很多

 

也就是说在最后一步链接的时候 会像目标文件里链入很多符号表

 

技术分享图片

printf函数就未实现

 

printf函数是一个库函数

 

虽然有include <stdio.h>

 

但是 printf是在libc库里 libc库是一个动态库

 

动态库是在程序的运行期间链接

 

只有 ./a.out的时候 才会把printf跟程序链接到一块

 

 

 

nm 一下之前那个可执行文件 还是U 未实现

技术分享图片

 

 

技术分享图片

这个主要用于反汇编

 

 技术分享图片

 

例如:

objdump –dS hello.o

技术分享图片

 

技术分享图片

 

callq 调用函数

 

 

除了可以反汇编a.o

也可以反汇编a.out

 

技术分享图片

ranlib 一般不用 太麻烦了

 

elf

 

 

file hello.o:

 

技术分享图片

 

LSB 小尾端法存储 低地址存在低字节 高地址存在高字节

技术分享图片

可重定位的

 

所以目标文件也叫 可重定位文件

 

file a.out:

技术分享图片

 

 

可执行文件

 

 

目标文件和可执行文件都是二进制文件

即使是二进制文件也有属于它的存储格式 即elf格式

 

readelf命令就是读取这种格式的工具

 

readelf –a hello.o

 

技术分享图片

技术分享图片

 

大概包括三部分:

 

elf头 包括节头

 

技术分享图片

技术分享图片

 

重定位节:

 

技术分享图片

 

符号表:

技术分享图片

 

 

可执行程序装载到内存的原理

 

64bit系统内存太大了, 从32bit的示例

 

0~3G 是用户区

3G~4G 是kernal区

 

 

text:代码段 存放代码 int main void 什么的ascii码都翻译成二进制

 

data: 数据段 常量 字符串

 

bss: 未初始化的全局变量和未初始化的static变量

 

栈和堆重合的时候就内存溢出了

 

技术分享图片

 

 技术分享图片

 

 

ro权限 (read only

 

rw权限

 

 

text段和data段之间有一个rodata

 

 

技术分享图片

 

04-静态库

 

技术分享图片

 

头文件只包含函数声明

 

真正的函数是在库文件里面

 

技术分享图片

 

 

静态库libmytest.a

 

技术分享图片

 

假如另外的b.out c.out d.out 每个都要添加一份

 

技术分享图片

会复制一份作为程序代码的一部分

如果一个3m的静态库 有100个程序使用 内存中就会多出来300MB

 

 

技术分享图片

 

技术分享图片

 

 

main.c

 

add.c

mul.c

sub.c

可以制作成静态库函数

 

技术分享图片

技术分享图片

 

技术分享图片

 

 技术分享图片

 

技术分享图片

 

 

gcc main.c –o app –L ./ -l mymath –I ./

-L 指定库位置

-l 指定库的名字

-I 指定头文件位置

 

技术分享图片

 

 

04- 动态库

 

动态链接器

 

技术分享图片

 

当运行a.out的时候会使用动态连接器加载

 

运行b.out c.out d.out的时候 都会去加载这个stack和heap之间的动态库

 

技术分享图片

 

共享代码(不共享数据)的意思是 如果a.out把共享库里一个变量改变了 b.out也会承受这个修改… … 所以一般动态数据库不会共享数据!  (了解)

 

技术分享图片

 

技术分享图片

 

 

动态链接器 链接器 除了名字像没任何关系

 

链接器工作在编译阶段

gcc 生成app的时候会用连接器

 

动态链接器是在程序运行的时候装载

技术分享图片

 

生成可执行文件 然后运行 报错了

 

问题出在动态链接器不知道在哪找库

 

指定的方法:

技术分享图片

 

 

 

01- 中午复习_动态库

 

符号: 全局变量 全局函数

 

函数名 变量名 都是地址值

 

 技术分享图片

 

静态库:编译时

 

动态库:运行时

 

 技术分享图片

 

 

Ldd 查看可执行文件执行期间要加载哪些库

技术分享图片

 

 

这个东西就是动态链接器

技术分享图片

 

动态链接器本质也是一个动态库

 

.bashrc

 

类似于vimrc 每次打开终端都会读取这个配置文件

 

export LD_LIBRARY_PATH = ./   (配置动态链接库目录)

 

这样配置完每次打开终端都生效

 

 

动态库的命名:

技术分享图片

 

 

Realname: libc-2.19.so

 

这是一个软连接

 

Linkername : libc.so

 

 

Soname:

libc.so.6

6是大版本号

 

技术分享图片

 

 

技术分享图片

 

 

Soname的作用 :

 

技术分享图片

当前是libc-2.19.so

 

官方进行更新后

可能变成libc-2.20.so

 

 

随着版本更新 版本更新的记录不想让用户知道

防止用户引起恐慌..

所以使用soname

 

Soname存在意义就是隐藏内部实现细节

 

 技术分享图片

 

技术分享图片

静态库)

 

 

nm app:

技术分享图片

Printf mul都没实现

 

nm app1:

技术分享图片

Mul是已经实现的

 

 

 

07    gdb调试

 

 技术分享图片

 

 

技术分享图片

 

 

编译的时候 加 -g 参数

 技术分享图片

 

gdb app

 

技术分享图片

 

 

 

list 1 从第一行开始往后列

 

b 20

 

info b

 

技术分享图片

 

 

条件断点

技术分享图片

 

 

disable

技术分享图片

 

 

run 

技术分享图片

 

 

p I (print i

技术分享图片

 

 

S (step 单步向下执行

技术分享图片

 

 

display 

技术分享图片

 

 

n next

s step

当定义到一个函数的时候就有区别了

Next会跳过函数 step会跳入函数

 

ptype

技术分享图片

 

 

 

栈帧:

函数调用会在栈上进行存储

 

栈帧:保存局部变量和临时值

 

局部变量

临时值:

 

例:

技术分享图片

函数执行一半执行到mul函数 mul函数执行完了 要回到刚才的位置 所以刚才的位置的地址要保存一下 这个就是临时值

 

函数只要调用就产生栈帧

 

当main函数开始调用时 产生一片栈帧,

执行第一个内部的函数时候 在main下面产生一个栈帧

 

技术分享图片

当这个函数执行完毕后 这个栈帧消失

下一个内部函数栈帧生成在main栈帧下面…

 

 

技术分享图片

 

 

Bt

技术分享图片

发现两块栈帧

 

 

Info locals 查看当前栈帧的值

技术分享图片

 

 

段错误 直接Run

直接运行 然后停止在段错误的代码

 

08-makefile_x264

技术分享图片

 

Vi makefile

Vi Makefile

 

只能起这两个名字 才能使用默认的make命令去执行它

 

 

Makefile里都是一组一组的规则

 

 

规则包含三部分:

 

目标 : 生成目标需要的依赖

      如何生成目标

 

 

App: add.c sub.c mul.c main.c

     gcc add.c sub.c mul.c main.c

 

 

Make

 

技术分享图片

 

比如一个main.c有三个依赖,我只修改了一个依赖 我不希望每次都把所有.c都编译

这时候可以使用makefile

 

Makefile:

app: add.o sub.o mul.o main.o

     gcc add.o sub.o mul.o main.o -o app

add .o: add.c

     gcc -c add.c -o add.o

sub.o: sub.c

     gcc -c sub.c -o sub.o

mul.o: mul.c

     gcc -c mul.c -o mul.o

main.o:main.c

     gcc -c main.c -o main.o

 

 

然后我修改一个依赖

然后make , makefile会智能地只编译修改过的c文件

 

技术分享图片

技术分享图片

 

 

技术分享图片

 

 技术分享图片

.c(依赖)的修改时间比.o(目标)的修改时间晚, 所以需要重新生成目标

 

重新生成目标后add.o 的修改时间比app晚 所以需要重新生成目标

 

 

 

 

 

技术分享图片

 

 技术分享图片

 

 

技术分享图片

然后 make clean

 技术分享图片

 

 

 

-n 命令 查看执行make的话会做什么

 

make clean -n

 

技术分享图片

 

 

 

 

自动变量

技术分享图片

$@

 

$<

 

$^

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

 

 

技术分享图片

技术分享图片

(当$< 和$^ 都可以用的时候 建议用$<    因为后边会用它写模式规则)

 

 

 

技术分享图片

 

 

技术分享图片

第三个参数中包含第一个参数的部分替换为第二个参数

 

 

补充小知识:

%也是通配符

 

 

技术分享图片

 

技术分享图片

 

 

 

技术分享图片

 

技术分享图片

 

 

技术分享图片

现在就可以 向里面加.c 调整.h 而不用调整makefile了

 

 

 

 

技术分享图片

 

make clean 因为clean得依赖修改时间没有变化(没有依赖)

           所以会提示没有更新

 

解决方法:

.PHONY: clean

把clean 声明称尾目标 不管依赖条件满不满足都会去执行它

 

技术分享图片

 

 

小技巧 rm前面加-

-rm

意思是无论是否出错 后序命令都正常执行

 

因为有时候rm遇到无法删除得文件报错了 后面就都删除不了了

 

 

当文件不叫makefile得时候要用-f指定

 

make –f xxxx

 

 

 

make默认第一条规则是终极目标 如果第一个是完成了 就不往下执行了

如果想随便掉换行需要指定终极目标

ALL:app 放在最开始

 

 

模式规则:

技术分享图片

 

 

静态模式规则:

技术分享图片

 

 

最终版:

 技术分享图片

 

 

通常的项目目录

技术分享图片

 

03-Linux命令基础-第03天(makefile、静态库、动态库、gdb调试工具)

原文:https://www.cnblogs.com/eret9616/p/10775962.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!