1.编译。对c++而言,通常是文件独立编译--生成独立的中间目标文件。这时主要是语义语法检查,函数与变量的申明的正确性。这需要引入合适的头文件,要让编译器看到定义。编译生成的文件在windows下是.obj文件,在unix下是.o文件。
2.连接。连接时,主要是连接函数和全局变量,地址替换和重定位。连接时只关注目标文件,忽略了源文件。如果函数未被声明,通常只是警告一下,可以生成目标文件。但是如果类型未定义(编译器无法确定类型大小时),则出错。
3.库文件。每个文本文件得到一个.o文件。我们使用时必须连接用到的所有.o文件。这显然不是一个聪明的做法。怎么办?我们可以把很多.o文件打包成库文件。比如说标准c库,标准c++库等。打包后的库文件在windows下是.lib文件,在unix下是.a文件。
// -- 4,5,6,7,8是关于makefile的概貌:http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/index.html#content
4.makefile的编写
makefile由make解释程序来执行,makefile的主要规则异常简单,以冒号区分目标和先决条件,下一行是满足先决条件时要执行的命令,如下:
target : condition1 ... conditionn
commandline
一个实例:
main.o: main.c main.h
gcc -g -o main main.c
如果main.c或main.h有任何一个文件比main.o新,则执行下面命令的重新编译。
另一个例子:
clean : (no conditions, clean不是一个文件,只是一个动作名,没有先决条件意味着无条件执行)
rm -f main.o
如果我们输入make clean则执行rm -f main.o
5.make的工作过程
--在当前目录下寻找Makefile和makefile文件。
--解释执行makefile文件,对于所依赖的目标文件,makefile会递归它们的依赖性(像一个堆栈的过程)。
--第一个目标文件当是终极目标,自动执行的时候,它相当于树的根。如果某些规则不在这棵树中,则该规则
不会自动执行。比如上面示例的clean动作(这些动作可以显示调用)
6.写出出色的makefile文件
会写makefile文件,并不意味着能写出一个漂亮的makefile文件。
makefile中可以申明变量(相当于宏):NAME= ... 引用$(NAME)
使用变量的目的会让makefile变得很清晰,易于维护。
7.make的自动推导功能
比如看到main.o自动把main.c加入到它的依赖列表。并且gcc -o main.o main.c被推导出来。
这就是“隐晦规则”,在这里不详细讨论隐晦规则和伪目标文件(.PHONY表示)。
8.关于"编程修养":为每一个makefile文件写一个clean的伪目标。一般风格是:
clean:
rm object1 ... $(objects)
更为稳健的做法是:
.PHONY : clean
clean :
-rm object1 ... $(objects) //前面加-的原因是:这样如果执行过程中出错了,忽略错误继续执行后面的。
// -- 9,10 是关于gcc/g++的概貌
9.gcc/g++简介:gcc and g++分别是gnu的c & c++编译器
gcc/g++在执行编译工作的时候,总共需要4步
1.预处理,生成.i的文件 --.i文件
2.将预处理后的文件不转换成汇编语言,生成文件.s --.s文件
3.有汇编变为目标代码(机器代码)生成.o的文件 --.o文件
4.连接目标代码,生成可执行程序
10.[参数详解]
-c
只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
-S
只激活预处理和编译,就是指把文件编译成为汇编代码。
-E
只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里
--可以试一下gcc -E hello.c >hello.txt 或者 gcc -E hello.c | more
-o
制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果 你和我有同感,改掉它,哈哈
-ansi
关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一些asm inline typeof关键字,以
及UNIX,vax等预处理宏,
-wall
显示警告信息
-fno-asm
此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作关键字。
-O0
-O1
-O2
-O3
编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-g
只是编译器,在编译的时候,产生调试信息。
-ggdb
此选项将尽可能的生成gdb的可以使用的调试信息.
-Ldir
指定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然编译器将只在标准库的目录
找。这个dir就是目录的名称。
-llibrary
指定编译的时候使用的库
// -- 11,12 是关于gdb的概貌
11.gdb简介:Linux包含了一个叫gdb的GNU调试程序. gdb是一个用来调试C和C++程序的强力调试器. 它使你能在程序运行时观察程序的内部结构和内存的使用情况. 以下是gdb 所提供的一些功能:
它使你能监视你程序中变量的值. --监视内存和寄存器
它使你能设置断点以使程序在指定的代码行上停止执行. --断点调试
它使你能一行行的执行你的代码. --单步调试
12.gdb基本命令:
file 装入想要调试的可执行文件.
kill 终止正在调试的程序.
list 列出产生执行文件的源代码的一部分. 可以后面加n定位
next 执行一行源代码但不进入函数内部.
step 执行一行源代码而且进入函数内部.
run 执行当前被调试的程序
quit 终止gdb
watch 使你能监视一个变量的值而不管它何时被改变. 必须先让设断点进入
break 在代码里设置断点, 这将使程序执行到这里时被挂起.
make 使你能不退出gdb就可以重新产生可执行文件.
shell 使你能不离开gdb就执行UNIX shell命令. exit退出shell模式