当前位置: 首页 > 科技观察

《电话号码管理系统》制作成静态库和动态库

时间:2023-03-13 04:22:29 科技观察

1.前言上次写了一篇关于Makefile的文章。《利用Makfile给多文件、多目录C源码建立工程》有很多粉丝的评论。有的fans想详细了解cmake的使用方法,有的fans想知道如何把一些函数编译成动态库或者静态库,然后把库编译进内存。一口君一定要整理一下,这篇文章先讲一下如何把一些函数编译成动态库或者静态库。这就涉及到库的概念。关于库的基础知识,一口君在后面的文章中对相关概念进行了详细的描述。我建议您先阅读以下文章。《Linux库概念,动态库和静态库概念》本文中,一扣君将继续以之前的电话号码管理系统项目为基础,详细讲解如何将本项目中的函数做成动态库和静态库。《从0开始写一个《电话号码管理系统》C入门项目》二、基础知识1)静态库所谓静态库,就是在静态编译时,由编译器查找并链接到指定目录。一旦链接完成,最终的可执行程序包含了库文件中所有有用的信息,包括代码段、数据段等。2)动态库所谓动态库是指应用程序运行时,操作系统根据应用程序的请求,动态查找并加载到指定目录下的内存中,同时需要进行地址重定向。3)库文件命名静态库的名称一般为libxxxx.a,其中xxxx为lib的名称;动态库的名字一般是libxxxx.so.x.y.z,含义如下图:4)制作库文件的常用参数首先需要了解一些参数是用来编译gcc库的,这一点很重要.3、制作静态库的原始文件目录如下:peng@ubuntu:/mnt/hgfs/code/phone3$tree..├──main.c├──phone.c└──phone.h0directories,3个文件其中phone.c包含链表上所有的操作函数phone.h是phone.c中所有函数的原型说明main.c是主程序下面我们将phone.c做成一个静态库。1.将listd.c编译成.o文件peng@ubuntu:/mnt/hgfs/code/phone3$gcc-cphone.c2.使用ar命令生成静态库libadd.a静态库名跟在static后面库命名规则lib+Name+.apeng@ubuntu:/mnt/hgfs/code/phone3$ar-rclibphone.aphone.o3。将库和头文件复制到其他目录,将库文件移动到lib目录下peng@ubuntu:/mnt/hgfs/code/phone3$mkdirlibpeng@ubuntu:/mnt/hgfs/code/phone3$mvlibphone.alib文件到包含目录peng@ubuntu:/mnt/hgfs/code/phone3$mkdirincludepeng@ubuntu:/mnt/hgfs/code/phone3$mvphone.hinclude/deletephone.cpeng@ubuntu:/mnt/hgfs/code/phone3$rmphone.c这里不能删除,下面的编译就不用了。删除这个文件只是为了排除干扰,有些同学会认为这个文件会被编译成最终的文件结构如下:peng@ubuntu:/mnt/hgfs/code/phone3$tree././├──include│└──phone.h├──lib│└──libphone.a├──main.c└──run2目录,6fileslibinclude目录也可以是其他目录,实际工程中的库文件和头文件会放在某个指定目录下4.编译值编译main.c,会出现如下错误信息,主要是因为phone.hpeng@ubuntu:/mnt/hgfs/code/phone3$gccmain.cmain.c:3:19:致命错误:phone.h:没有这样的文件或目录编译中断。指定头文件位置,编译结果如下,可以看到错误信息,“createisnotdefined”,这是因为链接peng@ubuntu:/mnt/hgfs时找不到这些函数的定义/code/phone3$gccmain.c-I./include/tmp/cctUUKm9.o:Infunction`management':main.c:(.text+0x109):undefinedreferenceto`create'main.c:(.text+0x120):undefinedreferenceto`delete'main.c:(.text+0x137):undefinedreferenceto`search'main.c:(.text+0x14e):undefinedreferenceto`display'main.c:(.text+0x167):undefinedreferenceto`allfree'/tmp/cctUUKm9.o:Infunction`main':main.c:(.text+0x2e3):undefinedreferenceto`init'collect2:ldreturns1最后我们执行peng@ubuntu:/mnt/hgfs/code/phone3$gccmain。c-I./include./lib/libphone.a指定头文件和库文件所在位置,执行结果如下:现象同前。可见,在使用库的时候,我们必须指定头文件目录和库目录。4.制作动态库原文件peng@ubuntu:/mnt/hgfs/code/phone3$tree..├──main.c├──phone.c└──phone.h0directories,3files1。将phone.c编译成动态链接库libphone.sogcc-fPIC-olibphone.o-cphone.cgcc-shared-olibphone.solibphone.o也可以直接使用命令gcc-fPIC-shared-olibphone.sophone.c2。动态库的安装一般是复制动态库到/lib:peng@ubuntu:/mnt/hgfs/code/phone4$sudomvlibphone.so/lib/[sudo]passwordforpeng:deletephone.cpeng@ubuntu:/mnt/hgfs/code/phone3$rmphone.c3。Compile执行并编译动态库:peng@ubuntu:/mnt/hgfs/code/phone4$gccmain.c-lphone-orun使用我们此时制作的动态库,只需加上-lphone即可观察动态库名称编译时与库文件libphone.so的对应关系<-------->-lphone执行结果如下:5.重新建立工程接下来我们将文件重新放置在当前文件目录如下:./include└──phone.h./Makefile./obj└──Makefile./src├──main.c└──Makefile0directories,5filesandadd3Makefiles编译步骤如下:声明环境变量CC编译名LIBS动态库SUBDIRS子目录OBJSsrc下所有目标文件BIN最后生成的可执行程序的名称OBJS_DIR目标文件存放目录BIN_DIR可执行程序存放目录执行make的默认目标全部,依赖CHECK_DIR$(SUBDIRS)执行目标CHECK_DIR,创建目录bin执行目标@,进入sub执行子目录src和obj下的Makefile,并打印语句echobegincompilephone!进入子目录src执行Makfile,执行命令@$(CC)-cmain.c-I../include-o../$(OBJS_DIR)/main.o@:打印这个命令-I../include头文件在上层目录的include-o../$(OBJS_DIR)/main.o生成的目标文件存放在../obj/main.o进入子目录obj执行Makfile,目标为../bin/phone:main.o执行命令@$(CC)-o$@$^$(LIBS)@$(CC)同上$@表示生成的目标文件,即../bin/phone$^表示所有依赖文件,即上面:目标文件main.o编译后,会得到一个可执行程序文件phone在bin目录下创建,运行结果如下:本文转载自微信公众号《一口Linux》