makefile学习经验(四)----编译生成动态库文件(方式二)
Lunix下生成动态库文件:
之前已经介绍了依靠makefile文件实现可执行文件,下面说下在源文件中指定加载的动态库文件;
一. 源码文件:
datetime.h:
#ifndef __DATETIME_H
#define __DATETIME_H
/* 日期结构 */
typedef struct
{
int year;
int mon;
int day;
}DATETYPE;
/* 时间结构 */
typedef struct
{
char hour;
char min;
char sec;
}TIMETYPE;
/* 函数原型说明 */
#ifdef SHARED
int (*getdate)(DATETYPE *d);
#else
int getdate(DATETYPE *d);
#endif
#ifdef SHARED
int (*gettime)(TIMETYPE *t);
#else
int gettime(TIMETYPE *t);
#endif
#endif
getdate.c:
#include "time.h"
#include "datetime.h"
int getdate(DATETYPE *d)
{
long ti;
struct tm *tm;
time(&ti);
tm=localtime(&ti);
d->year=tm->tm_year+1900;
d->mon=tm->tm_mon+1;
d->day=tm->tm_mday;
}
gettime.c:
#include "time.h"
#include "datetime.h"
int gettime(TIMETYPE *t)
{
long ti;
struct tm *tm;
time(&ti);
tm=localtime(&ti);
t->hour=tm->tm_hour;
t->min=tm->tm_min;
t->sec=tm->tm_sec;
}
dy.c:
#include "stdio.h" /* 包含标准输入输出文件 */
#include "dlfcn.h" /* 包含动态链接功能接口文件 */
#define SOFILE "../lib/libmy.so" /* 指定动态链接库名称 */
#define SHARED /* 定义宏,确认共享,以便引用动态函数 */
#include "datetime.h" /* 包含用户接口文件 */
main()
{
DATETYPE d;
TIMETYPE t;
void *dp;
char *error;
puts("获取当前时间");
dp=dlopen(SOFILE,RTLD_LAZY); /* 打开动态链接库 */
if (dp==NULL) /* 若打开失败则退出 */
{
fputs(dlerror(),stderr);
exit(1);
}
getdate=dlsym(dp,"getdate"); /* 定位取日期函数 */
error=dlerror(); /* 检测错误 */
if (error) /* 若出错则退出 */
{
fputs(error,stderr);
exit(1);
}
getdate(&d); /* 调用此共享函数 */
printf("当前日期: %04d-%02d-%02d\n",d.year,d.mon,d.day);
gettime=dlsym(dp,"gettime"); /* 定位取时间函数 */
error=dlerror(); /* 检测错误 */
if (error) /* 若出错则退出 */
{
fputs(error,stderr);
exit(1);
}
gettime(&t); /* 调用此共享函数 */
printf("当前时间: %02d:%02d:%02d\n",t.hour,t.min,t.sec);
dlclose(dp); /* 关闭共享库 */
exit(0); /* 成功返回 */
}
二.对源文件阐述:
dy.c文件中:
- #include "dlfcn.h" /* 包含动态链接功能接口文件 */
- #define SOFILE "../lib/libmy.so" /* 指定动态链接库名称 */
- dp=dlopen(SOFILE,RTLD_LAZY); /* 打开动态链接库 */
- error=dlerror();
- dlclose(dp); /* 关闭共享库 */
以上是在源文件中链接动态库文件常用命令;
三.Makefile文件:
#*****************************************************************************
# Copyright :
#
# Author : huochangjun
# Date : 2012-08-15
# Version : Demo1
# Description : Demo
#
#****************************************************************************/
SHELL = /bin/sh
LIB_DIR = /cbs/lhbb/hcj/test/lib/
BIN_DIR = /cbs/lhbb/hcj/test/bin/
OBJECT_DIR = /cbs/lhbb/hcj/test/obj/
APP_DIR = /cbs/lhbb/hcj/test/testapp/
$(shell mkdir -p ${LIB_DIR})
$(shell mkdir -p ${BIN_DIR})
$(shell mkdir -p ${OBJECT_DIR})
RM = rm -fr
#****************************************************************************
CC = gcc
SHARED = -shared -o
FPIC = -fPIC -c
RDY = -rdynamic -s
SRC_OBJECT = $(APP_DIR)getdate.c $(APP_DIR)gettime.c
H_OBJECT = $(APP_DIR)datetime.h
OBJECT = getdate.o gettime.o
DY_SRC_OBJECT = $(APP_DIR)dy.c
DY_OBJECT=dy.o
LIB_OBJECT = libmy.so
BIN_OBJECT = dy
#****************************************************************************
.PHONY:all
all:$(LIB_OBJECT) $(BIN_OBJECT)
$(LIB_OBJECT):$(OBJECT)
$(CC) $(OBJECT) $(SHARED) -fPIC -o $(LIB_OBJECT)
mv $(LIB_OBJECT) $(LIB_DIR)
$(OBJECT):$(SRC_OBJECT) $(H_OBJECT)
$(CC) $(FPIC) $(SRC_OBJECT)
$(BIN_OBJECT):$(DY_OBJECT)
$(CC) $(RDY) -o $(BIN_OBJECT) $(OBJECT_DIR)$(DY_OBJECT) -ldl -L$(LIB_DIR) -lmy
mv $(BIN_OBJECT) $(BIN_DIR)
$(DY_OBJECT):$(DY_SRC_OBJECT)
$(CC) -c $(DY_SRC_OBJECT) -o $(DY_OBJECT)
mv $(OBJECT) $(DY_OBJECT) $(OBJECT_DIR)
clean:
$(RM) $(LIB_DIR) $(BIN_DIR) $(OBJECT_DIR)
四.对makefile文件的简单阐述:
基本的变量赋值在生成静态库文件已经介绍了,这边就不再重复了。
和上一篇中加载不同的是,编译的命令不同:
1. $(CC) $(RDY) -o $(BIN_OBJECT) $(OBJECT_DIR)$(DY_OBJECT) -ldl -L$(LIB_DIR) -lmy
---- $(RDY):-rdynamic 指定输出文件为动态链接方式;
–s 指定删除目标文件中的符号表
-ldl 装配程序ld要装载dl函数库;