Linux 动态库与静态库制作

xiaoxiao2021-02-28  72

1、引言

1、Linux下的库 

静态库和共享库(动态库),二者的不同点在于代码被载入的时刻不同。  静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。  共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

2、库存在的意义  库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。  现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。  共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

2、静态库 静态库的后缀是.a,它的产生分两步 Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表 Step 2.ar命令将很多.o转换成.a,成为静态库 动态库的后缀是.so,它由gcc加特定参数编译产生。具体方法参见后文实例。 在 GNU/linux 系统中静态链接文件实际上就是多个 .o 文件的压缩包。假设我们有 cool.h cool.c 和 some.c 文件,要得到静态链接库 libcool.a。首先使用如下指令得到相应的 object 文件 cool.o 和 some.o:

    gcc -c cool.c

    gcc -c some.c

用这种方法生成的 object 文件称为 PDC 即位置相关代码(position-dependence code)。再使用如下指令可以得到静态链接文件 libcool.a:

    ar -r libcool.a cool.o some.o

静态链接库 libcool.a 遵从 GNU/Linux 规定的静态链接库命名规范,必须是”libyour_library_name.a”

3、动态库

在 GNU/Linux 中动态链接文件,必需通过链接器 ld 生成。假设我们有 hot.c other.c 等文件要生成动态链接库 libhot.so 。首先使用如下指令得到相应的 object 文件 hot.o 和 some.o

    gcc -fPIC -c hot.c

    gcc -fPIC -c other.c

参数 -fPIC 指定生成的 object 文件为位置无关代码(position-independence code),只有 PIC 可以被用作生成动态链接库。然后使用如下指令得到动态库:

   ld -Bshared -o libhot.so hot.o other.o

或者可以使用编译器的ld wrapper:

   gcc -shared -o libhot.so hot.o other.o

也可以使用编译器直接生成动态库:

  gcc -fPIC -shared -o libhot.so hot.c other.c

这里选项 -shared 指示目标文件的类型是动态链接库,动态库的命名规范是”libyour_library_name.so”

ldd  命令可以查看一个可执行程序依赖的共享库,  例如# ldd /bin/lnlibc.so.6  => /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2  => /lib/ld- linux.so.2 (0×40000000)  可以看到ln命令依赖于libc库和ld-linux库

1、创建动态库

目录/test/ include

lib1.h

#ifndef LIB1_H #define LIB1_H void lib1function(void); void lib1_1function(void); #endiflib2.h

#ifndef LIB2_H #define LIB2_H void lib2function(void); #endif 目录/test/src

lib1.c

#include<stdio.h> #include "lib1.h" void lib1function(void) { printf("lib1function\n"); } void lib1_1function(void) { printf("lib1_1function\n"); }lib2.c

#include<stdio.h> #include "lib2.h" void lib2function(void) { printf("lib2function\n"); }makefile CC=gcc CXX=g++ AR=ar TARGET=libmylib.a DIR=./ INCLUDE=-I../include SRC_C=$(wildcard *.c) SRC_CPP=$(wildcard *.cpp) DIR_C=$(notdir $(SRC_C)) DIR_CPP=$(notdir $(SRC_CPP)) OBJ_C=$(patsubst %.c,%.o,$(DIR_C) ) OBJ_CPP=$(patsubst %.cpp,%.o,$(DIR_CPP) ) all:$(TARGET) mv $(TARGET) ../lib $(TARGET):$(OBJ_C) $(AR) -rs $(TARGET) $(OBJ_C) $(OBJ_CPP) .cpp.o: $(CXX) -c $^ $(INCLUDE) .c.o: $(CC) -c $^ $(INCLUDE) clean: rm -rf *.o *.a

创建目录lib

执行命令  $src#./make

在目录lib下生成libmylib.a

目录/test

main.c

#include<stdio.h> #include "lib1.h" #include "lib2.h" int main(void) { lib1function(); lib1_1function(); lib2function(); return 0; }makefile

CC=gcc CXX=g++ AR=ar TARGET=main DIR=. LIB=-L./lib -lmylib INCLUDE=-I./include SRC_C=$(wildcard *.c) SRC_CPP=$(wildcard *.cpp) DIR_C=$(notdir $(SRC_C)) DIR_CPP=$(notdir $(SRC_CPP)) OBJ_C=$(patsubst %.c,%.o,$(DIR_C) ) OBJ_CPP=$(patsubst %.cpp,%.o,$(DIR_CPP) ) SRC =main.c all:$(TARGET) $(TARGET): $(OBJ_C) $(OBJ_CPP) $(CC) $(OBJ_C) $(LIB) -o $(TARGET) .cpp.o: $(CXX) -c $^ $(INCLUDE) .c.o: $(CC) -c $^ $(INCLUDE) clean: rm -rf *.o $(TARGET) 执行命令 test# ./makefile

结果在test目录下生成main

运行 #./main

# ./main lib1function lib1_1function lib2function

2、创建动态库

修改两个Makefile

目录/test/src

CC=gcc CXX=g++ AR=ar TARGET=libmylib.so DIR=./ INCLUDE=-I../include SRC_C=$(wildcard *.c) SRC_CPP=$(wildcard *.cpp) DIR_C=$(notdir $(SRC_C)) DIR_CPP=$(notdir $(SRC_CPP)) OBJ_C=$(patsubst %.c,%.o,$(DIR_C) ) OBJ_CPP=$(patsubst %.cpp,%.o,$(DIR_CPP) ) all:$(TARGET) mv $(TARGET) ../lib $(TARGET):$(OBJ_C) $(CC) -shared $(OBJ_C) $(OBJ_CPP) -o $(TARGET) .cpp.o: $(CXX) -c -fpic $^ $(INCLUDE) .c.o: $(CC) -c -fpic $^ $(INCLUDE) clean: rm -rf *.o *.a test目录

Makefile

CC=gcc CXX=g++ AR=ar TARGET=main DIR=. LIB=./lib/libmylib.so INCLUDE=-I./include SRC_C=$(wildcard *.c) SRC_CPP=$(wildcard *.cpp) DIR_C=$(notdir $(SRC_C)) DIR_CPP=$(notdir $(SRC_CPP)) OBJ_C=$(patsubst %.c,%.o,$(DIR_C) ) OBJ_CPP=$(patsubst %.cpp,%.o,$(DIR_CPP) ) SRC =main.c all:$(TARGET) $(TARGET): $(OBJ_C) $(OBJ_CPP) $(CC) $(OBJ_C) $(LIB) -o $(TARGET) .cpp.o: $(CXX) -c $^ $(INCLUDE) .c.o: $(CC) -c $^ $(INCLUDE) clean: rm -rf *.o $(TARGET)

转载请注明原文地址: https://www.6miu.com/read-81062.html

最新回复(0)