linux下gcc如何生成.so文件及使用动态链接库.so文件。

生成.so文件且使用

  1. 第一步,写成一个hello.h文件

    1
    2
    3
    4
    #include<stdio.h>
    #include<stdlib.h>

    void helloWorld();
  2. 第二步,写成一个hello.c文件

    1
    2
    3
    4
    5
    #include"hello.h"

    void helloWorld(){
    printf("hello coding");
    }
  3. 用这俩文件生成一个.so文件
    gcc hello.c -shared -fPIC -o libhello.so

  • -shared选项说明编译成的文件为动态链接库,不使用该选项相当于可执行文件
  • -fPIC 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的。
  1. 写一个test.c文件,运用动态链接库libhello.so文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include<sys/syscall.h>
    #include"hello.h"

    #define gettid() syscall(__NR_gettid)

    int main(){
    helloWorld();
    printf("\n hello world \n");
    printf("-------leave thread_main (pid: %d, tid: %ld) -------\n", getpid(), gettid());
    }

编译test.c文件,运行如下:gcc test.c -L. -lhello -o test

  • -L. 表示链接的文件在当前目录下;
  • -lhello 代表链接的文件名 gcc会自动为其前面添加lib,在其后边添加.so 即libhello.so;

运行之后会报错如下:

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

因为找不到动态链接库,导入环境变量:

1
export LD_LIBRARY_PATH=/data/c:$LD_LIBRARY_PATH;

./test运行即可。

动态链接库路径问题

引用文章https://blog.csdn.net/zxh2075/article/details/54629318

Linux下的共享库默认搜索路径为/lib/usr/lib两个目录(不包含子目录)。

加载动态链接库的方法有五种:
1,连接时使用静态库(.a文件)。
2,使用LD_LIBRARY_PATH环境变量(本文采用的),把需要添加的路径加入到LD_LIBRARY_PATH中,注意如果多于一个要用冒号隔开。如:export LD_LIBRARY_PATH=/usr/local/lib/lin
3,将动态库文件复制到可以搜索到的路径(一般是系统默认的路径,如/lib/usr/lib)里面,这样比较狠,但是可能导致一些后即问题。
4,编译的时候设定:在编译源码的时候可以用参数:-Wl-rpath指定动态搜索的路径即可。
5,修改系统文件/etc/ld.so.conf,添加路径,运行ldconfig命令。

第五种方法的说明如下:
/etc/ld.so.conf文件中指定了默认的动态链接库查找路径,我的/etc/ld.so.conf文件内容是这样的

1
2
include ld.so.conf.d/*.conf 
/usr/local/matrix/lib

也是说它间接的指定了定义路径的文件,我们只需要把需要的路径加到/etc/ld.so.conf.d目录下的任何一个文件中,再运行ldconfig就可以了,但为了容易理解,最好是找一个相关的文件,或者重新建立一个文件,把需要添加的路径写入然后运行ldconfig;

ldconfig几个需要注意的地方:

  1. /lib/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library会找不到;
  2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到(除非添加到环境变量);