Makefile带来的好处就是——“自动化编译”,一但写好,只需要一个 make 命令,整个工程便可以完全编译,极大的提高了软件的开发效率
一个工程中的源文件不计其数,按其类型、功能、模块分别放在若干个目录中。makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至进行更复杂的功能操作
make工具最主要也是最基本的功能就是根据makefile文件中描述的源程序至今的相互关系来完成自动编译、维护多个源文件工程。而makefile文件需要按某种语法进行编写,文件中需要说明如何编译各个源文件并链接生成可执行文件,要求定义源文件之间的依赖关系。
指源代码转化成生成可执行代码的过程,最常用的编译器是gcc。
gcc的编译流程
·预处理阶段:头文件和宏定义,—E可以让gcc在预处理结束之后停止编译过程,因此可以看到预处理的过程
一般格式为:gcc [选项] 要编译的文件 [选项] 目标文件
gcc -E hello.c -o hello.i
·编译阶段:gcc将代码翻译成汇编语言,使用选项-S只进行编译而不进行汇编,结果生成汇编代码。
gcc -S hello.i -o hello.s
汇编阶段:将.s文件转成目标文件,使用选项-c可以看到汇编代码转换为二进制目标代码。
gcc -c hello.s -o hello.o
链接阶段:默认搜索链接到libc.so.6函数库当中,调用库文件中已经实现的函数。
gcc编译选项分析
1)call指令:后接被调用过程的起始的指令地址。效果是将返回地址入栈,并跳转到被调用过程的起始处。
2)ret指令:从栈中弹出地址,并跳转到这个位置。
一个简单的、可以称之为IA32指令集的子集的指令集;只包括四字节整数操作,寻址方式比较少。指令编码长度从1——6字节不等。指令集的一个重要性只就是字节编码必须具有唯一的解释。
关于指令结构,每条指令的第一个字节表明指令的类型;这个字节分为两个部分,每部分四位:高四位是代码部分(0——0xB),第四位是功能部分。这里补充一些缩写:立即数(i),寄存器(r)、存储器(m)。指令附加的寄存器指示符字节依次是数据源(如果是立即数,把这一位设置成0xf)、目的寄存器/基址寄存器。有些指令需要附加四字节的常数字,采用小端法(倒序)编码
使用man -k passwd会找到很多和passwd相关的帮助页
grep 可以对文件全文检索,支持正则表达式
提供显示Linux命令使用案例,包括该命令所有的选项和简短但尚可理解的功能。
find的重要参数
-atime 最后访问时间
-ctime 创建时间
-mtime 最后修改时间
只能搜索二进制文件(-b),man帮助文件(-m)和源代码文件(-s)
which本身是 Shell 内建的一个命令,我们通常使用which来确定是否安装了某个指定的软件,因为它只从PATH环境变量指定的路径中去搜索命令
$ which man
三种模式:
命令行模式,插入模式,底行模式
模式的切换 :
vim启动进入普通模式,处于插入模式或命令行模式时只需要按Esc或者Ctrl+[(这在vim课程环境中不管用)即可进入普通模式。
普通模式->插入模式:普通模式中按i(插入)或a(附加)键都可以进入插入模式,
普通模式->命令行模式:普通模式中按:进入命令行模式。
退出:命令行模式中输入wq回车后保存并退出vim
删除信息:
dd 删除整行
dw 删除一个单词(不适用中文)
d$或D 删除至行尾
d^ 删除至行首
dG 删除到文档结尾处
d1G 删至文档首部
*命令之前加上数字,表示一次删除多行
快速跳转(行间):
nG(n Shift+g) 游标移动到第 n 行(如果默认没有显示行号,请先进入命令模式,输入:set nu以显示行号)
gg 游标移动到到第一行
G(Shift+g) 到最后一行
小技巧:你在完成依次跳转后,可以使用Ctrl+o快速回到上一次(跳转前)光标所在位置,
复制(类似于删除d):普通模式中使用y复制
预处理:gcc –E hello.c –o hello.i; gcc –E调用cpp
编 译:gcc –S hello.i –o hello.s; gcc –S调用ccl
汇 编:gcc –c hello.s –o hello.o; gcc -c 调用as
链 接:gcc hello.o –o hello ; gcc -o 调用ld
=>./hello(./当前目录)
程序保存退出后用gcc进行编译,一定要记得加上选项“-g”这样编译出来的可执行代码才包含调试信息
基本命令:
gdb programm (启动GDB)
b 设断点(要会设4种断点:行断点、函数断点、条件断点、临时断点)
run 开始运行程序
bt 打印函数调用堆栈
p 查看变量值
c 从当前断点继续运行到下一个断点
n 单步运行
s 单步运行
quit 退出GDB
四种断点
1.行断点
b [行数或函数名] <条件表达式>
2.函数断点
b [函数名] <条件表达式>
3.条件断点
b [行数或函数名] <if表达式>
4.临时断点
tbreak [行数或函数名] <条件表达式>
静态库的创建:
(1)使用归档工具ar,将目标文件集成在一起
# gcc -c unusgn_pow.c
# ar rscv libpow.a unsgn_pow.o
a - unsgn_pow.o
(2) 编译主程序来观看一下结果
# gcc -o pow_test pow_test.c -L. -lpow
# ./pow_test 2 10
2.^10=1024
"-L dir" :在库文件的搜索路径中添加dir目录
"-lname" 选项指示编译时连接到库文件libname.a或libname.so
动态库的创建:
# gcc -fPIC -Wall -c unsgn_pow.c
2.使用-shared选项和已创建的位置无关目标代码,生成动态库libpow.so
# gcc -shared -o libpow.so unsgn.so
3.编译程序(将链接到刚生成的动态库lipow.so)
# gcc -o pow_test pow_test.c -L. -lpow
一个makfile通常包含的内容:
需要有make工具创建的目标体(target),通常指目标文件和可执行文件
需要创建的目标所以依赖的文件(dependency_file)
创建每个目标体所需要运行的命令(command)这一行必须由制表符Tab开头
参考资料来自闫佳歆同学
原文:http://www.cnblogs.com/20135335hs/p/4928675.html