【Linux】动静态库

目录

  • 前言
  • 动态库与静态库
  • 1、动静态库的概念
  • 2、静态库的制作和使用
    • 2.1、静态库的制作
    • 2.2、静态库的发布
    • 2.3、静态库的使用
  • 3、动态库的制作和使用
    • 3.1、动态库的制作
    • 3.2、动态库的发布
    • 3.3、动态库的使用

前言

这篇文章给大家带来动态库和静态库的了解和制作!!!


动态库与静态库

1、动静态库的概念

Linux下动态库和静态库的区别:

  • 静态库(.a):程序在编译链接的时候把库的代码“链接(拷贝)”到可执行文件中。程序运行的时候就不再需要静态库了!

  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用动态库的代码

  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码

  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上指定的动态库中复制到内存中,这个过程称为动态链接(dynamic linking) – 加载后,多个程序就能共享链接

  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小节省了磁盘和内存空间

  • 操作系统采用虚拟内存(共享区)机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间

动静态库里里面可以带main函数吗???

  • 答案是:绝对不行的,因为当用户使用你制作的动静态库时,链接会导致main函数冲突(二义性)
  • 这里演示的是头文件没有带主函数的:
[root@localhost mklib]# cat mymath.h
#pragma once
#include 

// [from, to] -> result -> return
extern int addToVal(int from, int to);
[root@localhost mklib]# cat mymath.c
#include "mymath.h"
#include 

int addToVal(int from, int to)
{
    assert(from <= to);
    int result = 0;
    for (int i = from; i <= to; ++i)
    {
        result += i;
    }
    return result;
}

[root@localhost mklib]# cat test.c 
#include "mymath.h"

int main()
{
    int from, to;
    printf("请输入from和to的值: ");
    scanf("%d %d", &from, &to);
    int result = addToVal(from, to);
    printf("从%d开始累加到%d的值为: %d\n", from, to, result);
    return 0;
}

[root@localhost mklib]# ./test 
请输入from和to的值: 1 1001开始累加到100的值为: 5050

2、静态库的制作和使用

2.1、静态库的制作

首先我们定义这几个文件:mymath,h、mymath.c、myprint.h、myprint.c(前面二个代码与上面的一样)

[root@localhost mklib]# cat myprint.h
#pragma once
#include 
// 输出五个hello world!!!
extern void Print();

[root@localhost mklib]# cat myprint.c
#include "myprint.h"

void Print()
{
    for (int i = 0; i < 5; ++i)
    {
        printf("hello world!!!\n");
    }
}
  • 第一步:将mymath.c、myprint.c生成目标文件!!!
  • 链接:就是把所有后缀为.o的文件链接起来,生成可执行文件

gcc 【-c】文件名 ,编译到链接时停下来,生成目标文件

[root@localhost mklib]# cat makefile 
.PHONY:all
all:mymath.o myprint.o

mymath.o:mymath.c
	gcc -c $^ -o $@ -std=c99

myprint.o:myprint.c
	gcc -c $^ -o $@ -std=c99

.PHONY:clean
clean:
	rm -rf mymath.o myprint.o
	
[root@localhost mklib]# make
gcc -c mymath.c -o mymath.o -std=c99
gcc -c myprint.c -o myprint.o -std=c99

[root@localhost mklib]# ll
总用量 32
-rw-r--r--. 1 root root  174 1211 12:45 makefile
-rw-r--r--. 1 root root  209 1211 12:40 mymath.c
-rw-r--r--. 1 root root  106 1211 12:01 mymath.h
-rw-r--r--. 1 root root 1688 1211 12:46 mymath.o
-rw-r--r--. 1 root root  120 1211 12:40 myprint.c
-rw-r--r--. 1 root root   54 1211 12:01 myprint.h
-rw-r--r--. 1 root root 1520 1211 12:46 myprint.o
-rw-r--r--. 1 root root  250 1211 12:01 test.c

