GCC详解-gcc之创建动态库静态库及其使用

1、动态库

1.1 创建动态库

创建库文件的头文件mylib.h,内容为:

int myfun(int a);

创建库文件的源文件mylib.c,内容为:

#include <stdio.h>
#include "mylib.h"

int myfun(int a)
{
        return a;
}

使用如下命令生成我们的共享库libmy.so:

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

1.2 使用动态库

创建main.c,内容为:

#include "mylib.h"

int main()
{
        int result = myfun(88);
        printf("result is : %d\n", result);
        return 0;
}

可见我们里面用到了我们的动态库里的函数,也包含了动态库的头文件。我们用如下命令编译:

gcc  -I./ main.c ./libmy.so -o main

生成的可执行文件为main。我们执行它:

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

这说明编译的时候可以找到这个库,但是执行的时候找不到它。解决办法有如下几个:

1)export LD_LIBRARY_PATH=自定义动态库的路径
(只能起到临时作用,关闭终端后失效)
LD_LIBRARY_PATH : 指定查找共享库(动态链接库)时除了默认路径之外的其他路径,该路径在默认路径之前查找

2)将上述命令写入home目录下的.bashrc文件中,保存后重启终端生效(永久)

3)直接将动态库拷贝到user/lib的系统目录下(强烈不推荐!!)

4)将libmy.so所在绝对路径追加入到/etc/ld.so.conf文件,使用sudo ldconfig -v 更新

我们使用的方法是第1)种:

export LD_LIBRARY_PATH=/home/wjbvb2/study/gcc/gcc

$ ./main 
result is : 88

2、静态库

2.1 创建静态库

创建库文件的头文件:

#include <stdio.h>

int my_static_lib_func(int a, int b);

创建库文件的源文件:

#include "mystaticlib.h"

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

编译静态库:

$gcc -c mystaticlib.c -o mystaticlib.o #先将mystaticlib.c编译成.o文件

$ar rcs libmystaticlib.a mystaticlib.c #将mystaticlib.o生成静态库mystaticlib.a

$ ls
libmystaticlib.a  main.c  mystaticlib.c  mystaticlib.h  mystaticlib.o

rcs:

r将文件插入静态库中

c创建静态库,不管库是否存在

s写入一个目标文件索引到库中,或者更新一个存在的目标文件索引

2.2 使用静态库

写main.c:

#include "mystaticlib.h"

int main()
{
        int result = my_static_lib_func(30, 80);

        printf("result is %d \n", result);

        return 0;
}

编译方法有两种:

$ gcc main.c -L./ -lmystaticlib -I./  -o main

或者

$ gcc main.c ./libmystaticlib.a -o main2

$ ./main 
result is 110 

$ ./main2 
result is 110 

3、同时有静态库,又有动态库,如何区分

我们把刚才代码继续创建一份动态库 libmystaticlib.so(虽然看着很奇怪啊,名字叫静态库,结果又是so文件):

$ gcc mystaticlib.c -fPIC -shared -o libmystaticlib.so
$ ls
libmystaticlib.a  libmystaticlib.so  main  main2  main.c  mystaticlib.c  mystaticlib.h  mystaticlib.o

这时候,这个目录下有个libmystaticlib.a,又有个libmystaticlib.so,那么我们用如下命令编译main.c的时候,会用到哪个库呢?

$gcc main.c -L./ -lmystaticlib -I./ -o main3

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

可见如果有了libmystaticlib.so存在,那么编译的时候链接的是libmystaticlib.so,而不是libmystaticlib.a。运行的时候它找的是libmystaticlib.so。

那么如果两个库都存在,又想静态链接怎么办呢?用-static:

$ gcc main.c -L./ -lmystaticlib -I./ -static -o main4
$ ./main4 
result is 110 

我觉得可以将我们生成的4个可执行文件做个总结:

可执行程序 生成时的命令,以及当时有的库 readelf -d结果(只列出依赖的动态库)
main

gcc main.c -L./ -lmystaticlib -I./  -o main

当时只有libmystaticlib.a,没有so文件

Shared library: [libc.so.6]
 
main2

gcc main.c ./libmystaticlib.a -o main2

当时只有libmystaticlib.a,没有so文件

Shared library: [libc.so.6]
main3

gcc main.c -L./ -lmystaticlib -I./ -o main3

当时libmystaticlib.a和libmystaticlib.so都存在

 Shared library: [libmystaticlib.so]
 Shared library: [libc.so.6]
 
main4

gcc main.c -L./ -lmystaticlib -I./ -static -o main4

当时libmystaticlib.a和libmystaticlib.so都存在

There is no dynamic section in this file.

由此看,加了-static关键字后,连c库都被静态链接进去了。

Guess you like

Origin blog.csdn.net/sjwangjinbao/article/details/119062210