Linux —— 动静态库

目录

一,介绍

二,自定义库

生成静态库

生成动态库

三,使用外部库


一,介绍

        使用第三方功能时,可使用库、开源代码,网络功能的调用等;使用动静态库,可提升开发效率及代码的健壮性;一般去掉lib及.之后,剩下的即是库的名字,如libc.so,库名为cso;生成可执行文件有两种方式,动态库对应的是动态链接,静态库对应的是静态链接;另外,一般第三方库动静态库都会提供;

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

动态库(.so,程序在运行时才会链接动态库的代码,多个程序可共享库代码;

  • 与动态库链接的可执行文件仅包含使用到的该库函数入口地址的一个表;
  • 在可执行文件执行前,OS会将外部函数的机器码从磁盘上复制到内存中,即称为动态链接;
  • 使用动态链接的可执行文件会更小,且节省内存和资源;
//linux默认是使用动态链接
[wz@192 dir]$ gcc mytest.c 
[wz@192 dir]$ ldd a.out 
	linux-vdso.so.1 =>  (0x00007ffe4c370000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f9d4776b000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f9d47b39000)
[wz@192 dir]$ file a.out 
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=75504c6771dac83a91a0e25f34e7a0cd138b4190, not stripped
//如缺乏静态库,静态链接时会报错
//应安装静态库yum install glibc-static
[wz@192 dir]$ gcc -o mytest mytest.c -static
[wz@192 dir]$ ldd mytest
	not a dynamic executable
[wz@192 dir]$ file mytest
mytest: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=0488829d00f9538e3adbf29a2e2f712da559810a, not stripped
//静态链接的可执行文件大小明显比动态链接的文件大
[wz@192 dir]$ ll
total 860
-rwxrwxr-x. 1 wz wz   8360 8月  13 05:55 a.out
-rwxrwxr-x. 1 wz wz 861288 8月  13 05:52 mytest
-rw-rw-r--. 1 wz wz     76 8月  13 05:38 mytest.c

二,自定义库

//add.h
#ifndef __ADD_H__
    #define __ADD_H__
        int add(int a, int b);
#endif // __ADD_H__

//add.c
#include "add.h"
int add(int a, int b)
{
    return a + b;
}
//sub.h
#ifndef __SUB_H__
    #define __SUB_H__
        int sub(int a, int b);
#endif // __SUB_H__

//sub.c
#include "sub.h"
int sub(int a, int b)
{
    return a - b;
}
//main.c
#include 
#include "add.h"
#include "sub.h"
int main( void )
{
    int a = 10;
    int b = 20;
    printf("add(10, 20)=%d\n", a, b, add(a, b));
    a = 100;
    b = 20;
    printf("sub(%d,%d)=%d\n", a, b, sub(a, b));
    return 0;
}

生成静态库

//编译生成目标文件
[wz@192 mylib]$ gcc -c add.c -o add.o
[wz@192 mylib]$ gcc -c sub.c -o sub.o
//生成静态库,r(replace),c(create)
[wz@192 mylib]$ ar -rc ./lib/libmymath.a add.o sub.o
//查看静态库中的目录列表
[wz@192 mylib]$ ar -tv ./lib/libmymath.a 
rw-rw-r-- 1000/1000   1240 Aug 13 06:11 2023 add.o
rw-rw-r-- 1000/1000   1240 Aug 13 06:11 2023 sub.o

静态库文件libmymath.a,add.h、sub.h,根据这三个文件即可编译静态链接生成可执行文件,需指定库位置及名称;

//编译静态链接生成可执行文件
[wz@192 mylib]$ gcc main.c -L./lib -lmymath -static
[wz@192 mylib]$ file a.out 
a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=7f0e9ff63abde0c3e75988318b7fb805587f89f2, not stripped
  • -L后跟指定库的路径;
    • 库搜索路径,有-L指定的路径,环境变量指定的路径(LIBRARY_PATH),系统指定的目录(/usr/lib、/usr/local/lib);
  • -l后跟指定库名;

生成动态库

//fPIC,产生位置无关码
[wz@192 mylib]$ gcc -fPIC -c add.c sub.c
//shared,表示生成共享库格式
[wz@192 mylib]$ gcc -shared -o ./lib/libmymath.so *.o
[wz@192 mylib]$ ll ./lib
total 12
-rw-rw-r--. 1 wz wz 2688 8月  13 06:21 libmymath.a
-rwxrwxr-x. 1 wz wz 7936 8月  13 06:32 libmymath.so

静态库文件libmymath.so,add.h、sub.h,根据这三个文件即可编译动态链接生成可执行文件,需指定库位置及名称;但此时运行可执行文件,会报错;

//编译动态链接生成可执行文件
[wz@192 mylib]$ gcc main.c -o main -L./lib -lmymath
[wz@192 mylib]$ file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=3b80e3640e9f5fa39f040d4c84382dd2c3658821, not stripped
[wz@192 mylib]$ ldd main
	linux-vdso.so.1 =>  (0x00007ffedeffe000)
	libmymath.so => not found
	libc.so.6 => /lib64/libc.so.6 (0x00007f0fa374c000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f0fa3b1a000)

运行使用动态库的可执行文件,需设置路径

  • 将.so库文件拷贝到系统共享库路径下,一般是/usr/lib;
  • 更改LD_LIBRARY_PATH;
  • ldconfig配置/etc/ld.so.conf.d/,可保存重启不丢失路径;
[wz@192 mylib]$ echo $LD_LIBRARY_PATH
:/home/wz/.VimForCpp/vim/bundle/YCM.so/el7.x86_64:/home/wz/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
//添加自定义动态库路径
[wz@192 mylib]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wz/Desktop/mylib/lib
[wz@192 mylib]$ echo $LD_LIBRARY_PATH
:/home/wz/.VimForCpp/vim/bundle/YCM.so/el7.x86_64:/home/wz/.VimForCpp/vim/bundle/YCM.so/el7.x86_64:/home/wz/Desktop/mylib/lib
[wz@192 mylib]$ ldd main
	linux-vdso.so.1 =>  (0x00007ffe629f9000)
	libmymath.so => /home/wz/Desktop/mylib/lib/libmymath.so (0x00007f40b97be000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f40b93f0000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f40b99c0000)

三,使用外部库

jsoncpp、boost

你可能感兴趣的:(操作系统,linux)