gcc 编译、链接原理

!!!https://www.coder.work/article/183076

  1. 使用 ld-linux.so.* 作为解释器,是写在二进制文件中的,比如上面编译好的 demo 中。另外的,2) 其它库的查找和加载,则是 ld-linux.so.* 完成的。
    ldd <可执行文件名> 查看可执行文件链接了哪些 系统动态链接库
    strip <可执行文件名> 去除符号表可以给可执行文件瘦身
    ldconfig 命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件.缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表.

ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令.
vi /etc/ld.so.conf

首先ldd不是一个可执行程序,而只是一个shell脚本.
ldd显示可执行模块的dependency的工作原理,其实质是通过ld-linux.so(elf动态库的装载器)来实现的。我们知道,ld-linux.so模块会先于executable模块程序工作,并获得控制权,因此当上述的那些环境变量被设置时,ld-linux.so选择了显示可执行模块的dependency。
实际上可以直接执行ld-linux.so模块,如:/lib/ld-linux.so.2 --list program(这相当于ldd program)ldd命令使用方法(摘自ldd --help)
**ld
http://notes.maxwi.com/2017/04/13/linux-dynamic-lib-ldconfig/
在这里插入图片描述
在这里插入图片描述

Linux下有两个很好用的实用程序:
ldd:用于查看共享库依赖信息
ldconfig:用于配置动态链接器的运行时绑定
还有两个Linux下非常重要的动态链接器/载入器:
ld.so
ld-linux.so*
以及GNU的链接器:
ld:这个就是将一堆的目标文件通过符号表链接成最终的程序,可以参考上面推荐的另一篇文章**
https://www.cnblogs.com/zhouhbing/p/5109750.html
在linux中, strip也有脱衣服的含义, 具体就是从特定文件中剥掉一些符号信息和调试信息。
[taoge@localhost learn_strip]$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

在cmake_cache中查看链接信息。
./cmake_cache/source/util/CMakeFiles/xx_util.dir/link.txt
三大目录:
build(mkapp.h)、cmake(各种xx.cmake,自定义构建流程)、gradle()
https://tech.meituan.com/2014/08/18/gradle-practice.html
gradle maven 和 cmake 区别
修改gcc specs大全: gcc -dumpspecs
https://blog.csdn.net/Hodors/article/details/107339488http://www.360doc.com/content/16/0928/14/7991404_594388737.shtml
https://firmianay.gitbooks.io/ctf-all-in-one/content/doc/4.3_gcc_arg.html
刘超的通俗云计算
https://www.cnblogs.com/popsuper1982/
su是申请切换root用户,需要申请root用户密码。有些Linux发行版,例如ubuntu,默认没有设置root用户的密码,所以需要我们先使用sudo passwd root设置root用户密码。

而sudo是当前用户暂时申请root权限,所以输入的不是root用户密码,而是当前用户的密码。sudo是用户申请管理员权限执行一个操作,而此处的操作就是变成管理员。

编译链接最终会生成各种目标文件:
可重定位目标文件(.o、.a)
可执行文件
共享目标文件(.so)
核心转储文件(core dump)
// 设计模式 top 5
单例。写过消息队列、线程池、日志对象、配置文件对象。
标准库中用到的设计模式有iterator,adapter.stack,queue,priority_queue用到了adapter模式,把底层容器的接口转换为数据结构的接口。
GUI->组合模式
数据结构遍历->迭代器
消息机制->观察者模式
资源管理->单例模式
singleton,最经常干的事是把相关的全局变量包在一起
factory,业务流程和测试流程构造不同的实例
最常用的
单例
观察者
责任链

次一点的
工厂
装饰器
适配器等

、、、、、、、、、、、、、、、
详解 GCC 编译、构建原理
编译
目标文件(.o)
静态库(.a)
共享库(.so)
动态链接
动态加载
链接
ld:GNU 的链接器,将一堆目标文件通过符号表链接成最终的可执行文件
ldconfig:在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出动态链接库(lib*.so*),进而创建出动态加载程序(ld.so)所需的链接和缓存文件。缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表.
更新缓存使新添加的库生效,当然系统启动时会自动运行ldconfig。
ld.so:其他库的查找和加载,由ld.so完成。
运行
ld-linux.so:作为解释器,写在elf文件中,ld-linux.so 先于 main 函数工作,查找主程序所依赖的共享库。实际上可以直接执行ld-linux.so.
ldd:不是一个可执行程序,只是一个 shell 脚本(解释器:解释具有良好的动态特性和可移植性,比如在解释执行时可以动态改变变量的类型、对程序进行修改以及在程序中插入良好的调试诊断信息等,而将解释器移植到不同的系统上,则程序不用改动就可以在移植了解释器的系统上运行。同时解释器也有很大的缺点,比如执行效率低,占用空间大,因为不仅要给用户程序分配空间,解释器本身也占用了宝贵的系统资源。),可以用它来查看共享库所依赖的信息
再谈动态链接和动态加载的区别
动态加载和动态链接都是在程序运行时发生,并将所需代码加载到内存。
关键区别是动态加载由人工指定(代码中的dlopen),而动态链接直接把共享库的代码拷贝到内存。
动态链接需要 os 的特殊支持,通过动态链接加载的库代码可以在各个进程之间共享。而对动态加载而言,可以在各自进程中打开共享库代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自由技艺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值