Linux 动态库与静态库制作

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);
#endif
lib2.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)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值