目录

1.什么是库

2.静态库

文件

3.动态库

1.直接放在系统的动态库里

2.软链接

3.环境变量

4.更改系统的配置文件


1.什么是库

库是写好的现有的,成熟的,可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说库是⼀种可执⾏代码的⼆进制形式,可以被操作系统载入内存执行。库有两种:
•静态库.a[Linux]、.lib[windows]
•动态库.so[Linux]、.dll[windows]

2.静态库

静态库的制作

1.动静态库中,要不要包含main函数呢?
    不要

[user1@iZ5waahoxw3q2bZ my_stdio]$ gcc -c mystdio.c
[user1@iZ5waahoxw3q2bZ my_stdio]$ gcc -c mystring.c
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 24
-rw-rw-r-- 1 user1 user1 1604 May 17 10:12 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 10:12 mystdio.h
-rw-rw-r-- 1 user1 user1 3040 May 17 10:33 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 10:31 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 10:16 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 10:34 mystring.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -c usercode.c
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 24
-rw-rw-r-- 1 user1 user1  404 May 17 10:24 mystdio.h
-rw-rw-r-- 1 user1 user1 3040 May 17 10:36 mystdio.o
-rw-rw-r-- 1 user1 user1   44 May 17 10:24 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 10:36 mystring.o
-rw-rw-r-- 1 user1 user1  579 May 17 10:30 usercode.c
-rw-rw-r-- 1 user1 user1 2368 May 17 10:37 usercode.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc *.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 40
-rwxrwxr-x 1 user1 user1 13368 May 17 10:38 a.out
-rw-rw-r-- 1 user1 user1   404 May 17 10:24 mystdio.h
-rw-rw-r-- 1 user1 user1  3040 May 17 10:36 mystdio.o
-rw-rw-r-- 1 user1 user1    44 May 17 10:24 mystring.h
-rw-rw-r-- 1 user1 user1  1272 May 17 10:36 mystring.o
-rw-rw-r-- 1 user1 user1   579 May 17 10:30 usercode.c
-rw-rw-r-- 1 user1 user1  2368 May 17 10:37 usercode.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ ./a.out
buffer:hello myfile!!!
buffer:hello myfile!!!
buffer:hello myfile!!!
^C

头文件的本质实际上是对源文件的说明文档

只要把我们对应的.o文件+.h文件打包交给别人就可以实现库的效果。

原来所有的库(无论是动还是静),本质都是源文件对应的.o
静态库本质,就是给.o下了一个

静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不再需要静态库。

⼀个可执行程序可能用到许多的库,这些库运行有的是静态库,有的是动态库,而我们的编译默认为动态链接库,只有在该库下找不到动态.so的时候才会采用同名静态库。我们也可以使用gcc的-static强转设置链接静态库。

ar是gnu归档工具,rc表示(replace and create)
t: 列出静态库中的文件 v:verbose 详细信息

[user1@iZ5waahoxw3q2bZ my_stdio]$ ar -rc libmyc.a *.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 32
-rw-rw-r-- 1 user1 user1 4570 May 17 10:49 libmyc.a
-rw-rw-r-- 1 user1 user1 1604 May 17 10:12 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 10:12 mystdio.h
-rw-rw-r-- 1 user1 user1 3040 May 17 10:33 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 10:31 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 10:16 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 10:34 mystring.o

.a静态库,本质是一种归档文件,不需要使用者解包,而用gcc/g++直接进行链接即可!
t:列出静态库中的文件
v:verbose 详细信息
静态库:.a
库的名字去掉lib和.a


-L. 也在当前目录下找
-L  去哪找库
-l  找什么库
-I指定一个头文件让我们对指定头文件搜索路径

gcc默认编译的时候,不会在当前目录下找库

