Linux下的静态编译与动态编译

编译是一个把高级语言写成的代码经过一系列的步骤转换成相应处理器汇编语言的过程。

静态编译

静态编译是指在链接时把函数库整合到目标代码里面,这样做的优点是静态编译完成后就不再需要外部的函数库来支持了,缺点也显而易见,编译后的程序体量会增大很多,并且如果静态函数库改变了,程序需要重新静态编译。

生成静态链接库

静态编译自然不可缺少静态函数库(.a),静态函数库由可重定向文件*.o(也叫目标文件)打包而成:
在CentOS7环境下:

gcc -o libmylib.o -c libmylib.c
ar -rc libmylib.a libmylib.o

这样就会生成静态库libmylib.a

编译静态库

编译链接时需要指明头文件路径、库路径及库名称:

gcc -o main main.c  -I. -L. -l mylib

-I参数指明头文件路径
-L参数指明库路径
-l参数指明库名称,注意,这里的库名称要去掉前缀lib(静态库名称默认lib打头)和后缀.a

如果觉得麻烦,可以将头文件和库分别拷贝至系统指定的默认的头文件目录和库文件目录中,默认头文件路径一般为:/usr/include,默认库路径为:/usr/lib。执行这些操作需要root权限。
拷贝以后,编译时可以省略-I和-L参数,编译器会去默认路径下查找头文件和库,但-l参数仍要给出以指明库名称。
此外,也可以由环境变量LIBRARY_PATH指明静态库目录。
编译链接后,即使删掉静态库,程序也能正常运行。

动态编译

不同于静态编译,动态编译在运行时才去调用库函数。所以程序体量比较小,库升级时程序也不需要重新编译,比较方便。

生成动态库

动态函数库(.so)生成方式:
第一步,先生成可重定向文件,不同于静态编译,动态编译要加上-fPIC:

gcc -fPIC -c mylib.c

第二步,生成函数库(.so)

gcc -shared -o libmylib.so mylib.o

这两步也可以合起来:

gcc -fPIC -shared -o libmylib.so mylib.c

这时就会生成mylib.so。
第三步:编译链接
和静态编译链接一样:

gcc -o main main.c  -I. -L. -l mylib 

这时会生成一个文件main。
运行时却报错: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
再来看一下main的信息

ldd main

其中有一行为:
libmymath.so => not found
由此可见,程序在运行时找不到动态库。
加载动态库的方法:

  1. 将刚生成的动态库拷贝到默认目录/lib或者/usr/lib,然后执行ldconfig命令
  2. 更改环境变量LD_LIBRARY_PATH
  3. 修改/etc/ld.so.conf,把路径添加到文件末尾,然后执行ldconfig命令

你可能感兴趣的:(Linux下的静态编译与动态编译)