0720linux共享库和静态库制作

要制作静态库和共享库的代码块

代码块a.c

int add(int a, int b)
{
    return a+b;
}

代码块b.c

int sub(int a, int b)
{
    return a-b;
}

1. 静态库

静态库生成步骤

  • 首先把a.c和b.c编译成.o的文件 gcc a.c b.c -c生成a.o ,b.o

  • 静态库相当于做一个归档文件,就是把.o文件放在一块,ar rcs libmycalc.a a.o b.o,命令解析:表示要把目标码a.o和b.o加入到静态库libmycalc.a中(ar的参数r)。若libmylib.a不存在,会自动创建(ar的参数c)。然后更新.a文件的索引,使之包含新加入的.o文件的内容(ar的参数s)。 一般静态库命名开头是lib。

  • 生成静态库之后还要有配套的头文件calc.h
    #ifndef CALC_H_
    #define CALC_H_
    int add(int a, int b);
    int sub(int a, int b);
    #endif
  • 调用静态库

    • 目录结构:
      .
      ├── include
      │ └── calc.h
      ├── libmylib.a
      └── main.c
    • 代码块main.c
      
      #include <stdio.h>
      
      
      #include <calc.h>
      
      int main(void)
      {
          printf("10 + 20 = %d\n", add(10, 20));
      }
      return 0;

    gcc 编译命令gcc -Iinclude main.c libmycalc.a

  • 虽然静态库是一个.a的文件,但是内部还是按照归档的.o文件划分的,像这个例子,就是调用只一个add函数,仍会把a.o里面的其他函数全部编译进去,而不会编译b.o里面的函数。

2. 共享库

共享库生成步骤

  • gcc -fPIC -c a.c b.c生成与位置无关的.o文件a.o b.o

第一种生成共享库的方法

gcc -shared -Wl -o libmycalc.so a.o b.o生成共享库
gcc -Iinclude main.c libmycalc.so但这时候如果执行a.out报错,因为这个时候系统找不到libmycalc.so,因为共享库要设置环境变量

ldd a.out 查看a.out运行的时候所依赖的库有哪些

  • linux默认共享库路径有/lib//usr/lib/,但是不要往里面放,万一自己生成的把系统的原来的共享库覆盖掉,就会出问题。
  • 可以执行exprot LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./,临时设置,只对当前终端生效
  • 在用户目录~下,把exprot LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径放到.bashrc里面就可以对当前用户生效,放到/etc/profile里,对所有用户生效
  • /etc/ld.so.conf最后一行加上你共享库的路径,在使用sudo ldconfig -v更新这个配置文件。

第二种生成共享库的方法

gcc -shared -W1,-soname,libmycalc.so.1 -o libmycalc.so.1.10 a.o b.o,逗号后面没有空格

库有三个名字

read name soname linkname
记录库真正的名字 记录库的主版本号 Makefile和加载器,用于链接的名字(手动创建的软链接)
libmycalc.so.1.10 libmycalc.so.1 libmycalc.so

场景1:

1. 如果用libmycalc.so.1.10生成了一个a.out,然后在add函数中加了几行代码并没有改变函数接口,这时候把库重新发布为libmycalc.so.1.20,但是库的soname没有变,还是libmycalc.so.1,这个时候a.out还可以继续加载新发布的libmycalc.so.1.20;
2. a.out里面的库名称是soname,只要库的soname没变,a.out就可以继续加载此库。

场景2:

1.如果改变了add函数的接口,把库重新发布为libmycalc.so.2.10,相应的,库的soname就变成了libmycalc.so.2
2.此时a.out运行的时发现soname不匹配,a.out就无法完成加载,运行不起来 

共享库与静态库优缺点

静态库

优点:
    1.生成的可执行程序,可以扔到任何电脑上执行
缺点:
    1.如果静态库非常大,链到可执行程序里,导致可执行程序非常大
    2.如果库发生修改,可执行文件就要重新编译
    3.对于多个可执行程序链到同一个函数,并且执行的时候,浪费内存。

共享库

优点:
    1.编译的时候省硬盘空间
    2.运行的时候省内存空间
    3.如果库发生修改,可执行文件在某些情况下不需要重新编译,但是当库的借口改变的时候也是需要重新编译的
缺点:
    1.生成的可执行程序依赖共享库

你可能感兴趣的:(编译,共享库,Linux编程)