From 9a8bd6aa414673345223b3652de0f19d574d2240 Mon Sep 17 00:00:00 2001 From: gozfree Date: Mon, 17 Sep 2018 01:09:58 +0800 Subject: [PATCH] [libplugin] add --- libplugin/Android.mk | 14 ++++ libplugin/Makefile | 104 ++++++++++++++++++++++++++ libplugin/README.md | 3 + libplugin/libplugin.c | 130 +++++++++++++++++++++++++++++++++ libplugin/libplugin.h | 62 ++++++++++++++++ libplugin/modules/Makefile | 80 ++++++++++++++++++++ libplugin/modules/plugin_ipc.c | 31 ++++++++ libplugin/modules/plugin_log.c | 30 ++++++++ libplugin/modules/plugin_skt.c | 30 ++++++++ libplugin/test_libplugin.c | 80 ++++++++++++++++++++ libplugin/version.sh | 27 +++++++ 11 files changed, 591 insertions(+) create mode 100644 libplugin/Android.mk create mode 100644 libplugin/Makefile create mode 100644 libplugin/README.md create mode 100644 libplugin/libplugin.c create mode 100644 libplugin/libplugin.h create mode 100644 libplugin/modules/Makefile create mode 100644 libplugin/modules/plugin_ipc.c create mode 100644 libplugin/modules/plugin_log.c create mode 100644 libplugin/modules/plugin_skt.c create mode 100644 libplugin/test_libplugin.c create mode 100755 libplugin/version.sh diff --git a/libplugin/Android.mk b/libplugin/Android.mk new file mode 100644 index 00000000..7e97d90e --- /dev/null +++ b/libplugin/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libplugin + +LIBRARIES_DIR := $(LOCAL_PATH)/../ + +LOCAL_C_INCLUDES := $(LOCAL_PATH) + +# Add your application source files here... +LOCAL_SRC_FILES := libplugin.c + +include $(BUILD_SHARED_LIBRARY) diff --git a/libplugin/Makefile b/libplugin/Makefile new file mode 100644 index 00000000..2c2e86a7 --- /dev/null +++ b/libplugin/Makefile @@ -0,0 +1,104 @@ +############################################################################### +# common +############################################################################### +#ARCH: linux/pi/android/ios/ +ARCH ?= linux +CROSS_PREFIX ?= +OUTPUT ?= /usr/local +BUILD_DIR := $(shell pwd)/../build/ +ARCH_INC := $(BUILD_DIR)/$(ARCH).inc +COLOR_INC := $(BUILD_DIR)/color.inc + +ifeq ($(ARCH_INC), $(wildcard $(ARCH_INC))) +include $(ARCH_INC) +endif + +CC = $(CROSS_PREFIX)gcc +CXX = $(CROSS_PREFIX)g++ +LD = $(CROSS_PREFIX)ld +AR = $(CROSS_PREFIX)ar + +ifeq ($(COLOR_INC), $(wildcard $(COLOR_INC))) +include $(COLOR_INC) +else +CC_V = $(CC) +CXX_V = $(CXX) +LD_V = $(LD) +AR_V = $(AR) +CP_V = $(CP) +RM_V = $(RM) +endif + +############################################################################### +# target and object +############################################################################### +LIBNAME = libplugin +VERSION_SH = $(shell pwd)/version.sh $(LIBNAME) +VER = $(shell $(VERSION_SH); awk '/define\ $(LIBNAME)_version/{print $$3}' version.h) +TGT_LIB_H = $(LIBNAME).h +TGT_LIB_A = $(LIBNAME).a +TGT_LIB_SO = $(LIBNAME).so +TGT_LIB_SO_VER = $(TGT_LIB_SO).${VER} +TGT_UNIT_TEST = test_$(LIBNAME) + +OBJS_LIB = $(LIBNAME).o +OBJS_UNIT_TEST = test_$(LIBNAME).o + +############################################################################### +# cflags and ldflags +############################################################################### +CFLAGS := -g -Wall -Werror -fPIC +CFLAGS += $($(ARCH)_CFLAGS) +CFLAGS += -I$(OUTPUT)/include + +SHARED := -shared + +LDFLAGS := $($(ARCH)_LDFLAGS) +LDFLAGS += -pthread -ldl + +############################################################################### +# target +############################################################################### +.PHONY : all clean + +TGT := $(TGT_LIB_A) +TGT += $(TGT_LIB_SO) +TGT += $(TGT_UNIT_TEST) + +OBJS := $(OBJS_LIB) $(OBJS_UNIT_TEST) + +all: $(TGT) + +%.o:%.c + $(CC_V) -c $(CFLAGS) $< -o $@ + +$(TGT_LIB_A): $(OBJS_LIB) + $(AR_V) rcs $@ $^ + +$(TGT_LIB_SO): $(OBJS_LIB) + $(LD_V) -o $@ $^ $(SHARED) + @mv $(TGT_LIB_SO) $(TGT_LIB_SO_VER) + @ln -sf $(TGT_LIB_SO_VER) $(TGT_LIB_SO) + +$(TGT_UNIT_TEST): $(OBJS_UNIT_TEST) $(ANDROID_MAIN_OBJ) + $(CC_V) -o $@ $^ $(TGT_LIB_A) $(LDFLAGS) + +clean: + $(RM_V) -f $(OBJS) + $(RM_V) -f $(TGT) + $(RM_V) -f version.h + $(RM_V) -f $(TGT_LIB_SO)* + $(RM_V) -f $(TGT_LIB_SO_VER) + +install: + $(MAKEDIR_OUTPUT) + $(CP_V) -r $(TGT_LIB_H) $(OUTPUT)/include + $(CP_V) -r $(TGT_LIB_A) $(OUTPUT)/lib + $(CP_V) -r $(TGT_LIB_SO) $(OUTPUT)/lib + $(CP_V) -r $(TGT_LIB_SO_VER) $(OUTPUT)/lib + +uninstall: + $(RM_V) -f $(OUTPUT)/include/$(TGT_LIB_H) + $(RM_V) -f $(OUTPUT)/lib/$(TGT_LIB_A) + $(RM_V) -f $(OUTPUT)/lib/$(TGT_LIB_SO) + $(RM_V) -f $(OUTPUT)/lib/$(TGT_LIB_SO_VER) diff --git a/libplugin/README.md b/libplugin/README.md new file mode 100644 index 00000000..27c23e2a --- /dev/null +++ b/libplugin/README.md @@ -0,0 +1,3 @@ +## libplugin +This is a simple libplugin library. + diff --git a/libplugin/libplugin.c b/libplugin/libplugin.c new file mode 100644 index 00000000..d64d0635 --- /dev/null +++ b/libplugin/libplugin.c @@ -0,0 +1,130 @@ +/****************************************************************************** + * Copyright (C) 2014-2018 Zhifeng Gong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libraries; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ******************************************************************************/ +#include "libplugin.h" +#include +#include +#include +#include +#include + +struct plugin_manager *plugin_manager_create() +{ + struct plugin_manager *pm = CALLOC(1, struct plugin_manager); + if (!pm) { + printf("malloc failed!\n"); + return NULL; + } + INIT_LIST_HEAD(&pm->plugins); + return pm; +} + +void plugin_manager_destroy(struct plugin_manager *pm) +{ + if (!pm) { + return; + } +} + +static void *plugin_get_func(struct plugin *p, const char *name) +{ + if (!p || !name) { + return NULL; + } + struct plugin *q = dlsym(p->handle, name); + if (!q) { + printf("dlsym failed:%s\n", dlerror()); + return NULL; + } + return q; +} + + +struct plugin *plugin_lookup(struct plugin_manager *pm, const char *name) +{ + if (!pm || !name) + return NULL; + + struct list_head* head = NULL; + struct plugin* p = NULL; + + list_for_each(head, &pm->plugins) { + p = list_entry(head, struct plugin, entry); + if (0 == strcmp(p->name, name)) { + return plugin_get_func(p, name); + } + } + + return NULL; +} + +struct plugin *plugin_load(struct plugin_manager *pm, const char *path, const char *name) +{ + struct plugin *sym = NULL; + struct plugin *p = NULL; + void *handle = dlopen(path, RTLD_LAZY); + if (!handle) { + printf("dlopen failed: %s\n", dlerror()); + goto failed; + } + p = plugin_lookup(pm, name); + if (p) { + printf("plugin %s has already loaded!\n", name); + return p; + } + sym = dlsym(handle, name); + if (!sym) { + printf("incompatible plugin, dlsym failed: %s\n", dlerror()); + goto failed; + } + p = CALLOC(1, struct plugin); + if (!p) { + goto failed; + } + p->handle = handle; + p->name = strdup(name); + p->path = strdup(path); + list_add(&p->entry, &pm->plugins); + return p; + +failed: + if (handle) dlclose(handle); + if (p) { + free(p->name); + free(p->path); + free(p); + } + return NULL; +} + +void plugin_unload(struct plugin_manager *pm, const char *name) +{ + struct plugin *p, *tmp; + list_for_each_entry_safe(p, tmp, &pm->plugins, entry) { + dlclose(p->handle); + list_del(&p->entry); + free(p->name); + free(p->path); + free(p); + } +} + +struct plugin *plugin_reload(struct plugin_manager *pm, const char *path, const char *name) +{ + plugin_unload(pm, name); + return plugin_load(pm, path, name); +} diff --git a/libplugin/libplugin.h b/libplugin/libplugin.h new file mode 100644 index 00000000..1e7a3261 --- /dev/null +++ b/libplugin/libplugin.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * Copyright (C) 2014-2018 Zhifeng Gong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libraries; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ******************************************************************************/ +#ifndef LIBPLUGIN_H +#define LIBPLUGIN_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct version { + int major; + int minor; + int patch; +}; + +struct plugin { + char *name; + char *path; + struct version version; + + void *(*open)(void *arg); + void (*close)(void *arg); + void *(*call)(void *arg0, ...); + + void *handle; + struct list_head entry; +}; + +struct plugin_manager { + struct list_head plugins; +}; + +struct plugin_manager *plugin_manager_create(); +void plugin_manager_destroy(struct plugin_manager *); + +struct plugin *plugin_lookup(struct plugin_manager *pm, const char *name); +struct plugin *plugin_load(struct plugin_manager *pm, const char *path, const char *name); +void plugin_unload(struct plugin_manager *pm, const char *name); +struct plugin *plugin_reload(struct plugin_manager *pm, const char *path, const char *name); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libplugin/modules/Makefile b/libplugin/modules/Makefile new file mode 100644 index 00000000..e5a7c573 --- /dev/null +++ b/libplugin/modules/Makefile @@ -0,0 +1,80 @@ +############################################################################### +# common +############################################################################### +#ARCH: linux/pi/android/ios/ +ARCH ?= linux +CROSS_PREFIX ?= +OUTPUT ?= /usr/local +BUILD_DIR := $(shell pwd)/../build/ +ARCH_INC := $(BUILD_DIR)/$(ARCH).inc +COLOR_INC := $(BUILD_DIR)/color.inc + +ifeq ($(ARCH_INC), $(wildcard $(ARCH_INC))) +include $(ARCH_INC) +endif + +CC = $(CROSS_PREFIX)gcc +CXX = $(CROSS_PREFIX)g++ +LD = $(CROSS_PREFIX)ld +AR = $(CROSS_PREFIX)ar + +ifeq ($(COLOR_INC), $(wildcard $(COLOR_INC))) +include $(COLOR_INC) +else +CC_V = $(CC) +CXX_V = $(CXX) +LD_V = $(LD) +AR_V = $(AR) +CP_V = $(CP) +RM_V = $(RM) +endif + +############################################################################### +# target and object +############################################################################### +LIBNAME = libplugin +VERSION_SH = $(shell pwd)/version.sh $(LIBNAME) +VER = $(shell $(VERSION_SH); awk '/define\ $(LIBNAME)_version/{print $$3}' version.h) +TGT_LIB_H = $(LIBNAME).h +TGT_LIB_SO = plugin_log.so plugin_ipc.so plugin_skt.so + +OBJS_LIB = plugin_log.o plugin_skt.o plugin_ipc.o + +############################################################################### +# cflags and ldflags +############################################################################### +CFLAGS := -g -Wall -Werror -fPIC +CFLAGS += $($(ARCH)_CFLAGS) +CFLAGS += -I$(OUTPUT)/include + +SHARED := -shared + +LDFLAGS := $($(ARCH)_LDFLAGS) +LDFLAGS += -pthread -ldl + +############################################################################### +# target +############################################################################### +.PHONY : all clean + +TGT := $(TGT_LIB_SO) + +OBJS := $(OBJS_LIB) + +all: $(TGT) + +%.o:%.c + $(CC_V) -c $(CFLAGS) $< -o $@ + +plugin_log.so: plugin_log.o + $(LD_V) -o $@ $^ $(SHARED) + +plugin_ipc.so: plugin_ipc.o + $(LD_V) -o $@ $^ $(SHARED) + +plugin_skt.so: plugin_skt.o + $(LD_V) -o $@ $^ $(SHARED) +clean: + $(RM_V) -f $(OBJS) + $(RM_V) -f $(TGT) + $(RM_V) -f version.h diff --git a/libplugin/modules/plugin_ipc.c b/libplugin/modules/plugin_ipc.c new file mode 100644 index 00000000..c4d4cefc --- /dev/null +++ b/libplugin/modules/plugin_ipc.c @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright (C) 2014-2018 Zhifeng Gong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libraries; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ******************************************************************************/ + +#include "../libplugin.h" + +static void *ipc_open(void *arg) +{ + printf("ipc_open\n"); + return NULL; +} + +struct plugin plugin_ipc = { + .name = "plugin_ipc", + .version = {1, 0, 0}, + .open = ipc_open, +}; diff --git a/libplugin/modules/plugin_log.c b/libplugin/modules/plugin_log.c new file mode 100644 index 00000000..cf0dd067 --- /dev/null +++ b/libplugin/modules/plugin_log.c @@ -0,0 +1,30 @@ +/****************************************************************************** + * Copyright (C) 2014-2018 Zhifeng Gong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libraries; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ******************************************************************************/ + +#include "../libplugin.h" + +static void *log_open(void *arg) +{ + printf("log_open\n"); + return NULL; +} + +struct plugin plugin_log = { + .name = "plugin_log", + .open = log_open, +}; diff --git a/libplugin/modules/plugin_skt.c b/libplugin/modules/plugin_skt.c new file mode 100644 index 00000000..f3d1d0f0 --- /dev/null +++ b/libplugin/modules/plugin_skt.c @@ -0,0 +1,30 @@ +/****************************************************************************** + * Copyright (C) 2014-2018 Zhifeng Gong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libraries; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ******************************************************************************/ + +#include "../libplugin.h" + +static void *skt_open(void *arg) +{ + printf("skt_open %s\n", (char *)arg); + return NULL; +} + +struct plugin plugin_skt = { + .name = "plugin_skt", + .open = skt_open, +}; diff --git a/libplugin/test_libplugin.c b/libplugin/test_libplugin.c new file mode 100644 index 00000000..dc191f30 --- /dev/null +++ b/libplugin/test_libplugin.c @@ -0,0 +1,80 @@ +/****************************************************************************** + * Copyright (C) 2014-2018 Zhifeng Gong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libraries; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ******************************************************************************/ +#include "libplugin.h" +#include +#include + +struct plugin_info { + char *path; + char *name; +}; + +struct plugin_info p_info[] = { + {"./modules/plugin_log.so", "plugin_log"}, + {"./modules/plugin_ipc.so", "plugin_ipc"}, + {"./modules/plugin_skt.so", "plugin_skt"}, +}; + +#define SIZEOF(array) (sizeof(array)/sizeof(array[0])) +static struct plugin_manager *pm = NULL; +void init() +{ + int i = 0; + struct plugin *p = NULL; + pm = plugin_manager_create(); + if (!pm) { + printf("plugin_manager_create failed!\n"); + return; + } + for (i = 0; i < SIZEOF(p_info); i++) { + p = plugin_load(pm, p_info[i].path, p_info[i].name); + if (!p) { + printf("plugin_load failed!\n"); + return; + } + } +} + +void deinit() +{ + int i = 0; + for (i = 0; i < SIZEOF(p_info); i++) { + plugin_unload(pm, p_info[i].name); + } + plugin_manager_destroy(pm); +} + +void foo() +{ + char *name = "plugin_ipc"; + struct plugin *p = plugin_lookup(pm, name); + if (!p) { + printf("plugin_lookup %s failed!\n", name); + return; + } + p->open(NULL); + printf("name=%s, version=%d,%d,%d\n", p->name, p->version.major, p->version.minor, p->version.patch); +} + +int main(int argc, char **argv) +{ + init(); + foo(); + deinit(); + return 0; +} diff --git a/libplugin/version.sh b/libplugin/version.sh new file mode 100755 index 00000000..e4d37fd8 --- /dev/null +++ b/libplugin/version.sh @@ -0,0 +1,27 @@ +#!/bin/sh +major=0 +minor=1 +patch=0 + +libname=$1 +output=version.h + +LIBNAME=`echo ${libname} | tr 'a-z' 'A-Z'` +export version=${major}.${minor}.${patch} +export buildid=`git log -1 --pretty=format:"git-%cd-%h" --date=short .` +autogen_version_h() +{ +cat > version.h <