LINUX下动态库及静态库的学习记录
2013-06-12 15:14
260 查看
1.前言:
动态库是程序运行 的时候才去链接的库,默认链接路径为/lib/目录,规范命名为libxxx.so;静态库为编译可执行档时把需要调用到的函数
体嵌进到可执行程序里面,规范命名为libxxx.a.
2.一个动态库或静态库:
意思是指一个动态或静态库里面只有纯粹的源码生成,库中并没有再链接到其他静态库.下面给出实例:
func1.c
func2.c
Makefile
直接make可以生成libfunc.so和libfunc.a.
测试程序main.c
把libfunc.so和libfunc.a复制到main.c同一目录下,编译main.c:
运行./main报错:
可见,如果编译时同时存在动态库和静态库的时候,gcc优先选择动态库来参与编译.将libfunc.so复制到/lib/目录下,再次运行./main:
以上为动态库参与程序的编译,可知道需要把动态库更新到/lib/目录下.下面对比看一下静态库.先把libfunc.so从main.c的目录下删除.
编译main.c
3.目标动态库链接静态库.
在日常的工作中,常常会遇到这种情况.比如说别人的源码不开放,只提供了一个libxxx.a库.我们的可执行程序先链接到我们自己的库,而我们
自己的库又链接到别人提供的libxxx.a库.比如,上述的libfunc.a假设是别人给的源码.将要生成的libfunc2.so是我们自己的目标库.
下面给出实例:
libfunc.a是由两个源码文件func1.c和func2.c生成.源码见上述.下面再写一个函数去调用func1.c和func2.c里面的函数.如下:
func3.h
测试我们生成的目标动态库libfunc2.so:
4.静态库链接静态库
静态库链接静态库,这边测试没有成功.搜索GOOGLE结果如下:
把func1.o、func2.o复制到我们目标的.a库目录下.Makefile如下:
make生成libfunc2.a
测试结果如下:
动态库是程序运行 的时候才去链接的库,默认链接路径为/lib/目录,规范命名为libxxx.so;静态库为编译可执行档时把需要调用到的函数
体嵌进到可执行程序里面,规范命名为libxxx.a.
2.一个动态库或静态库:
意思是指一个动态或静态库里面只有纯粹的源码生成,库中并没有再链接到其他静态库.下面给出实例:
func1.c
#include <stdio.h> #include <stdlib.h> void func1(void) { printf("######### %s | %d ##########\n",__func__,__LINE__); }
func2.c
clude <stdio.h> #include <stdlib.h> void func2(void) { printf("######## %s | %d ########\n",__func__,__LINE__); }
Makefile
SRCS=$(wildcard *.c) OBJS=$(SRCS:.c=.o) CC=gcc LD=ld AR=ar #LFLAGS+=-I/your_lib_dir/ -lyourlib CFLAGS=-O2 -c -Wall -fpic all:libfunc.so libfunc.a libfunc.so: $(CC) $(CFLAGS) $(SRCS) $(CC) --shared -o $@ $(OBJS) libfunc.a: $(CC) $(CFLAGS) $(SRCS) $(AR) -rcs $@ $(OBJS) %.c:%.o $(CC) -c $< $(CFLAGS) clean: rm -f *.o *.a *.so .PHONY: clean
直接make可以生成libfunc.so和libfunc.a.
测试程序main.c
#include <stdio.h> #include <stdlib.h> int main(int argc,char **argv) { func1(); func2(); return 0; }
把libfunc.so和libfunc.a复制到main.c同一目录下,编译main.c:
gcc main.c -o main -L./ -lfunc
运行./main报错:
root@seven-laptop:~/learn/libforlinux# ./main ./main: error while loading shared libraries: libfunc.so: cannot open shared object file: No such file or directory root@seven-laptop:~/learn/libforlinux#
可见,如果编译时同时存在动态库和静态库的时候,gcc优先选择动态库来参与编译.将libfunc.so复制到/lib/目录下,再次运行./main:
root@seven-laptop:~/learn/libforlinux# ./main ######### func1 | 6 ########## ######## func2 | 6 ######## root@seven-laptop:~/learn/libforlinux#
以上为动态库参与程序的编译,可知道需要把动态库更新到/lib/目录下.下面对比看一下静态库.先把libfunc.so从main.c的目录下删除.
编译main.c
gcc main.c -o main -L./ -lfunc直接运行./main:
root@seven-laptop:~/learn/libforlinux# ./main ######### func1 | 6 ########## ######## func2 | 6 ######## root@seven-laptop:~/learn/libforlinux#由此可见,静态库是作为可执行程序一部分实体链接进可执行程序的.而且静态编译生成的可执行档比动态编译生成的可执行档要大好多.
3.目标动态库链接静态库.
在日常的工作中,常常会遇到这种情况.比如说别人的源码不开放,只提供了一个libxxx.a库.我们的可执行程序先链接到我们自己的库,而我们
自己的库又链接到别人提供的libxxx.a库.比如,上述的libfunc.a假设是别人给的源码.将要生成的libfunc2.so是我们自己的目标库.
下面给出实例:
libfunc.a是由两个源码文件func1.c和func2.c生成.源码见上述.下面再写一个函数去调用func1.c和func2.c里面的函数.如下:
func3.h
ifndef _FUNC3_H_ #define _FUNC3_H_ extern void func1(void); extern void func2(void); #endiffunc3.c
#include <stdio.h> #include <stdlib.h> #include "func3.h" void func3(void) { func1(); func2(); printf("######## %s | %d #######\n",__func__,__LINE__); }注意:上述必须需要声明一下我们在libfunc.a里面调用的函数func1()和func2().否则编译提示下面警告:
func3.c: In function ‘func3’: func3.c:8: warning: implicit declaration of function ‘func1’ func3.c:9: warning: implicit declaration of function ‘func2’Makefile:
SRCS=$(wildcard *.c) OBJS=$(SRCS:.c=.o) CC=gcc LD=ld AR=ar LFLAGS+=-L./ -lfunc CFLAGS=-O2 -c -Wall -fpic OBJTA=*.o all:libfunc2.so libfunc2.a libfunc2.so: $(CC) $(CFLAGS) $(SRCS) $(CC) --shared -o $@ $(OBJS) $(LFLAGS) libfunc2.a: $(CC) $(CFLAGS) $(SRCS) $(AR) -rcs -o $@ $(OBJTA) %.c:%.o $(CC) -c $< $(CFLAGS) clean: rm -f *.o *.so .PHONY: clean注:上述Makefile中通过LFLAGS指定我们要链接进我们目标的动态库的静态库.
测试我们生成的目标动态库libfunc2.so:
root@seven-laptop:~/learn/libforlinux# gcc main2.c -o main2 -L./ -lfunc2 root@seven-laptop:~/learn/libforlinux# ./main2 ./main2: error while loading shared libraries: libfunc2.so: cannot open shared object file: No such file or directory root@seven-laptop:~/learn/libforlinux# cp libfunc2.so /lib/ root@seven-laptop:~/learn/libforlinux# ./main2 ######### func1 | 6 ########## ######## func2 | 6 ######## ######## func3 | 10 #######
4.静态库链接静态库
静态库链接静态库,这边测试没有成功.搜索GOOGLE结果如下:
静态库就是一堆.o,不需要“链接”任何东西,只有可执行文件和共享库(.so库)才需要“链接”.因此,如果把依赖的.o作为元素而不是把.a库作为元素来加工我们的目标静态库.是OK的.
把func1.o、func2.o复制到我们目标的.a库目录下.Makefile如下:
SRCS=$(wildcard *.c) OBJS=$(SRCS:.c=.o) CC=gcc LD=ld AR=ar LFLAGS+=-L./ -lfunc CFLAGS=-O2 -c -Wall -fpic OBJTA=*.o all:libfunc2.so libfunc2.a libfunc2.so: $(CC) $(CFLAGS) $(SRCS) $(CC) --shared -o $@ $(OBJS) $(LFLAGS) libfunc2.a: $(CC) $(CFLAGS) $(SRCS) $(AR) -rcs -o $@ $(OBJTA) %.c:%.o $(CC) -c $< $(CFLAGS) clean: rm -f *.o *.so .PHONY: clean注:这里的OBJTA变量除了func3.o是动态生成之外,还包括了从别处复制过来的func1.o和func2.o.
make生成libfunc2.a
测试结果如下:
root@seven-laptop:~/learn/libforlinux# cp example2/libfunc2.a ./ root@seven-laptop:~/learn/libforlinux# rm -rf /lib/libfu libfunc.so libfuse.so.2 libfuse.so.2.7.2 root@seven-laptop:~/learn/libforlinux# rm -rf /lib/libfu libfunc.so libfuse.so.2 libfuse.so.2.7.2 root@seven-laptop:~/learn/libforlinux# rm -rf main2 root@seven-laptop:~/learn/libforlinux# gcc main2.c -o main2 -L./ -lfunc2 root@seven-laptop:~/learn/libforlinux# ./main2 ######### func1 | 6 ########## ######## func2 | 6 ######## ######## func3 | 10 ####### root@seven-laptop:~/learn/libforlinux#
相关文章推荐
- linux学习——动态库和静态库实例分析
- 静态库/动态库的编译和使用方法学习记录
- linux学习 建立静态库,动态库,写简单的makefile
- 自己在linux上编译、链接、动态库和静态库的学习笔记
- Linux下gcc编译器生成和使用静态库和动态库学习笔记
- linux下编程学习--- 静态库和动态库的编译
- linux学习 建立静态库,动态库,写简单的makefile
- Linux静态库和动态库学习总结
- Linux静态库和动态库学习总结
- Linux学习(十七):动态库与静态库
- 学习笔记: linux下静态库与动态库的生成与调用
- [学习备忘录]Linux平台静态库、动态库的一些笔记
- Linux下gcc编译器生成和使用静态库和动态库学习笔记
- 自己在linux上编译、链接、动态库和静态库的学习笔记
- Linux静态库和动态库学习总结
- Linux学习---静态库 动态库
- 自己在linux上编译、链接、动态库和静态库的学习笔记
- Linux静态库和动态库学习总结
- Linux-----学习静态库,动态库
- linux下静态库和动态库学习