作者: 晓崔忆网 发布日期:2006-03-12 10:33 出自:互联网
感谢作者提供心得.
最近开始有重操过去使用过的Linux,不过这次不是RedHat,改成了同学推荐的Ubuntu,安装过程简单多了,而且只需要一张光盘。其余的大部分更新和安装都是在网上完成的,所以如果你想学Linux的话,最好要有一个良好的网络环境。回到正题,这次知识为了学习GCC:
请大家看看吧
1.Preprocessor
1)在宏定义代参数的函数时,左括号和函数名之间不能有空格
2)在重新定义同一宏名字之前,应该先undef该宏
3)当宏在一行内定义不下时,用反斜杠/放在一行的结尾
4)当宏中的参数被当作字符串处理时,参数本身会和其相邻的字符串自动组合
5)当参数出现...时,表示参数个数是变元
6)宏#error,会产生一个致命错误,并终止编译
7)宏#warning,会产生一个警告信息,但继续编译
8)Gcc选项 -Wundef会对未定义宏的使用进行警告
9)Gcc选项 -I会指定率先搜索的头文件路径
10)宏##是连接符
11)好习惯:利用宏实现头文件只包含一次
12)好习惯:利用宏实现错误信息的显示和log
13)好习惯:在调试过程中可以利用宏来Remove source code in Place
14)Gcc选项 -E指示编译器只进行预处理,不进行编译和连接
15)Gcc选项 -M指示编译器输出所有的头文件依赖信息
2.C Language Compile
1).a是静态库,也称为archive
2).s是汇编文件
3).so是共享库
4)Gcc选项 -c是只将源文件编译为目标文件即停止
5)Gcc选项 -S是将源文件编译为汇编文件
6)静态库使用ar -r命令生成可以将多个目标文件个并生成一个静态库。如:ar -r libxxx.a fisrt.o second.o
7)对于传统的名字命名习惯对于静态库开头以lib开始,后缀为.a即可,这样在调用静态库时可以使用-l选项:
如 gcc main.c libxxx.a -o main
可以写成 gcc main.c -lxxx -o main
8)在实现共享库时,要将源文件编译为相对地址编码的格式。
9)Gcc选项 -fpic是实现8)中要求的选项。pic是position independent code的缩写。如:gcc -c -fpic component1.c component2.c
10)Gcc选项 -shared实现共享库的生成。利用-fpic得到的目标文件生成共享库文件:gcc -shared component1.o component2.o -o component.so
11)9)和10)两个步骤可以合并:gcc -fpic -shared component1.c component2.c -p component.so
12)Gcc选项 -aux-info可以导出被编译源文件所包含的所有函数(或方法)的原型。如:gcc component.c -aux-info prototype.h
以下几条为GCC对C语言扩展:
13)定义数组可以使用动态长度:char str_arr[strlen(string)+1];
14)动态数组可以做参数
15)在结构体里可以定义长度为0的数组,但必须作为最后一个成员。如:
typedef struct{
int size;
char string[0]; // 也可以写成 char string[]
}vlen;
在使用时只要把想要生成的空间在malloc时加上就好,如:vlen *line = (vlen *)malloc(sizeof(vlen) + ncount);
注:虽然动态地分配了更多的内存到结构题对象,但其大小还是按原大小计算,即无论ncount的大小是多少,sizeof的大小永远是4(int的大小)
16)__attribute__关键字使用来指定给一个函数某些属性,以便让他们在编译是被编译器优化编译
17)复合语句:用大括号来把一些列语句括起来,并返回一个值。一般用于定义复合语句的宏定义。注意:C++没有复合语句的宏定义
18)枚举变量可以声明和定义分离
19)inline函数就好宏一样在code内展开
20)在Switch/Case语句中可以用“ ... ”来表示一个区间值,如:case 1 ... 5, 或者 case 'a' ... 'h'。注意:...两边要有空格
21)typedef语句还可以得到类型:
int a = 1;
typedef _type = a; // 这时_type已经是int的代名词了
_type b = 0; // b也是int类型了
也可以用typeof来实现上面的功能:
int a = 1;
typeof(a) b = 0;
3.C++ Language Compile
1)默认情况下,头文件是按照C语言环境编译的,正如extern "C"一样,但是如果有C++语言就会出错,可以在C++头文件加入#pragma cplusplus
2)Mangling Names的解释:P120。不同语言如C++和Java的Mangling策略是不同的
4.Linking and Librayies
1) ar负责用来生成静态库,如:ar -q libxxx.a xxx1.o xxx2.o xxx3.o,使用-q选项可以快速生成静态库,而不更新索引。所以要后事用ranlib libxxx.a来建索引。目标文件的顺序会影响调用者的行为。ar详细选项件P262
2)C++于C在编译时会有不同,在main函数之前就已存在的对象要依靠静态构造函数实现,这就需要collect2来链接。
3)在链接时定位共享库:用-L指定绝对路径,也可以是用-l指定相对路径。对于使用传统命名法:这种情况下会先搜索该名的共享库,然后是静态库。默认搜索路径是/lib和/usr/lib
4) 在运行时,应用程序的搜索路径包括:环境变量LD_LIBRARY_PATH指定的路径、/etc/ld.so.cache中的共享库(由 ldconfig生成)、/lib和/usr/lib。另外还有一个环境变量LD_PRELOAD,在这里定义的共享库会比任何前述路径优先搜索。
5)前面讲过在gcc命令行里面加入共享库编译的方式,我们暂时称他为静态链接。这里要讲动态链接:首先在调用文件中加如#include <dlfcn.h>。以及使用dlopen(),dlsym(), dlerror()和dlclose()。在dlopen()里有一个flag,RTLD_NOW表示将库中所有函数全部装入内存,RTLD_LAZY则是只装入调入的内存。
6)ldconfig命令有两个主要作用:一是使链接所指向的动态库永远保持最新版本;二是它可以把全部可用的动态库信息装到/etc/ld.so.cache中,帮助搜索。详见P270
7)nm命令可以列出所有定义在目标文件、静态库和共享库中的symbols。P271
8)strip命令用于去除目标文件、静态库和共享库中的debug信息,从而是目标文件变小。P274
9)ldd命令用来读取可执行文件、共享库对其他共享库的依赖关系。一个典型用途就是找到程序所使用的共享库。
10)objdump命令用来抽取目标文件、静态库和共享库中的信息并将它们保存成为可供理解的格式。P277
5.GNU debug
1)gdb的三个警告水平:默认是2。
2)gdb有不同的debug信息格式:最常用的就是-ggdb,除此之外还有-gstabs和-gdwarf。命令行P296。
3)三种debug模式:
a)把一个程序装在到调试器中:gdb program
b)利用程序crush掉生成的core文件信息进行debug:gdb program core
c)把一个运行中(后台运行)的程序动态的载入到debugger中:先用ps aux找到program的process ID,然后用gdb program ID。这是调试器就会结合到该进程上,并且挂起当前进程。
6.Make and Autoconf
1)make的作用就是检查源代码和目标文件,确定哪些源文件需要重新编译生成新目标文件。
2)目标文件和源文件之间的这种关系称作依存关系(dependency),目标文件称为目标(target)
3)用": "确定依存关系,在实现依存关系的命令行必须一tab键缩进。可是在开始用All: xxx yyy zzz把没有相互依存关系的xxx yyy zzz放在一起,把它们都make。
4)make默认情况下会在当前路径下查找makefile文件,然后是Makefile文件。也可以用make -f xxx的选项指定特殊名称的makefile文件。
5)要活用make自己定义的一些宏和suffix rule。可以用make -p | more来学习用法。
6)初学者些makefile可以参照已有的工程模板。自己做修改。
7)Autoconf工具集的用途是帮助我们创建安装shell脚本。我们的目的是生成configure脚本,用于检查某些工程编译所需的系统模块的存在性,并且生成makefiles文件反应当前的环境状态。
8)创建安装文件脚本的步骤:
a)Determine conditional compilation
b)Create the configure.in file
c)Edit the configure.in file
d)Create makefile.in
e)Create config.h.in
f)Update your source
g)Create the installation script
h)copy the Autoconf scripts
最后GCC还有一些环境变量可以设置,请有所了解。P502