库的概念  

  Ø 库是一个二进制文件,包含的代码可被程序调用
  Ø 标准C库、数学库、线程库……
  Ø 库有源码,可下载后编译;也可以直接安装二进制包
  Ø /lib /usr/lib 库

  Ø 库是事先编译好的,可以复用的代码。
  Ø 在OS上运行的程序基本上都要使用库。使用库可以提高 开发效率。
  Ø Windows和Linux下库文件的格式不兼容
  Ø Linux下包含静态库和共享库

 

静态库

  在程序编译时候链接截断被连接到目标代码中,运行时候不在需要静态库。编译后体积较大。

共享库动态库

  在程序编译时候并不会被马上链接到目标代码中,而是在执行阶段才被程序载入,因此编译后的可执行程序体积小,但是需要系统动态库存在。

了解静态库动态库
Windows .lib .dll
Linux .a .so

  预处理 gcc   a.c   -E   -o   a.i   做宏替换,头文件展开,去除注释

  编译  gcc   a.i   -S   -o   a.s   检查语法错误,将C语言编译生产汇编

  汇编  gcc   a.s   -c   -o   a.o  将汇编编译成二进制机器码

  链接  gcc   a.o   -o   a.out    将所有二进制机器码文件.o和静态库文件.a统一链接生成可执行程序a.out

              E      i

              S      s

              c      o

静态库制作

静态库特点

  ~ 编译(链接)时把静态库中相关代码复制到可执行文件中
  ~程序中已包含代码,运行时不再需要静态库
  ~程序运行时无需加载库,运行速度更快
  ~占用更多磁盘和内存空间
  ~静态库升级后,程序需要重新编译链接

静态库创建

  Ø 确定库中函数的功能、接口
  Ø 编写库源码hello.c

1 //hello.c    
2 #include <stdio.h>
3 void hello(void) 
4 {
5    printf(“hello world\n”); 
6    return; 
7 }

 

  Ø 编译生成目标文件
    $ gcc -c hello.c -Wall

gcc -c hello.c -Wall

 

  Ø 创建静态库 hello
    $ ar crs libhello.a hello.o

ar crs libhello.a hello.o

  Ø 查看库中符号信息
    $nm libhello.a

nm libhello.a

    hello.o: 

    0000000 T hello
        U puts

链接静态库

  Ø 编写应用程序test.c

1 //test.c
2 #include <stdio.h>
3  
4 void hello(void); 
5 int main() 
6 { 
7     hello(); 
8     return 0; 
9 }

  Ø 编译test.c 并链接静态库libhello.a

    $ gcc -o test test.c -L. -lhello

gcc -o test test.c -L. -lhello

  

gcc  

-o  test  test.c  -L  -l Hello
gcc编译器 重命名选项 重命名  .c文件 链接库选项 链接库路径 链接库标识符  库名

 


  $ ./test
  hello world

 

共享库制作

共享库特点

  ~ 编译(链接)时仅记录用到哪个共享库中的哪个符号,不 复制共享库中相关代码
  ~ 程序不包含库中代码,尺寸小
  ~ 多个程序可共享同一个库
  ~ 程序运行时需要加载库
  ~ 库升级方便,无需重新编译程序
  ~ 使用更加广泛

共享库创建

1、确定库中函数的功能、接口
2、编写库源码hello.c bye.c
  

 1 //hello.c
 2 #include <stdio.h>
 3 void hello(void) 
 4 {   
 5   printf(“hello world\n”); 
 6   return; 
 7  } 
 8 
 9 //bye.c
10 #include <stdio.h>
11 void hello(void) 
12 { 
13   printf(“bye\n”); 
14   return; 
15 } 



3、 编译生成目标文件
  $ gcc -c -fPIC hello.c bye.c -Wall
    gcc -c -fPIC hello.c bye.c -Wall
    -fpic编译为位置独立的代码

4、 创建共享库 common
  $ gcc -shared -o libcommon.so.1 hello.o bye.o
  gcc -shared -o libcommon.so.1 hello.o bye.o
  -shared指定生成动态库 lib<库名>.so.<版本>

5、 为共享库文件创建链接文件
  $ ln -s libcommon.so.1 libcommon.so
  ln -s libcommon.so.1 libcommon.so

  1)在虚拟机与物理机的共享文件目录中,无法创建符号链接文件  
  2)将 libcommon.so.1 复制到虚拟机家目录下,就可以创建符号链接了

6、 符号链接文件命名规则
  lib<库名>.so

链接共享库

1、编写应用程序 test.c

1 #commin.h
2 void hello(void);
3 void bye(void);
 1 //test.c
 2 
 3 #include <stdio.h>
 4 #include "common.h"
 5 int main() 
 6 { 
 7   hello(); 
 8   bye(); 
 9   return 0; 
10 } 

 

  

2、 编译 test.c 并链接共享库 libcommon.so
  $ gcc -o test test.c -L. -lcommon
  gcc -o test test.c -L . -l common

  1)默认情况下先找共享库
  2)如果共享库存在,则链接共享库
  3)如果共享库不存在,则寻找静态库
  4)如果静态库存在,则链接静态库
  5)如果静态库不存在,则报错

  6)若加上 -static 选项,则直接链接静态库

加载共享库

1、执行程序 

  $ ./test
  ./test: error while loading shared libraries: libcommon.so cannot open shared object file : No such file or directory

2、添加共享库的加载路径
  $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
  $ ./test
    hello world
    bye!
如何找到共享库

Ø 为了让系统能找到要加载的共享库,有四种方法 :
  1、把库拷贝到/usr/lib和/lib目录下 不推荐
  2、在LD_LIBRARY_PATH环境变量中添加库所在路径 推荐(但是是一次性的)
  3、添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新 推荐(永久性的)
    1)在/etc/ld.so.conf.d/目录下,新建一个*.conf文件
      如:touch my.conf
    2)在 my.conf 添加路径
      如 /mnt/htgf/abc
    3)在终端中执行 sudo ldconfig 命令刷新
  4、或者 sudo vim /etc/bash.bashrc 推荐(永久性的)
    在文件末尾增加  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tmp

    保存退出,重启终端,此时在此执行./a.out正常显示。






























 

posted on 2020-10-06 21:10  八杯水  阅读(224)  评论(0)    收藏  举报