目录
一、静态库的实现
1.如何制作静态库,以及静态库的使用
例如我要将llist.c做成静态库
1,输入gcc -c llist.c 生成llist.o文件
2.ar -cr libllist(红色是库名).a llist.o生成libllist.a文件
3.将llist.h移动到/usr/local/include/目录,将libllist.a移动到/usr/local/lib/目录
4这样一来就可以将#include "llist.h" 改成#include <llist.h>
5 运行gcc (-I/usr/local/include/-L/usr/local/lib/可省略当时在这两个目录时) -o main main.c -lllist(-l****,我这里的库名是llist)生成可执行文件main
2.静态库使用案例
我的文件如下(文件的具体的内容在动态库的制作章节,因为我先写的动态库)我这里还是把makefile粘贴过来:
CFLAGS+=-I../te -L../th
LDFLAGS+=
all:main
main:main.c
gcc $(CFLAGS) $^ -o $@ -lh
按照我前面写的先制作静态库:
然后把libh.a 移动到th文件夹。之后make就可以了:
二、动态库的实现
1.如何制作动态库(共享库),以及它的使用
例如我要将下面的程序liststack.c做成动态库
1.输入命令:gcc -shared -fpic -o libliststack.so liststack.c(lib***.so)(***.c)
2.然后将其对应的liststack.h 移动到/usr/local/include/目录,对应的.so 文件移动到/usr/local/lib/目录
3.然后 使用 vim /etc/ld.so.conf 命令打开这个文件在里面加入/usr/local/lib/并保存。
4.使用命令sudo ldconfig -v进行更新。
5.最后输入gcc (***可省,对于这一路径)-o main main.c -lliststack -lllist (-l*****)的到可执行文件main
2.动态库(共享库)使用案例
(如上面所示,有的文件你必须使用root才能修改,但是在最后编译的时候可以不用root。)
我的文件树如图所示
其中main.c如下
#include <h.h>
#include <stdio.h>
int main()
{
print();
return 0;
}
h.h文件如下:
#ifndef H_H
#define H_H
void print(void);
#endif
h.c文件如下:
#include "h.h"
#include <stdio.h>
void print(void)
{
printf("hh\n");
}
makefile如下:
CFLAGS+=-I../te -L../th
LDFLAGS+=
all:main
main:main.c
gcc $(CFLAGS) $^ -o $@ -lh
现在先把h.c 编译成共享库
然后移动到 th 文件夹下。之后按照前面的介绍开始修改。
sudo vim /etc/ld.so.conf
然后sudo ldconfig -v .
最后make即可:
通过ldd命令可以看到 有链接我们的动态库 。
(最近这makefile 可是把我搞得心累,-o 的位置不同,-lh的位置不同,他有可能就错了。,我还是应该在花点时间在研究一下makefile)
三、一个案例
.
├── client
│ ├── client.c
│ ├── client.o
│ └── makefile
├── command
│ ├── download
│ │ ├── download.c
│ │ ├── download.h
│ │ ├── download.o
│ │ └── makefile
│ ├── lsc
│ │ ├── lsf.c
│ │ ├── lsf.h
│ │ ├── makefile
│ │ ├── sls.c
│ │ └── sls.h
│ ├── makedir
│ │ ├── makefile
│ │ ├── mkdirn.c
│ │ ├── mkdirn.h
│ │ ├── mkdirr.c
│ │ └── mkdirr.h
│ ├── remove
│ │ ├── help.txt
│ │ ├── makefile
│ │ ├── optrm.c
│ │ ├── optrm.h
│ │ ├── rmc.c
│ │ ├── rmc.h
│ │ ├── rmi.c
│ │ └── rmi.h
│ ├── removedir
│ │ ├── makefile
│ │ ├── rmd.c
│ │ ├── rmd.h
│ │ ├── rmdi.c
│ │ └── rmdi.h
│ ├── touchc
│ │ ├── makefile
│ │ ├── touchc.c
│ │ ├── touchc.h
│ │ ├── touchs.c
│ │ └── touchs.h
│ └── updown
│ ├── makefile
│ ├── updown.c
│ └── updown.h
├── include
│ ├── client.h
│ ├── command.h
│ ├── dlstring.h
│ ├── errorcode.h
│ ├── make.inc
│ ├── network.h
│ ├── opt.h
│ ├── print.h
│ ├── proto.h
│ └── server.h
├── lib
│ ├── libdownload.a
│ └── libdownload.so
├── libsrc
│ ├── command.c
│ ├── dlstring.c
│ ├── network.c
│ ├── opt.c
│ ├── opt.o
│ ├── print.c
│ └── print.o
├── server
│ └── server.c
└── worklist
我的代码的结构是上面这样的。
以download文件夹为例
make.inc
#makefile 头文件
#定义应用包含的文件路径,MYFTPPATH 是一个环境变量在我这代表/home/jiawen/myftp
INCDIR = $(MYFTPPATH)/include
LIBDIR = $(MYFTPPATH)/lib
#***************定义系统命令**************
CC = cc -std=c99
#定义归档工具命令,这里是ar
AR = ar
CP = cp
RM = rm -rf
MV = mv
#定义链接器命令,这里是ld
LD = ld
MK = mkdir
# 定义lint代码检查工具
LINT = lint
#定义产生静态库目录的命令,这里是ranlib
RANLIB = ranlib
#定义应用包含标志
APPINC = -I$(INCDIR)
CFLAGS = -Wall -c -fPIC -pthread -D__DBG__ -I$(MYFTPPATH)/include
#定义检查标志
LINTFLAGS =
#定义程序编译标志
ECFLAGS = $(CFLAGS)
#定义共享库标志
SOFLAGS = -shared
#定义系统库标志
SYSLFLAGS = -L$(MYFTPPAH)/lib -ldevlog
#定义自定义库的标志,-Wl是gcc编译器的一个选项,用于向链接器ld传递参数。
#-Wl,-rpath=/home/user/lib 向ld传递-rpath=/home/user/lib选项
USERLFLAGS = -Wl -rpaht=$(MYFTPPAH)/lib
#LFLAGS用于指定libraries、库搜索路径等链接相关的选项。
#但是SYSLFLAGS和USERLFLAGS分别定义系统库和用户自定义库
#,而LFLAGS一般用于定义所有类型的链接标志
LFLAGS = $(SYSLFLAGS) $(USERLFLAGS)
makefile
include $(MYFTPPATH)/include/make.inc
SRCS = ${wildcard *.c}
OBJS = ${SRCS:.c=.o}
#分别生成动态和静态库
OBJLIB = libdownload.so
OBJSTA = libdownload.a
all:$(OBJLIB) $(OBJSTA)
#生成共享库
$(OBJLIB):$(OBJS)
$(CC) $(SOFLAGS) $^ -o $@
$(MV) $(OBJLIB) $(LIBDIR)
#生成静态库,注意这里的$@ $^写为$^ $@会有问题
$(OBJSTA):$(OBJS)
$(AR) -cr $@ $^
$(MV) $(OBJSTA) $(LIBDIR)
.c.o:
$(CC) $(ECFLAGS) $(SRCS)
.PHONY:clean
clean:
$(RM) *.o
如上面的树所示,生成了libdownload.so 和libdownload.a
如果你有好的建议或疑问欢迎与我联系qq909244296.