[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -o usercode usercode.o
usercode.o: In function `main':
usercode.c:(.text+0x13): undefined reference to `MyFopen'
usercode.c:(.text+0x64): undefined reference to `MyFwrite'
usercode.c:(.text+0x70): undefined reference to `MyFFlush'
usercode.c:(.text+0xad): undefined reference to `MyFclose'
usercode.c:(.text+0xc1): undefined reference to `my_strlen'
collect2: error: ld returned 1 exit status
[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -o usercode usercode.o -llibmyc.a
/usr/bin/ld: cannot find -llibmyc.a
collect2: error: ld returned 1 exit status
[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -o usercode usercode.o -lmyc
/usr/bin/ld: cannot find -lmyc
collect2: error: ld returned 1 exit status
[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -o usercode usercode.o -L. -lmyc
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 40
-rw-rw-r-- 1 user1 user1  4570 May 17 10:51 libmyc.a
-rw-rw-r-- 1 user1 user1   404 May 17 10:24 mystdio.h
-rw-rw-r-- 1 user1 user1    44 May 17 10:24 mystring.h
-rwxrwxr-x 1 user1 user1 13368 May 17 10:54 usercode
-rw-rw-r-- 1 user1 user1   579 May 17 10:30 usercode.c
-rw-rw-r-- 1 user1 user1  2368 May 17 10:37 usercode.o

如果我们要连接任何非C/C++标准库(包括其他外部或者我们自己已写的),都需要指明-L -l


[user1@iZ5waahoxw3q2bZ my_stdio]$ mkdir lib
[user1@iZ5waahoxw3q2bZ my_stdio]$ mkdir -p lib/include
[user1@iZ5waahoxw3q2bZ my_stdio]$ mkdir -p lib/mylib
[user1@iZ5waahoxw3q2bZ my_stdio]$ tree lib
lib
├── include
└── mylib

2 directories, 0 files
[user1@iZ5waahoxw3q2bZ my_stdio]$ cp *.h lib/include
[user1@iZ5waahoxw3q2bZ my_stdio]$ cp *.a lib/mylib
[user1@iZ5waahoxw3q2bZ my_stdio]$ tree lib
lib
├── include
│   ├── mystdio.h
│   └── mystring.h
└── mylib
    └── libmyc.a

2 directories, 3 files
[user1@iZ5waahoxw3q2bZ my_stdio]$ tar czf lib.tgz lib
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 40
drwxrwxr-x 4 user1 user1 4096 May 17 11:10 lib
-rw-rw-r-- 1 user1 user1 4570 May 17 11:08 libmyc.a
-rw-rw-r-- 1 user1 user1 1781 May 17 11:11 lib.tgz
-rw-rw-r-- 1 user1 user1 1604 May 17 10:12 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 10:12 mystdio.h
-rw-rw-r-- 1 user1 user1 3040 May 17 10:33 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 10:31 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 10:16 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 10:34 mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ cd ../zhangsan
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 4
-rw-rw-r-- 1 user1 user1 579 May 17 10:30 usercode.c
[user1@iZ5waahoxw3q2bZ zhangsan]$ cp ../my_stdio/lib.tgz .
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 16
drwxrwxr-x 4 user1 user1 4096 May 17 11:02 lib
-rw-rw-r-- 1 user1 user1 1781 May 17 11:11 lib.tgz
-rw-rw-r-- 1 user1 user1  579 May 17 10:30 usercode.c
-rw-rw-r-- 1 user1 user1 2368 May 17 11:06 usercode.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ tar xzf lib.tgz
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 16
drwxrwxr-x 4 user1 user1 4096 May 17 11:10 lib
-rw-rw-r-- 1 user1 user1 1781 May 17 11:11 lib.tgz
-rw-rw-r-- 1 user1 user1  579 May 17 10:30 usercode.c
-rw-rw-r-- 1 user1 user1 2368 May 17 11:06 usercode.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ rm lib.tgz
[user1@iZ5waahoxw3q2bZ zhangsan]$ rm usercode.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ tree
.
├── lib
│   ├── include
│   │   ├── mystdio.h
│   │   └── mystring.h
│   └── mylib
│       ├── libmyc.a
│       ├── mystdio.c
│       └── mystring.c
└── usercode.c

3 directories, 6 files

[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -c usercode.c -I ./lib/include
[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -o usercode usercode.c -I ./lib/include -L ./lib/mylib -lmyc
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 28
drwxrwxr-x 4 user1 user1  4096 May 17 11:10 lib
-rwxrwxr-x 1 user1 user1 13368 May 17 11:13 usercode
-rw-rw-r-- 1 user1 user1   579 May 17 10:30 usercode.c
-rw-rw-r-- 1 user1 user1  2368 May 17 11:13 usercode.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ ./usercode
buffer:hello myfile!!!
buffer:hello myfile!!!
buffer:hello myfile!!!
^C

  #include "./lib/include/mystdio.h"
  或者直接在.c里面写

库,也是要被安装到系统中的


文件

[user1@iZ5waahoxw3q2bZ zhangsan]$ cat usercode.c
#include "mystdio.h"
#include "mystring.h"
#include <string.h>
#include <unistd.h>

int main()
{
    MyFile *filep = MyFopen("./log.txt","a");
    if(!filep)
    {
        printf("fopen error!\n");
        return 1;
    }

    int cnt = 10;
    while(cnt--)
    {
        char *msg = (char*)"hello myfile!!!";
        MyFwrite(filep,msg,strlen(msg));
        MyFFlush(filep);
        printf("buffer:%s\n",filep->outbuffer);
        sleep(1);
    }
    MyFclose(filep);// FILE *fp

    const char *str = "hello world!\n";
    printf("strlen:%d\n",my_strlen(str));
    return 0;
}
[user1@iZ5waahoxw3q2bZ my_stdio]$ cat mystdio.c
#include "mystdio.h"
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>

static MyFile *BuyFile(int fd,int flag)
{
    MyFile *f =(MyFile*)malloc(sizeof(MyFile));
    if(f== NULL) return NULL;
    f->bufferlen = 0;
    f->fileno = fd;
    f->flag = flag;
    f->flush_method = LINE_FLUSH;
    memset(f->outbuffer, 0, sizeof(f->outbuffer));
    return f;
}

MyFile *MyFopen(const char *path,const char *mode)
{
    int fd= -1;
    int flag = 0;
    if(strcmp(mode,"w") == 0)
    {
        flag = O_CREAT | O_WRONLY | O_TRUNC;
        fd = open(path,flag,0666);
    }
    else if(strcmp(mode,"a")==0)
    {
        flag = O_CREAT | O_WRONLY | O_APPEND;
        fd = open(path,flag,0666);
    }
    else if(strcmp(mode,"r")==0)
    {
        flag = O_RDWR;
        fd = open(path,flag);
    }
    else
    {
        //TODO
    }
    if(fd<0) return NULL;
    return BuyFile(fd,flag);
}
void MyFclose(MyFile *file)
{
    if(file->fileno < 0) return;
    MyFFlush(file);//把文件内容进行刷新
    close(file->fileno);
    free(file);
}
int MyFwrite(MyFile *file,void *str,int len)
{
    //1.拷贝
    memcpy(file->outbuffer+file->bufferlen,str,len);
    file->bufferlen +=len;
    //2.尝试判断是否满足刷新条件
    if((file->flush_method & LINE_FLUSH) && file->outbuffer[file->bufferlen-1] == '\n')
    {
        MyFFlush(file);
    }
    return 0;
}
void MyFFlush(MyFile *file)
{
    if(file->bufferlen <= 0) return;
    int n = write(file->fileno,file->outbuffer,file->bufferlen);
    (void)n;
    file->bufferlen = 0;
}
[user1@iZ5waahoxw3q2bZ my_stdio]$ cat mystdio.h
#pragma once

#include<stdio.h>

#define MAX 1024
#define NODE_FLUSH (1<<0)
#define LINE_FLUSH (1<<1)
#define FULL_FLUSH (1<<2)

typedef struct IO_FILE
{
    int fileno;
    int flag;
    char outbuffer[MAX];
    int bufferlen;
    int flush_method;
}MyFile;

MyFile *MyFopen(const char *path,const char *mode);
void MyFclose(MyFile *);
int MyFwrite(MyFile *,void *str,int len);
void MyFFlush(MyFile *);
[user1@iZ5waahoxw3q2bZ my_stdio]$ cat mystring.c
#include "mystring.h"

int my_strlen(const char *s)
{
    const char *start = s;
    while(*s)
    {
        s++;
    }
    return s-start;
}
[user1@iZ5waahoxw3q2bZ my_stdio]$ cat mystring.h
#pragma once

int my_strlen(const char *s);

[user1@iZ5waahoxw3q2bZ my_stdio]$ make
gcc -c mystdio.c
gcc -c mystring.c
ar -rc libmyc.a mystdio.o mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 36
-rw-rw-r-- 1 user1 user1 4570 May 17 11:28 libmyc.a
-rw-rw-r-- 1 user1 user1  292 May 17 11:28 Makefile
-rw-rw-r-- 1 user1 user1 1604 May 17 11:20 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 11:20 mystdio.h
-rw-rw-r-- 1 user1 user1 3040 May 17 11:28 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 11:20 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 11:20 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 11:28 mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ make output
mkdir -p lib/include
mkdir -p lib/mylib
cp -f *.h lib/include
cp -f *.a lib/mylib
tar czf lib.tgz lib
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 44
drwxrwxr-x 4 user1 user1 4096 May 17 11:28 lib
-rw-rw-r-- 1 user1 user1 4570 May 17 11:28 libmyc.a
-rw-rw-r-- 1 user1 user1 1773 May 17 11:28 lib.tgz
-rw-rw-r-- 1 user1 user1  292 May 17 11:28 Makefile
-rw-rw-r-- 1 user1 user1 1604 May 17 11:20 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 11:20 mystdio.h
-rw-rw-r-- 1 user1 user1 3040 May 17 11:28 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 11:20 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 11:20 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 11:28 mystring.o

3.动态库

动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
• ⼀个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的⼀个表,而不是外部函数所在目标文件的整个机器码
• 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamiclinking)
• 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的⼀份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

•shared:表示生成共享库格式
•fPIC:产生位置无关码(positionindependentcode)
•库名规则:libxxx.so

动态库打包直接用gcc就可以

[user1@iZ5waahoxw3q2bZ my_stdio]$ gcc -fPIC -c *.c
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 28
-rw-rw-r-- 1 user1 user1  292 May 17 11:28 Makefile
-rw-rw-r-- 1 user1 user1 1604 May 17 11:20 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 11:20 mystdio.h
-rw-rw-r-- 1 user1 user1 3088 May 17 12:53 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 11:20 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 11:20 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 12:53 mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ gcc -shared -o libmyc.so *.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 40
-rwxrwxr-x 1 user1 user1 8680 May 17 12:56 libmyc.so
-rw-rw-r-- 1 user1 user1  292 May 17 11:28 Makefile
-rw-rw-r-- 1 user1 user1 1604 May 17 11:20 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 11:20 mystdio.h
-rw-rw-r-- 1 user1 user1 3088 May 17 12:53 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 11:20 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 11:20 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 12:53 mystring.o

动态库

[user1@iZ5waahoxw3q2bZ my_stdio]$ file libmyc.so
libmyc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=ecd4304057aadbc686a3e10222dc4e044422d438, not stripped

静态库

[user1@iZ5waahoxw3q2bZ my_stdio]$ make
ar -rc libmyc.a mystdio.o mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 48
-rw-rw-r-- 1 user1 user1 4618 May 17 13:07 libmyc.a
-rwxrwxr-x 1 user1 user1 8680 May 17 12:56 libmyc.so
-rw-rw-r-- 1 user1 user1  292 May 17 11:28 Makefile
-rw-rw-r-- 1 user1 user1 1604 May 17 11:20 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 11:20 mystdio.h
-rw-rw-r-- 1 user1 user1 3088 May 17 12:53 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 11:20 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 11:20 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 12:53 mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ file libmyc.a
libmyc.a: current ar archive

cp Makefile Makefile-bak
[user1@iZ5waahoxw3q2bZ my_stdio]$ cat Makefile
libmyc.so:mystdio.o mystring.o
	gcc -shared -o $@ $^
mystdio.o:mystdio.c
	gcc -fPIC -c $<
mystring.o:mystring.c
	gcc -fPIC -c $<

.PHONY:output
output:
	mkdir -p lib/include
	mkdir -p lib/mylib
	cp -f *.h lib/include
	cp -f *.so lib/mylib
	tar czf lib.tgz lib

.PHONY:clean
clean:
	rm -rf *.o libmyc.so lib lib.tgz
[user1@iZ5waahoxw3q2bZ my_stdio]$ make
gcc -fPIC -c mystdio.c
gcc -fPIC -c mystring.c
gcc -shared -o libmyc.so mystdio.o mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 44
-rwxrwxr-x 1 user1 user1 8680 May 17 13:12 libmyc.so
-rw-rw-r-- 1 user1 user1  315 May 17 13:12 Makefile
-rw-rw-r-- 1 user1 user1  292 May 17 13:09 Makefile-bak
-rw-rw-r-- 1 user1 user1 1604 May 17 11:20 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 11:20 mystdio.h
-rw-rw-r-- 1 user1 user1 3088 May 17 13:12 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 11:20 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 11:20 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 13:12 mystring.o
[user1@iZ5waahoxw3q2bZ my_stdio]$ make output
mkdir -p lib/include
mkdir -p lib/mylib
cp -f *.h lib/include
cp -f *.so lib/mylib
tar czf lib.tgz lib
[user1@iZ5waahoxw3q2bZ my_stdio]$ ll
total 52
drwxrwxr-x 4 user1 user1 4096 May 17 13:12 lib
-rwxrwxr-x 1 user1 user1 8680 May 17 13:12 libmyc.so
-rw-rw-r-- 1 user1 user1 3407 May 17 13:12 lib.tgz
-rw-rw-r-- 1 user1 user1  315 May 17 13:12 Makefile
-rw-rw-r-- 1 user1 user1  292 May 17 13:09 Makefile-bak
-rw-rw-r-- 1 user1 user1 1604 May 17 11:20 mystdio.c
-rw-rw-r-- 1 user1 user1  404 May 17 11:20 mystdio.h
-rw-rw-r-- 1 user1 user1 3088 May 17 13:12 mystdio.o
-rw-rw-r-- 1 user1 user1  142 May 17 11:20 mystring.c
-rw-rw-r-- 1 user1 user1   44 May 17 11:20 mystring.h
-rw-rw-r-- 1 user1 user1 1272 May 17 13:12 mystring.o
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 4
-rw-rw-r-- 1 user1 user1 579 May 17 11:20 usercode.c
[user1@iZ5waahoxw3q2bZ zhangsan]$ cp ../my_stdio/lib.tgz ./
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 8
-rw-rw-r-- 1 user1 user1 3407 May 17 13:15 lib.tgz
-rw-rw-r-- 1 user1 user1  579 May 17 11:20 usercode.c
[user1@iZ5waahoxw3q2bZ zhangsan]$ tar xzf lib.tgz
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 12
drwxrwxr-x 4 user1 user1 4096 May 17 13:12 lib
-rw-rw-r-- 1 user1 user1 3407 May 17 13:15 lib.tgz
-rw-rw-r-- 1 user1 user1  579 May 17 11:20 usercode.c
[user1@iZ5waahoxw3q2bZ zhangsan]$ tree lib
lib
├── include
│   ├── mystdio.h
│   └── mystring.h
└── mylib
    └── libmyc.so

2 directories, 3 files
[user1@iZ5waahoxw3q2bZ zhangsan]$ gcc -o usercode usercode.c -I lib/include -L lib/mylib/ -lmyc
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 24
drwxrwxr-x 4 user1 user1 4096 May 17 13:12 lib
-rw-rw-r-- 1 user1 user1 3407 May 17 13:15 lib.tgz
-rwxrwxr-x 1 user1 user1 8808 May 17 13:17 usercode
-rw-rw-r-- 1 user1 user1  579 May 17 11:20 usercode.c
[user1@iZ5waahoxw3q2bZ zhangsan]$ ./usercode
./usercode: error while loading shared libraries: libmyc.so: cannot open shared object file: No such file or directory
[user1@iZ5waahoxw3q2bZ zhangsan]$ ldd usercode
	linux-vdso.so.1 =>  (0x00007ffca925b000)
	libmyc.so => not found
	libc.so.6 => /lib64/libc.so.6 (0x00007f4972fb3000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f4973381000)

表示不存在,没找到。

告诉谁了?只告诉了gcc
系统 != gcc

静态库为什么没有这个问题?
静态库在链接时是直接把库的文件拷贝到可执行文件里,一旦形成可执行文件,可执行文件不再依赖静态库

 

1.直接放在系统的动态库里

[user1@iZ5waahoxw3q2bZ zhangsan]$ sudo cp lib/mylib/libmyc.so /lib64
[sudo] password for user1: 
[user1@iZ5waahoxw3q2bZ zhangsan]$ ls /lib64/libmyc.so
/lib64/libmyc.so
[user1@iZ5waahoxw3q2bZ zhangsan]$ ./usercode
buffer:hello myfile!!!
buffer:hello myfile!!!
buffer:hello myfile!!!
^C
[user1@iZ5waahoxw3q2bZ zhangsan]$ ldd usercode
	linux-vdso.so.1 =>  (0x00007ffd3f186000)
	libmyc.so => /lib64/libmyc.so (0x00007f120b58f000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f120b1c1000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f120b791000)
[user1@iZ5waahoxw3q2bZ zhangsan]$ sudo rm /lib64/libmyc.so
[user1@iZ5waahoxw3q2bZ zhangsan]$ ldd usercode
	linux-vdso.so.1 =>  (0x00007ffe80771000)
	libmyc.so => not found
	libc.so.6 => /lib64/libc.so.6 (0x00007f6e38aa3000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f6e38e71000)

2.软链接

[user1@iZ5waahoxw3q2bZ zhangsan]$ sudo ln -fs /home/user1/linux-learning/linux/26-5-18.2/zhangsan/lib/mylib/libmyc.so /lib64/libmyc.so
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll /lib64/libmyc.so
lrwxrwxrwx 1 root root 71 May 17 13:27 /lib64/libmyc.so -> /home/user1/linux-learning/linux/26-5-18.2/zhangsan/lib/mylib/libmyc.so
[user1@iZ5waahoxw3q2bZ zhangsan]$ ./usercode
buffer:hello myfile!!!
buffer:hello myfile!!!
buffer:hello myfile!!!
^C
[user1@iZ5waahoxw3q2bZ zhangsan]$ ldd usercode
	linux-vdso.so.1 =>  (0x00007fff703fb000)
	libmyc.so => /lib64/libmyc.so (0x00007f5e2be59000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f5e2ba8b000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f5e2c05b000)
[user1@iZ5waahoxw3q2bZ zhangsan]$ sudo unlink /lib64/libmyc.so
[user1@iZ5waahoxw3q2bZ zhangsan]$ ll
total 28
drwxrwxr-x 4 user1 user1 4096 May 17 13:12 lib
-rw-rw-r-- 1 user1 user1 3407 May 17 13:15 lib.tgz
-rw-rw-r-- 1 user1 user1   90 May 17 13:28 log.txt
-rwxrwxr-x 1 user1 user1 8808 May 17 13:17 usercode
-rw-rw-r-- 1 user1 user1  579 May 17 11:20 usercode.c
[user1@iZ5waahoxw3q2bZ zhangsan]$ ldd usercode
	linux-vdso.so.1 =>  (0x00007fff30aed000)
	libmyc.so => not found
	libc.so.6 => /lib64/libc.so.6 (0x00007f16a641f000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f16a67ed000)

3.环境变量

[user1@iZ5waahoxw3q2bZ zhangsan]$ echo $LD_LIBRARY_PATH

OS运行程序,要查找动态库,也会在该环境变量下查找动态库(LD_LIBRARY_PATH,经常都是空的)

[user1@iZ5waahoxw3q2bZ zhangsan]$ pwd
/home/user1/linux-learning/linux/26-5-18.2/zhangsan
[user1@iZ5waahoxw3q2bZ zhangsan]$ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/user1/linux-learning/linux/26-5-18.2/zhangsan/lib/mylib
[user1@iZ5waahoxw3q2bZ zhangsan]$ echo ${LD_LIBRARY_PATH}
:/home/user1/linux-learning/linux/26-5-18.2/zhangsan/lib/mylib:/home/user1/linux-learning/linux/26-5-18.2/zhangsan/lib/mylib
[user1@iZ5waahoxw3q2bZ zhangsan]$ ldd usercode
	linux-vdso.so.1 =>  (0x00007fffbd7cb000)
	libmyc.so => /home/user1/linux-learning/linux/26-5-18.2/zhangsan/lib/mylib/libmyc.so (0x00007f940485c000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f940448e000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f9404a5e000)
[user1@iZ5waahoxw3q2bZ zhangsan]$ ./usercode
buffer:hello myfile!!!
buffer:hello myfile!!!
buffer:hello myfile!!!
^C

4.更改系统的配置文件

[user1@iZ5waahoxw3q2bZ zhangsan]$ ls /etc/ld.so.conf
/etc/ld.so.conf
[user1@iZ5waahoxw3q2bZ zhangsan]$ ls /etc/ld.so.conf.d/
bind-export-x86_64.conf  mysql-x86_64.conf  zopenssl.conf
[user1@iZ5waahoxw3q2bZ zhangsan]$ sudo nano /etc/ld.so.conf.d/25-12-14.conf
[user1@iZ5waahoxw3q2bZ zhangsan]$ cat /etc/ld.so.conf.d/25-12-14.conf
/home/user1/linux-learning/xuexi/25-12-9.1/zhangsan/lib/mylib
[user1@iZ5waahoxw3q2bZ zhangsan]$ sudo ldconfig
[user1@iZ5waahoxw3q2bZ zhangsan]$ ldd usercode
    linux-vdso.so.1 (0x00007ffe7ff61000)
    libmyc.so => /home/user1/linux-learning/xuexi/25-12-9.1/zhangsan/lib/mylib/libmyc.so (0x00007f58e25a3000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f58e23bd000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f58e25aa000)
[user1@iZ5waahoxw3q2bZ zhangsan]$ ./usercode
buffer: hello myfile!!!


结论1:动静态库同时存在时,gcc/g++默认使用的是动态库
        非得静态链接,只能带-static。一旦-static,就必须存在对应的静态库

结论2:在Linux系统下,默认情况安装的大部分库,默认都优先安装的是动态库!

结论3: 库:应用程序=1:n

结论4: vs不仅仅形成可执行程序,也能形成静态库
 

感谢你的观看,期待我们下次再见!

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