gcc:编译器 业界最流行的编译器就是gcc,然后是微软的masm.mac已经默认安装了gcc、g++的编译器。
gdb:调试器。
一、gcc编译器:
c 程序:使用gcc或g++编译器编译。c程序后缀为:.c
c++程序:使用g++编译器编译。c++程序后缀为:
一个编译过程包括下面几个阶段:
(1)预处理:预处理器将对源文件中的宏进行展开。
(2)编 译:gcc将c文件编译成 汇编文件。
(3)汇 编:as将汇编文件编译成机器码。
(4)链 接:将目标文件和外部符号进行连接,得到一个可执行二进制文件。
步骤1:写代码:test.c
步骤2:预编译:gcc
-E test.c
-o test.i //vim test.i 可以看到预编译已经把.h拷贝进去了,define X 2 也全部替换掉了。
步骤3:编 译:gcc
-S test.i
-o test.s //生成的test.s是汇编语言。
步骤4:汇 编:
as test.s
-o test.o //将汇编代码翻译成二进制,生成目标文件.o不可执行。通过file可看到该文件位置还没有定下来。
步骤5:链 接:gcc test.o
-o test //生成可执行文件test。./test可以执行。
一步生成目 标文件:gcc -c test.c //后面省略了-o test.o 。可以使用nm命令查看test.o文件。
一步生成可执行文件:gcc test.c -o test //这时生成的就是可执行文件。可以任何文件直接-o成最后的可执行文件。
如果不写-o test,会默认生成a.out
gcc test1.c test2.c test3.c -o main //一次编多个文件的情况
gcc -v //显示gcc版本
-c 生成 .o文件,只编译不链接
-o 输出目标文件,制定输出文件名
-g 加上之后会把自己的代码跟调试信息对应起来,可执行程序包含调试信息
二、动态库、静态库
静态库:lib***.a
动态库:lib***.o
静态库:静态库少之又少。当把静态库拷给使用者之后,别人不需要库就能执行。也就是不依赖于中间层。缺点就是生成的二进制太大了。可能拷贝了很多无用的接口。每一个可执行文件都包含库。
动态库:在程序链接时并不会被链接到目标代码中,而是在程序运行时才被载入。 好处就是:当有多个可执行文件时。共享一个库。 坏处就是:当程序拿到别的机器上运行时,需要调试。需要看看库是不是有,版本是不是对。
工作当中一般都是动态库。
系统默认动态库:/lib /lib64 /usr/lib /usr/local/ 一般自己写的库放在/usr/lib下
如何编写动态库:
步骤一:vim add.c
int add(int a,int b){
return a+b;
}
步骤二:
gcc -fPIC -Wall -c add.c
//-o add.o 可以省略。因为-c 默认生成同名的.o文件。
步骤三:
gcc add.o -shared -o libadd.so //这时就生成了动态库:libadd.so
步骤四:
cp -rp libadd.so /lib //最简单的就是拷贝到lib下面,这样其他程序就可以使用了。
步骤五:vim test.c
#include <stdio.h>
void main(int argc,char* argv[]){
if(argc!=3){
printf("argc error");
return;
}
int i=atoi(argv[1]);
int j=atoi(argv[2]);
printf("sum=%d\n",
add(i,j));
}
步骤六:gcc test.c -o main
-ladd //要显示地写出自己写的库。-l***表示链接库。
或步骤六:
env看环境变量。里面的PATH能看到自动搜索的路径。
echo $LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/luke //在环境变量中增加路径,在该路径下存放动态库
如何编写静态库:(工作中都不用,一般只写动态库)
步骤一:vim add.c //同动态库步骤一。
步骤二:gcc -c add.c //省略了-o add.o
步骤三:ar crsv libadd.a add.o //生成了静态库:libadd.a
步骤四:rm /lib/libadd.so //拷静态库之前先把add的动态库删了。
cp libadd.a /lib //同动态库步骤四。
步骤五:开始使用,vim test.c //同动态库步骤五。
步骤六:gcc main.c -o main -ladd //同动态库步骤六。