目录
1 编译
1.1 编译流程
- 预处理 gcc -E hello.c -o hello.i
- 编译 gcc -S hello.i -o hello.s
- 汇编 as hello.s -o hello.o 相当于gcc -c hello.c -o hello.o
- 链接 ld -static crt1.o .... 生成a.out可执行文件,把各个模块之间相互引用的部分都处理好,使得各个模块之间能够正确的衔接。链接器为目标文件分配地址和空间
- 预编译编译程序cc1(相当于预处理+编译)、汇编器as、链接器ld
- 有限状态机进行词法分析;lex程序进行词法扫描
- 生成静态库ar命令
-
libtool:提供通用的库编译支持。libtool主要的一个作用是在编译大型软件的过程中解决了库的依赖问题
-
libtoolize:提供了一种标准方式来将libtool支持加入到一个软件包
-
xmake:一个跨平台自动构建工具,支持在各种主流平台上构建项目。xmake -UB;xmake // 用于构建环境并生成Makefile
1.2 automake生成Makefile
- 创建源代码文件,使用autoscan生成configure.scan文件,将其重命名为configure.ac,并做适当修改
- 使用aclocal命令生成aclocal.m4文件。AM_INIT_AUTOMAKE(hello,1.0)需要手动添加,否则生成不了aclocal.m4文件
- 手工编辑或由系统给定acconfig.h文件,使用autoheader命令生成config.h.in文件
- 手工编辑Makefile.am文件,使用automake命令生成configure.in文件
- 使用autoconf命令由configure.ac和aclocal.m4文件生成configure文件,依赖于gnu m4
- 使用configure命令由configure、configure.in和config.h.in文件生成Makefile文件。运行时会检测系统的环境,确定软件安装目录。执行时可以--prefix=PREFIX设置,如果不指定,缺省情况下:PREFIX 是 /usr/local默认安装时;执行文件安装到 /usr/local/bin目录;库安装到 /usr/local/lib 目录;数据文件安装到/usr/local/share 目录
- make调用系统中的编译器进行编译和连接
- make install将软件安装到设定的目录
- 执行make dist将程序和相关文件打包生成“程序名-版本号.tar.gz
1.3 编写Makefile.am
AUTOMAKE_OPTIONS=foreign # automake提供了三种软件等级:foreign(只检测必须的文件)、gnu'(默认)和gnits。
bin_PROGRAMS=main # 定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空格隔开。
main_SOURCES=main.c # 定义main这个执行程序所需要的原始文件。所有原始文件都列出来,并用空格隔开
AM_CPPFLAGS:编译器的-I参数
SUBDIRS:在处理顶层目录之前,先递归处理子目录
$(top_srcdir):源代码所在目录
$(top_builddir):编译顶层目录
noinst:不安装
1.4 编写bMakefile
$ 表示执行一个Makefile的函数
$@ 表示规则中的目标文件集
$% 仅当目标是函数库文件中,表示规则中的目标成员名
$< 依赖目标中的第一个目标名字
$? 所有比目标新的依赖目标的集合
$^ 所有的依赖目标的集合
.PHONY clean是一个“伪目标”
-fPIC 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的
-shared 指定生成动态链接库
-pipe 使用管道代替编译中临时文件
-L 设置文件路径,-l 代表库名
-rm file 命令前面加“-”表示忽略命令出错
-Idir (大写i) 对于#include,gcc/g++会到-I制定的目录查找,查找不到,然后将到系统的缺省的头文件目录查找
(~/.bashrc 中,export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib)
ifeq () … else … endif 条件判断
automake --add-missing:可以让 automake 自动添加一些必需的脚本文件,默认方式是采用符号链接
1.5 底层查看命令
readelf -h *.o : 查看目标文件文件头
readelf -e *.o : 查看目标文件各个段信息
readelf -S *.o:查看目标文件符号表
objdump -d *.o : 查看目标文件汇编信息
objdump -h :输出目标文件的所有段概括()
objdump -r helloworld.o 查看重定位表
objdump -x obj 以某种分类信息的形式把目标文件的数据组织(被分为几大块)输出 <可查到该文件的所有动态库>
objdump -t obj 输出目标文件的符号表()
objdump -j .text/.data -S obj 输出指定段的信息,大概就是反汇编源代码把
objdump -S obj C语言与汇编语言同时显示
2 gdb调试命令
cat /proc/sys/kernel/core_pattern:查看core路径
gdb <program> core:调试Core
gdb <program> ->attach PID
gdb <program> <PID>
generate-core-file:在gdb调试时保存core文件
c 跳到下一个断点,继续运行程序
s 单步跟踪并进入函数
n 单步跟踪但不进入函数
u 运行直到退出循环体
p *array@len 查看动态数组
p array 查看静态数组
finish 退出函数
thread apply all bt 查看所有线程的调用栈情况
frame 0:表示栈顶
frame 1:表示栈的第二层
frame 切换当前的栈 up:表示向栈的上面移动一层。down:表示向栈的下面移动一层
set print element 0 看一个字符串的时候默认显示是截断的,可以通过命令显示完整的字符串
set print address on 打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址,系统默认为打开的
set print array on 打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则
set var width=47 设置程序变量的值
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args:命令可以查看设置好的运行参数。
info f:这个命令会打印出更为详细的当前栈层的信息
info args:打印出当前函数的参数名及其值。
info locals:打印出当前函数中所有局部变量及其值。
info break:显示当前设置的断点信息
break filename:linenum 在源文件filename的linenum行处停住
break filename:function 在源文件filename的function函数的入口处停住
break if i=100,表示当i为100时停住程序