如果我把二个目标文件给别人,别人能链接使用吗?

  • 可以的,只要新建的源文件能找到要执行函数的头文件(#include “”),然后生成目标文件后

  • 三个目标文件在链接时,会将所有内容拷贝合并成可执行文件,这就是(伪)静态库!!!

[root@localhost mklib]# mkdir Test
[root@localhost mklib]# cp myprint.o mymath.o ./Test/
[root@localhost mklib]# cd Test
[root@localhost Test]# vim test.c
[root@localhost Test]# cat test.c
#include "../mymath.h"
#include "../myprint.h"

int main()
{
    int ret = addToVal(1, 100);
    printf("1到100累加的值为: %d\n", ret);
    Print();
    return 0;
}

[root@localhost Test]# gcc -c test.c
[root@localhost Test]# ls
mymath.o  myprint.o  test.c  test.o

[root@localhost Test]# gcc mymath.o myprint.o test.o -o test
[root@localhost Test]# ls
mymath.o  myprint.o  test  test.c  test.o

[root@localhost Test]# ./test 
1100累加的值为: 5050
hello world!!!
hello world!!!
hello world!!!
hello world!!!
hello world!!!

这时候我们发现有很多的.o文件,我们要将他们打包起来,打包后,它就是一个静态库!!!

生成静态库:

  • ar [-rc] lib文件名 目标文件

  • ar是“GNU归档工具”,意思就是将“目标文件打包”

  • rc选项:当打包完后目标文件发生改变时,重写打包就需要该选项(替换旧的.o文件

  • 选项后面跟的文件名就是你要生成的静态库名字(以lib开头后面是文件名)

$@是目标文件的名字
$^是依赖文件的名字

  • 比如有test:test.o test2.o,test就是$@,后面的目标文件就是另外一个^
[root@localhost mklib]# ls
makefile  mymath.c  mymath.h  myprint.c  myprint.h  test.c

// 自动构建项目
[root@localhost mklib]# cat makefile 
.PHONY:all
all:libmymath.a
libmymath.a:mymath.o myprint.o
	ar -rc $@ $^

mymath.o:mymath.c
	gcc -c $^ -o $@ -std=c99

myprint.o:myprint.c
	gcc -c $^ -o $@ -std=c99

.PHONY:clean
clean:
	rm -rf mymath.o myprint.o libmymath.a
	
[root@localhost mklib]# make
gcc -c mymath.c -o mymath.o -std=c99
gcc -c myprint.c -o myprint.o -std=c99
ar -rc libmymath.a mymath.o myprint.o

[root@localhost mklib]# ll
总用量 36
-rw-r--r--. 1 root root 3424 1211 14:16 libmymath.a
-rw-r--r--. 1 root root  224 1211 14:14 makefile
-rw-r--r--. 1 root root  209 1211 12:40 mymath.c
-rw-r--r--. 1 root root  106 1211 12:01 mymath.h
-rw-r--r--. 1 root root 1688 1211 14:16 mymath.o
-rw-r--r--. 1 root root  120 1211 13:18 myprint.c
-rw-r--r--. 1 root root   54 1211 12:01 myprint.h
-rw-r--r--. 1 root root 1520 1211 14:16 myprint.o
-rw-r--r--. 1 root root  250 1211 12:01 test.c

查看静态库中的目标文件:

  • ar [-tv] 静态库文件名

  • t选项:列出静态库中的文件

  • v(verbose)选项:详细信息

[root@localhost mklib]# ar -tv libmymath.a 
rw-r--r-- 0/0   1688 Dec 11 14:45 2022 mymath.o
rw-r--r-- 0/0   1520 Dec 11 14:45 2022 myprint.o

2.2、静态库的发布

我们学习C/C++时,使用它们库,需要什么呢???

  • 需要下载C/C++的动静态库文件

  • 需要动静态库中目标文件所依赖的头文件

这里的makefile里面使用伪目标UseStatic’创建一个目录,里面有二个目录分别存储动静态件和头文件

[root@localhost mklib]# cat makefile 
.PHONY:all
all:libmymath.a
libmymath.a:mymath.o myprint.o
	ar -rc $@ $^

mymath.o:mymath.c
	gcc -c $^ -o $@ -std=c99

myprint.o:myprint.c
	gcc -c $^ -o $@ -std=c99

.PHONY:UseStatic
UseStatic:
	mkdir -p ./lib-static/lib
	mkdir -p ./lib-static/include
	cp *.a ./lib-static/lib
	cp *.h ./lib-static/include

.PHONY:clean
clean:
	rm -rf *.o *.a lib-static

发布静态库

[root@localhost mklib]# ls
makefile  mymath.c  mymath.h  myprint.c  myprint.h  test

[root@localhost mklib]# make
gcc -c mymath.c -o mymath.o -std=c99
gcc -c myprint.c -o myprint.o -std=c99
ar -rc libmymath.a mymath.o myprint.o

[root@localhost mklib]# ls
libmymath.a  makefile  mymath.c  mymath.h  mymath.o  myprint.c  myprint.h  myprint.o  test.c

[root@localhost mklib]# make UseStatic
mkdir -p ./lib-static/lib
mkdir -p ./lib-static/include
cp *.a ./lib-static/lib
cp *.h ./lib-static/include

[root@localhost mklib]# ll
总用量 36
-rw-r--r--. 1 root root 3424 1211 14:45 libmymath.a
drwxr-xr-x. 4 root root   32 1211 14:46 lib-static
-rw-r--r--. 1 root root  353 1211 14:39 makefile
-rw-r--r--. 1 root root  209 1211 12:40 mymath.c
-rw-r--r--. 1 root root  106 1211 12:01 mymath.h
-rw-r--r--. 1 root root 1688 1211 14:45 mymath.o
-rw-r--r--. 1 root root  120 1211 13:18 myprint.c
-rw-r--r--. 1 root root   54 1211 12:01 myprint.h
-rw-r--r--. 1 root root 1520 1211 14:45 myprint.o
-rw-r--r--. 1 root root  250 1211 12:01 test.c

[root@localhost mklib]# tree lib-static/
lib-static/
├── include
│   ├── mymath.h
│   └── myprint.h
└── lib
    └── libmymath.a

2 directories, 3 files

2.3、静态库的使用

  • 首先将·动态库拷贝到新的目录中,给用户使用
[root@localhost mklib]# ll
总用量 32
-rw-r--r--. 1 root root 3424 1211 21:45 libmymath.a
drwxr-xr-x. 4 root root   32 1211 21:45 lib-static
-rw-r--r--. 1 root root  748 1211 21:44 makefile
-rw-r--r--. 1 root root  209 1211 12:40 mymath.c
-rw-r--r--. 1 root root  106 1211 12:01 mymath.h
-rw-r--r--. 1 root root 1688 1211 21:45 mymath.o
-rw-r--r--. 1 root root  120 1211 13:18 myprint.c
-rw-r--r--. 1 root root   54 1211 12:01 myprint.h
-rw-r--r--. 1 root root 1520 1211 21:45 myprint.o
drwxr-xr-x. 2 root root    6 1211 21:45 test


[root@localhost mklib]# cp -r lib-static ./test
[root@localhost mklib]# tree test/
test/
└── lib-static
    ├── include
    │   ├── mymath.h
    │   └── myprint.h
    └── lib
        └── libmymath.a

3 directories, 3 files
  • 在新建的目录中新建源文件调用动态库的库函数
[root@localhost test]# ll
总用量 4
drwxr-xr-x. 4 root root  32 1211 21:48 lib-static
-rw-r--r--. 1 root root 284 1211 21:50 test.c
[root@localhost test]# cat test.c 
#include "mymath.h"
#include "myprint.h"

int main()
{
    int from, to;
    printf("请输入from和to的值: ");
    scanf("%d %d", &from, &to);
    int result = addToVal(from, to);
    printf("从%d开始累加到%d的值为: %d\n", from, to, result);
    Print();
    return 0;
}
[root@localhost test]# gcc -o test test.c
test.c:1:20: 致命错误:mymath.h:没有那个文件或目录
 #include "mymath.h"
                    ^
编译中断。

头文件的搜索路径分为二种:" "和<>

  • " ":在进程的当前工作路径下查找头文件是否存在,但是头文件在lib-dynamic目录里面

  • <>:在系统头文件路径(/usr/include)下查找文件,如果没找到,就从当前工作路径查找

注意:如果在vs2022中是编译器在找,在Linux下是gcc在找,当它们被运行起来就是一个进程!

解决方法一:将自己的头文件和库文件,拷贝到系统路径下(库的安装)

[root@localhost test]# ll
总用量 4
drwxr-xr-x. 4 root root  32 1211 21:48 lib-static
-rw-r--r--. 1 root root 284 1211 21:50 test.c

[root@localhost test]# cp ./lib-static/include/*  /usr/include/
[root@localhost test]# cp ./lib-static/lib/libmymath.a  /lib64
[root@localhost test]# ls /lib64/libmymath.a 
/lib64/libmymath.a
  • gcc -l(指明我们要链接的第三方库,自己写的和下载的都是第三方库,C/C++库是原装库

注意:-l选项后后面假的是第三方库的文件名,要去掉前缀lib和后缀.a

[root@localhost test]# gcc -o test test.c -l mymath
[root@localhost test]# ll
总用量 16
drwxr-xr-x. 4 root root   32 1211 21:48 lib-static
-rwxr-xr-x. 1 root root 8704 1211 22:01 test
-rw-r--r--. 1 root root  284 1211 21:50 test.c
[root@localhost test]# ./test 
请输入from和to的值: 1 1001开始累加到100的值为: 5050
hello world!!!
hello world!!!
hello world!!!
hello world!!!
hello world!!!
  • 不推荐使用这种做法,因为会污染系统中头文件和库文件的命名

解决方法二:指定搜索路径 – 指令有点长!!!

  • gcc -I选项(include,指定头文件路径搜索) -L(lib,指定库文件路径搜索) -l(在-L选项指定的搜索路径下,你要链接的第三方库的名字

  • 注意头文件路径搜索指令是大写l,链接第三方库是小写l

[root@localhost test]# ll
总用量 4
drwxr-xr-x. 4 root root  32 1211 21:48 lib-static
-rw-r--r--. 1 root root 284 1211 21:50 test.c

[root@localhost test]# gcc test.c -I ./lib-static/include/  -L ./lib-static/lib/  -l mymath -o test
[root@localhost test]# ./test 
请输入from和to的值: 1 1001开始累加到100的值为: 5050
hello world!!!
hello world!!!
hello world!!!
hello world!!!
hello world!!!


3、动态库的制作和使用

3.1、动态库的制作

动态库的制作与静态库是基本一样的,只是指令有所不同

制作动态库:

[root@localhost mklib]# cat makefile 
.PHONY:all
all:libmymath.so
libmymath.so:mymath.o myprint.o
	gcc -shared -o $@ $^

mymath.o:mymath.c
	gcc -fPIC -c $^ -o $@ -std=c99

myprint.o:myprint.c
	gcc -fPIC -c $^ -o $@ -std=c99

.PHONY:clean
clean:
	rm -rf *.o *.so
  • shared选项:表示生成共享库格式 – 生成动态库

  • fPIC选项:产生位置无关码(position-independent code,PIC),PIC是一种可以在内存中的任何位置运行的程序代码。它允许操作系统将代码加载到内存中的任意位置,而不必考虑其物理地址

  • 通过使用动态库,可以在运行时将新功能添加到程序中,而无需重新编译整个程序。通过使用位置无关码,您可以将代码加载到内存中的任意位置,从而避免与其他程序的冲突

  • 位置无关码的特点是它的代码不依赖于具体的内存地址,而是通过相对地址或其他方式来访问内存中的数据。这样,程序就可以在运行时动态地被加载到内存中的任意位置,并正常运行

  • 动态库名规则:libxxx.so

//制作动态库
[root@localhost mklib]# make
gcc -fPIC -c mymath.c -o mymath.o -std=c99
gcc -fPIC -c myprint.c -o myprint.o -std=c99
gcc -shared -o libmymath.so mymath.o myprint.o

// 后缀伪.so的就是动态库
[root@localhost mklib]# ll
总用量 44
-rwxr-xr-x. 1 root root 8208 1211 19:49 libmymath.so
-rw-r--r--. 1 root root  746 1211 19:49 makefile
-rw-r--r--. 1 root root  209 1211 12:40 mymath.c
-rw-r--r--. 1 root root  106 1211 12:01 mymath.h
-rw-r--r--. 1 root root 1736 1211 19:49 mymath.o
-rw-r--r--. 1 root root  120 1211 13:18 myprint.c
-rw-r--r--. 1 root root   54 1211 12:01 myprint.h
-rw-r--r--. 1 root root 1568 1211 19:49 myprint.o
-rw-r--r--. 1 root root  250 1211 12:01 test.c

3.2、动态库的发布

动态库的发布:

.PHONY:all
all:libmymath.so
libmymath.so:mymath.o myprint.o
	gcc -shared -o $@ $^

mymath.o:mymath.c
	gcc -fPIC -c $^ -o $@ -std=c99

myprint.o:myprint.c
	gcc -fPIC -c $^ -o $@ -std=c99

.PHONY:UseDynamic
UseDynamic:
	mkdir -p ./lib-dynamic/lib
	mkdir -p ./lib-dynamic/include
	cp *.so ./lib-dynamic/lib
	cp *.h ./lib-dynamic/include

.PHONY:clean
clean:
	rm -rf *.o *.so lib-dynamic

动态库的发布跟静态库一样:

  • 需要动态库文件

  • 动态库中目标文件所依赖的头文件

[root@localhost mklib]# ls
makefile  mymath.c  mymath.h  myprint.c  myprint.h  test.c

[root@localhost mklib]# make
gcc -fPIC -c mymath.c -o mymath.o -std=c99
gcc -fPIC -c myprint.c -o myprint.o -std=c99
gcc -shared -o libmymath.so mymath.o myprint.o
 
[root@localhost mklib]# ls
libmymath.so  makefile  mymath.c  mymath.h  mymath.o  myprint.c  myprint.h  myprint.o  test.c
 
[root@localhost mklib]# make UseDynamic
mkdir -p ./lib-dynamic/lib
mkdir -p ./lib-dynamic/include
cp *.so ./lib-dynamic/lib
cp *.h ./lib-dynamic/include

[root@localhost mklib]# ll
总用量 44
drwxr-xr-x. 4 root root   32 1211 19:56 lib-dynamic
-rwxr-xr-x. 1 root root 8208 1211 19:56 libmymath.so
-rw-r--r--. 1 root root  748 1211 19:55 makefile
-rw-r--r--. 1 root root  209 1211 12:40 mymath.c
-rw-r--r--. 1 root root  106 1211 12:01 mymath.h
-rw-r--r--. 1 root root 1736 1211 19:56 mymath.o
-rw-r--r--. 1 root root  120 1211 13:18 myprint.c
-rw-r--r--. 1 root root   54 1211 12:01 myprint.h
-rw-r--r--. 1 root root 1568 1211 19:56 myprint.o
-rw-r--r--. 1 root root  250 1211 12:01 test.c
[root@localhost mklib]# tree lib-dynamic/
lib-dynamic/
├── include
│   ├── mymath.h
│   └── myprint.h
└── lib
    └── libmymath.so

2 directories, 3 files


3.3、动态库的使用

  • 首先将·动态库拷贝到新的目录中,给用户使用
[root@localhost mklib]# ll
总用量 44
drwxr-xr-x. 4 root root   32 1211 19:56 lib-dynamic
-rwxr-xr-x. 1 root root 8208 1211 19:56 libmymath.so
-rw-r--r--. 1 root root  748 1211 19:55 makefile
-rw-r--r--. 1 root root  209 1211 12:40 mymath.c
-rw-r--r--. 1 root root  106 1211 12:01 mymath.h
-rw-r--r--. 1 root root 1736 1211 19:56 mymath.o
-rw-r--r--. 1 root root  120 1211 13:18 myprint.c
-rw-r--r--. 1 root root   54 1211 12:01 myprint.h
-rw-r--r--. 1 root root 1568 1211 19:56 myprint.o
drwxr-xr-x. 3 root root   25 1211 21:23 Test
-rw-r--r--. 1 root root  250 1211 12:01 test.c

[root@localhost mklib]# cp -r lib-dynamic ./Test
[root@localhost mklib]# tree Test/
Test/
└── lib-dynamic
    ├── include
    │   ├── mymath.h
    │   └── myprint.h
    └── lib
        └── libmymath.so

3 directories, 3 files
  • 在新建的目录中新建源文件调用动态库的库函数
[root@localhost Test]# ll
总用量 4
drwxr-xr-x. 4 root root  32 1211 21:23 lib-dynamic
-rw-r--r--. 1 root root 284 1211 21:27 test.c
[root@localhost Test]# cat test.c 
#include "mymath.h"
#include "myprint.h"

int main()
{
    int from, to;
    printf("请输入from和to的值: ");
    scanf("%d %d", &from, &to);
    int result = addToVal(from, to);
    printf("从%d开始累加到%d的值为: %d\n", from, to, result);
    Print();
    return 0;
}
[root@localhost Test]# gcc -o test test.c 
test.c:1:20: 致命错误:mymath.h:没有那个文件或目录
 #include "mymath.h"
                    ^
编译中断。

头文件的搜索路径分为二种:" "和<>

  • " ":在进程的当前工作路径下查找头文件是否存在,但是头文件在lib-dynamic目录里面

  • <>:在系统头文件路径(/usr/include)下查找文件,如果没找到,就从当前工作路径查找

注意:如果在vs2022中是编译器在找,在Linux下是gcc在找,当它们被运行起来就是一个进程!

解决方法一:将自己的头文件和库文件,拷贝到系统路径下(库的安装)

  • gcc -l(指明我们要链接的第三方库,自己写的和下载的都是第三方库,C/C++库是原装库

注意:-l选项后后面假的是第三方库的文件名,要去掉前缀lib和后缀.a

[root@localhost Test]# ll
总用量 4
drwxr-xr-x. 4 root root  32 1211 21:23 lib-dynamic
-rw-r--r--. 1 root root 284 1211 21:27 test.c

[root@localhost Test]# cp ./lib-dynamic/include/mymath.h  /usr/include/
[root@localhost Test]# cp ./lib-dynamic/include/myprint.h  /usr/include/
[root@localhost Test]# cp ./lib-dynamic/lib/libmymath.so  /lib64/
[root@localhost Test]# gcc -o test test.c -l mymath

[root@localhost Test]# ll
总用量 16
drwxr-xr-x. 4 root root   32 1211 21:23 lib-dynamic
-rwxr-xr-x. 1 root root 8496 1211 22:49 test
-rw-r--r--. 1 root root  284 1211 21:27 test.c

[root@localhost Test]# ./test 
请输入from和to的值: 1 1001开始累加到100的值为: 5050
hello world!!!
hello world!!!
hello world!!!
hello world!!!
hello world!!!
  • 跟上面静态库一样,不推荐使用这种做法,因为会污染系统中头文件和库文件的命名

解决方法二:指定搜索路径

  • gcc -I选项(include,指定头文件路径搜索) -L(lib,指定库文件路径搜索) -l(在-L选项指定的搜索路径下,你要链接的第三方库的名字

  • 注意头文件路径搜索指令是大写l,链接第三方库是小写l

[root@localhost libdynamic_Test]# ll
总用量 16
drwxr-xr-x. 4 root root   32 1211 21:23 lib-dynamic
-rwxr-xr-x. 1 root root 8496 1211 22:49 test
-rw-r--r--. 1 root root  284 1211 21:27 test.c

[root@localhost libdynamic_Test]# tree .
.
├── lib-dynamic
│   ├── include
│   │   ├── mymath.h
│   │   └── myprint.h
│   └── lib
│       └── libmymath.so
├── test
└── test.c

3 directories, 5 files

[root@localhost libdynamic_Test]# gcc test.c -I lib-dynamic/include/  -L lib-dynamic/lib/  -l mymath  -o test

[root@localhost libdynamic_Test]# ./test 
./test: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

错误原因是没有找到库文件和头文件,为什么呢???

  • 因为-L、-I这些选项是gcc的,gcc启动后也是一个进程,也就是说只告诉了gcc该库的搜索路径

  • 生成test可执行程序后,运行后,test就变成了一个进程,没有人告诉这个进程中库的搜索路径

  • 一个是编译时找库,另一个是运行时找库。程序和动态库是分开加载的!

为什么静态库不会有这种问题呢???

  • 因为静态库形成可执行文件之后,已经把需要的代码拷贝进我们的代码中了,所以运行时,就不依赖自己写的库,所以就不需要运行时查找库了!!!

解决方法一:将库文件和头文件拷贝到系统路线下 – 前面已经演示过

解决方法二:导入环境变量

  • 程序在运行的时候,会在环境变量中查找自己需要的动态库路径!!!

  • 这种环境变量叫做:“LD_LIBRARY_PATH”

[root@localhost Test]# ll
总用量 16
drwxr-xr-x. 4 root root   32 1211 21:23 lib-dynamic
-rwxr-xr-x. 1 root root 8496 1211 22:59 test
-rw-r--r--. 1 root root  284 1211 21:27 test.c

[root@localhost Test]# ls /home/lyh_sky/Linux_Study/lesson23/mklib/Test/lib-dynamic/lib/
libmymath.so

// Before
[root@localhost libdynamic_Test]# echo $LD_LIBRARY_PATH
:/root/.VimForCpp/vim/bundle/YCM.so/el7.x86_64

[root@localhost Test]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lyh_sky/Linux_Study/lesson23/mklib/Test/lib-dynamic/lib/

// 添加搜索路径之后
[root@localhost libdynamic_Test]# echo $LD_LIBRARY_PATH
:/root/.VimForCpp/vim/bundle/YCM.so/el7.x86_64:/home/lyh_sky/Linux_Study/lesson23/mklib/libdynamic_Test

[root@localhost libdynamic_Test]# ./test 
请输入from和to的值: 1 1001开始累加到100的值为: 5050
hello world!!!
hello world!!!
hello world!!!
hello world!!!
hello world!!!

  • 缺陷:没有真正的添加到环境变量,关闭系统重新打开后就会消失不见

解决方法三:修改系统配置文件

  • 在 /etc/ld.so.conf.d/ 路径下创建一个新的后缀为.conf的文件

  • 将动态库的路径写入到到新创建的文件中

[root@localhost libdynamic_Test]# ll
总用量 16
drwxr-xr-x. 4 root root   32 1211 21:23 lib-dynamic
-rwxr-xr-x. 1 root root 8496 1211 22:59 test
-rw-r--r--. 1 root root  284 1211 21:27 test.c

[root@localhost libdynamic_Test]# ls /etc/ld.so.conf.d/ -l
总用量 28
-rw-r--r--. 1 root root 26 224 2022 bind-export-x86_64.conf
-rw-r--r--. 1 root root 19 89 2019 dyninst-x86_64.conf
-r--r--r--. 1 root root 63 811 00:25 kernel-3.10.0-1160.76.1.el7.x86_64.conf
-r--r--r--. 1 root root 63 1020 2020 kernel-3.10.0-1160.el7.x86_64.conf
-rw-r--r--. 1 root root 17 116 2016 libiscsi-x86_64.conf
-rw-r--r--. 1 root root 17 102 2020 mariadb-x86_64.conf
-rw-r--r--. 1 root root 21 41 2015 xulrunner-64.conf

[root@localhost libdynamic_Test]# touch /etc/ld.so.conf.d/test.conf

[root@localhost libdynamic_Test]# ls /etc/ld.so.conf.d/test.conf
/etc/ld.so.conf.d/test.conf

[root@localhost libdynamic_Test]# vim /etc/ld.so.conf.d/test.conf

[root@localhost libdynamic_Test]# cat /etc/ld.so.conf.d/test.conf
home/lyh_sky/Linux_Study/lesson23/mklib/libdynamic_Test/lib-dynamic/lib/:/home/lyh_sky/Linux_Study/lesson23/mklib/libdynamic_Test/lib-dynamic/lib/

// 设置系统动态库路径,加载新增的文件到内存中
[root@localhost libdynamic_Test]# ldconfig 

[root@localhost libdynamic_Test]# ./test 
请输入from和to的值: 1 1001开始累加到100的值为: 5050
hello world!!!
hello world!!!
hello world!!!
hello world!!!
hello world!!!

最后一种方法:在系统路径下建立软链接

  • 在/lib64/ 目录下建立动态库的软链接
[lyh@192 Test]$ ll
总用量 16
drwxrwxr-x. 4 lyh lyh   32 1212 03:59 lib-dynamic
-rwxrwxr-x. 1 lyh lyh 8536 1212 04:02 test
-rw-rw-r--. 1 lyh lyh  284 1212 04:02 test.c

[lyh@192 Test]$ ./test 
./test: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

[lyh@192 Test]$ ls /home/lyh/Linux_Study/lesson1/Test/lib-dynamic/lib/libmymath.so 
/home/lyh/Linux_Study/lesson1/Test/lib-dynamic/lib/libmymath.so

// 查看可执行文件的依赖关系
[lyh@192 Test]$ ldd test
	linux-vdso.so.1 =>  (0x00007fff037dd000)
	libmymath.so => not found
	libc.so.6 => /lib64/libc.so.6 (0x00007ff4f0ba8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ff4f0f76000)
	
[lyh@192 Test]$ sudo ln -s /home/lyh/Linux_Study/lesson1/Test/lib-dynamic/lib/libmymath.so /lib64/libmymath.so
[sudo] lyh 的密码:

[lyh@192 Test]$ ls /lib64/libmymath.so  -l
lrwxrwxrwx. 1 root root 63 1212 04:10 /lib64/libmymath.so -> /home/lyh/Linux_Study/lesson1/Test/lib-dynamic/lib/libmymath.so

[lyh@192 Test]$ ldd test
	linux-vdso.so.1 =>  (0x00007ffc5f5e3000)
	libmymath.so => /lib64/libmymath.so (0x00007fae883b9000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fae87feb000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fae885bb000)
	
[lyh@192 Test]$ ./test 
请输入from和to的值: 1 1001开始累加到100的值为: 0
hello world!!!
hello world!!!
hello world!!!
hello world!!!
hello world!!!
[lyh@192 Test]$ 

你可能感兴趣的:(Linux,linux,运维,服务器)