嵌入式Linux文件IO,共享库(动态库)创建,添加加载路径和使用,LD_LIBRARY_PATH环

2019-07-12 14:46发布

文章目录

1,共享库的创建

a,编写库源码hello.c,bye.c

linux@linux:~/test/stdio/share_library$ vi hello.c #include void hello(void) { printf("hello world "); return ; } linux@linux:~/test/stdio/share_library$ vi bye.c #include void bye(void) { printf("bye! "); return ; }

b,为共享库编写头文件common.h

#ifndef __COMMON_H__ #define __COMMON_H__ void hello(void); void bye(void); #endif

c,编译生成目标文件

linux@linux:~/test/stdio/share_library$ gcc -c hello.c bye.c -fPIC -Wall linux@linux:~/test/stdio/share_library$ ls bye.c bye.o common.h hello.c hello.o
  1. -fPIC选项:告诉编译器生成位置无关代码
  2. 位置无关代码:生成的".o文件"文件中的代码可以被加载到任意的地址执行。编译的时候用到了相对寻址而不是绝对寻址

d,创建共享库common

linux@linux:~/test/stdio/share_library$ gcc -shared hello.o bye.o -o libcommon.so.1 linux@linux:~/test/stdio/share_library$ ls bye.c bye.o common.h hello.c hello.o libcommon.so.1
  1. -shared选项:告诉编译器生成一个共享库
  2. 生成的共享库的文件名叫"libcommon.so.1",其中".so"表示这是一个共享库,".1"表示这个库的版本是1

e,为共享库文件创建链接文件

linux@linux:~/test/stdio/share_library$ ln -s libcommon.so.1 libcommon.so linux@linux:~/test/stdio/share_library$ ll total 36 drwxr-xr-x 2 linux linux 4096 11月 5 19:53 ./ drwxrwxr-x 5 linux linux 4096 11月 5 19:09 ../ -rw-rw-r-- 1 linux linux 70 11月 5 19:13 bye.c -rw-rw-r-- 1 linux linux 1312 11月 5 19:38 bye.o -rw-rw-r-- 1 linux linux 86 11月 5 19:24 common.h -rw-r--r-- 1 linux linux 78 11月 5 19:29 hello.c -rw-rw-r-- 1 linux linux 1324 11月 5 19:38 hello.o lrwxrwxrwx 1 linux linux 14 11月 5 19:53 libcommon.so -> libcommon.so.1* -rwxrwxr-x 1 linux linux 6937 11月 5 19:51 libcommon.so.1*

2,共享库的使用

a,编写测试程序test.c

#include #include "common.h" int main(int argc, const char *argv[]) { hello(); bye(); return 0; }

b,编译test.c并链接共享库libcommon.so

linux@linux:~/test/stdio/share_library$ gcc test.c -o test.out -L. -lcommon linux@linux:~/test/stdio/share_library$ ls bye.c bye.o common.h hello.c hello.o libcommon.so libcommon.so.1 test.c test.out linux@linux:~/test/stdio/share_library$ ./test.out ./test.out: error while loading shared libraries: libcommon.so: cannot open shared object file: No such file or directory
  1. “gcc test.c -o test.out -L. -lcommon”,可以发现此处共享库和静态库用法相同;GCC在链接时首先找共享库,如果共享库不存在,则链接静态库,如果静态库也找不到,则报错;加"-static"选项后,编译器会直接去找静态库。
  2. 执行时出错原因:因为程序链接的是共享库,并没有复制共享库中的代码,程序在执行时还会去加载用到的共享库,在加载的时候回去缺省的路径(比如"/lib","/usr/lib")下去寻找共享库,但是我们创建的库在当前目录下,并不在系统库的搜索路径里,所以在执行的时候找不到共享库就报错了;
  3. 创建好共享库后还需要添加共享库加载路径

3,添加共享库的加载路径

a,在LD_LIBRARY_PATH环境变量中库所在路径

linux@linux:~/test/stdio/share_library$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. linux@linux:~/test/stdio/share_library$ ./test.out hello world bye!
  1. export:将原来的环境变量导出
  2. “:“前面”$LD_LIBRARY_PATH"是引用原先的值;”:“后面的”.“是追加了当前目录;还可以追加其余共享库的路径,要用”:"隔开
  3. 此方法是临时的,只对当前终端有效。当重新打开一个终端再执行改程序时又会报错

b,把库拷贝到/usr/lib和/lib目录下

  1. 不建议采用这种方案,拷贝到该目录下需要管理员权限
  2. 一般系统库放在该目录下,程序员开发的库放在其他目录下更加合适

c,添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新

  1. 在/etc/ld.so.conf.d/目录下创建my_common.conf文件
linux@linux:~/test/stdio/share_library$ sudo vi /etc/ld.so.conf.d/my_common.conf [sudo] password for linux:
  1. 文件中写入共享库路径
/home/linux/test/stdio/share_library
  1. 使用ldconfig刷新
linux@linux:~/test/stdio/share_library$ sudo ldconfig ldconfig会读取这个目录下面所有的配置文件,把配置文件路径中的库的所有信息提取出来
  1. 在多个终端都可执行测试程序
linux@linux:~/test/stdio/share_library$ ./test.out hello world bye!