2020-12-05

shell 基本指令

echo <> 将 <> 中的内容输出到屏幕
$? 上一次命令执行的结果

man 帮助的使用:

man command
man 1 command 和上面的一样
man 2 系统调用
man 3 库函数
PRINTF(3) 表示man 3 可以查看这个函数

程序编译的流程

1.预处理
gcc -E hello.c -o hello.i
2. 编译 将预处理后的文件翻译为汇编文件
gcc -S hello.i -o hello.s
3. 汇编 将汇编语言翻译为机器语言
gcc -c hello.s -o hello.o
4. 将目标文件和运行是文件或者函数库链接形成可执行文件
gcc hello.o -o hello

  1. 编译的基本单位是什么?
    编译的基本单位是源程序

nm 二进制文件名
可以查看二进制文件中的符号表
什么是符号?
一个二进制符号表中包含 函数的名字 全局变量的名字 静态局部变量的名字
T 表示 在此文件中定义了该函数
U表示 在此文件中没有定义该函数

链接

链接分为动态链接和静态链接

静态链接就是将各个二进制文件(.o文件) 链接在一起,发生在生成可执行文件的时候
nm t_add.o
00000000 T t_add
0000000d T t_sub

nm t_mul.o
0000000c T t_div
00000000 T t_mul
这些地址是相对地址,相对于自己模块的地址

nm a.out
生成的符号表的地址是绝对地址

file main.o
他的属性有 relocatable 表示可以重定位
file a.out
他的属性是 可执行的

静态库的制作,使用

根据链接方式的不同分为静态库和动态库(共享库)

命名规则:

lib库名.a 静态库的名字
lib库名.so 动态库的名字

  1. 将需要打包到静态库的源文件编译编译成为目标文件
    gcc -c t_add.c t_mul.c
    之后会生成t_add.o t_mul.o
  2. 将第一步中生成的目标文件打包到静态库文件中
    ar -r libp_math.a *.o
    会生成 libp_math.a
    libp_math.a 这是静态库文件 静态库名字是 p_math
  3. 用静态库链接生成可执行文件
    gcc -c main.c -o main.o
    gcc main.o -L. -lp_math
    注意: 其中
    -L路径 告诉连接器到指定的路径下找需要的静态库文件
    -l库名 指定使用到的静态库的库名

静态库在链接时,用到的才会被连接到可执行文件中,不用的不会链接到可执行文件中。

三 环境变量

什么是环境变量

进程是程序运行的实例。
程序执行过程中(进程中),需要访问计算机的资源,每台计算机资源存放的位置和配置都不同。

每个进程都有自己的环境变量列表。
所有的应用进程构成了一棵树。进程树
pstree(1) 查看系统的进程树
进程间的关系 父子关系 兄弟关系
环境变量可以被子进程继承。

以bash 进程为例,讲解环境变量的操作。

  1. 查看bash进程的环境列表
    env(1)
    环境变量的格式
    name=val 注意: =两边不允许出现空格
    $name 可以取出环境变量的名字
    echo $name
    grep 字符串 文件名

修改环境变量的值
name=value 如果环境变量name存在,使用value得知替换name环境变量原来的值。
如果环境变量name不存在,将创建一个自定义变量。

环境变量和自定义变量
环境变量可以被子进程继承的,但是自定义变量不可以被子进程继承。

如果将自定义变量转换为环境变量?
export name
删除环境变量
unset name

exit 退出当前子进程

PS1 自定义变量
这个变量表示bash 进程的提示符
如果希望bash 进程前面显示的仅仅是当前文件夹,则修改PS1
PS1="\W$"
bash 本身就是一个进程,当bash这个进程启动以后,会执行一个bash 脚本文件 ~/.bashrc
用户可以在这个脚本文件中设置bash 进程的环境变量。

PATH 是一个环境变量
echo $PATH
/home/book/bin:/home/book/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/work/tools/gcc-3.4.5-glibc-2.3.6/bin:/snap/bin

对PATH 环境变量的注释:
1.冒号会分割多个路径
2. bash 输入一条指令的时候,会在这些路径下找可执行程序,如果能够找到,则执行这个程序,如果找不到,会报错。

修改PATH 环境变量:
如果想要在a.out 目录下直接执行 a.out 程序
例如 原来 ./a.out 现在 a.out
则 有如下的修改方法: 在环境变量PATH 中加入当前路径即可

PATH= $PATH:.

仅仅是在当前bash 下可以使用 a.out
如果想要在任意的路径下使用a.out
则需要修改 vim .bashrc
将 PATH=$PATH:. 加入 .bashrc 文件即可。

动态库的制作和使用

lib库名.so

  1. 将所有要打包的动态库的源文件编译为目标文件(与位置无关的目标文件?)
    gcc -c -fPIC t*.c 将所有t 开头 的.c 文件打包生成与位置无关的.o 文件
  2. 将第一步中生成的目标文件打包成为动态库
    gcc -shared -o libt_math.so *.o
  3. 使用动态库链接生成可执行文件
    gcc main.c -L. -lt_math
    注意: 这一步使用的是静态连接器,当识别为动态库时,只是check 一下其中有没有需要的函数 没有则会报错。
    然后执行./a.out 会有error :
    显示 libt_math.so cant open 找不到这个文件
    产生这个error 的原因是动态连接器到不到文件

处理方法

ldd a.out : 查看 a.out 在执行时,需要依赖那些动态库
普通的c 程序依赖的库如下
linux-vdso.so.1 => (0x00007ffd769f4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fee7137b000)
/lib64/ld-linux-x86-64.so.2 (0x00007fee71745000)
libt_math.so =》 not found
表示动态链接器无法找到这个动态库

告知动态连接器这个库文件的位置:
1.export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
冒号分隔符分隔多条路径
2. 动态连接器默认的搜索路径是 /lib 或者是 /usr/lib

#include <> " " 的区别

<> 去系统的指定路径下寻找,找不到会报错
“ ” 在当前路径下找,找不到去系统指定路径下找,再找不到,报错

系统指定路径是什么?

gcc -E hello.c -o hello.i -v
显示预处理的过程

#include “…” search starts here:
#include <…> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.

  1. gcc -E hello.c -Ilib -o hello.i -v
    -I路径 将路径添加到文件包含时,系统指定的路径中。
  2. 将 头文件移动到 系统的搜索路径下 比如 /usr/include 或者/usr/local/include

链接过程进一步分析

  1. gcc hello.o -o hello -v 显示链接的过程
    会有很多的.o 文件,这些文件是函数在运行时的链接文件
  2. nm /usr/lib/gcc/x86_64-linux-gnu/5/…/…/…/x86_64-linux-gnu/crt1.o 查看这个.o 函数的符号表,可以看到 main 函数也是一个需要链接的 .o 函数,而T_start 才是一个函数执行时真正的入口地址

其他的.o 文件也都是系统提供的,被称为运行时文件(运行时环境)

nm /usr/lib/gcc/x86_64-linux-gnu/5/…/…/…/x86_64-linux-gnu/crt1.o
0000000000000000 D __data_start 0000000000000000 W data_start
0000000000000000 R _IO_stdin_used
U __libc_csu_fini
U __libc_csu_init
U __libc_start_main
U main
0000000000000000 T _start

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值