由于现在开发软件基本上都是用的IDE(集成开发环境),所以很少接触到关于编译、链接、装载和库等方面的知识,这也导致了大家仅仅只会在上层开发代码,但对软件的编译、装载等工作原理一无所知,所以,当遇到一些编译、链接之类的错误底层错误时,都较难解决;
为了弄清编译、链接和程序运行的原理,我特意研究了相关知识;
本文是我当时在研究时用到的常用命令整理的,为了方便大家学习,现分享给大家,如下:
备注: Mac 中 可用clang 取代 gcc 命令
1. 预处理
$ gcc -E <代码文件> -o <输出文件>
或者
$ cpp <代码文件> -o <输出文件>
2. 编译
$ gcc -S <代码文件或者预处理后文件> -o <输出文件>
-fno-builtin:关闭内置函数;
-shared : 产生共享对象(动态链接库);
-fPIC : 指示gcc产生地址无关代码;
-fpic : 指示gcc产生地址无关代码;产生的代码相对“-fPIC”较小,但“-fpic”在某些平台上有一些限制;
3. 汇编
$ gcc -c <代码文件或者编译后文件> -o <输出文件>
或者
$ as <编译后文件> -o <输出文件>
$ gcc -c <代码文件或者编译后文件> -o <输出文件>
查看文件类型
$ file <文件名>
4. 查看可执行文件的内部结构
$ objdump -h <文件名>
-h :把关键段的基本信息打印出来;
-x : 把各段的更多的信息打印出来;
-s :将所有段的内容以16进制的方式打印出来;
-d :将所有包含指令的段把汇编;
-r :打印需要重定位的内容;
5. 查看可执行文件的代码段、数据段、BSS段的长度
$ size <文件名>
6. 查看可执行文件的符号表
$ nm <文件名>
7. 查看可执行文件的段
$ readelf <文件名>
8. 解析被编译器修饰后的名称
$ c++filt <修改后的名字>
9. 链接目标文件
$ id <目标文件1> <目标文件2> …… -e <入口函数名字> -o <输出文件名>
10. 链接命令
$ id [选项]
-verbose:查看默认的链接脚本;
-static : 静态链接;
-e <入口函数名>:设置程序的入口函数
-o <文件名>:设置输出文件名;
-s:禁止链接器产生符号表;
11. 静态库
$ ar <选项> <静态库>
-t:查看静态库的中目标文件;
-X: 将库中的所有目标文件解压出来;