From mboxrd@z Thu Jan 1 00:00:00 1970 From: iyzsong@member.fsf.org (=?utf-8?B?5a6L5paH5q2m?=) Subject: guile-dbi: Use libltdl and prefer GUILE_DBD_PATH. Date: Fri, 16 Sep 2016 11:36:46 +0800 Message-ID: <878tush5wx.fsf_-_@member.fsf.org> References: <87bn2yc3zu.fsf@member.fsf.org> <878ty06ze8.fsf@gnu.org> <8760t36it3.fsf@elisya.g.zucchetti.com> <87mvme8w8k.fsf@gnu.org> <87inx2inou.fsf@member.fsf.org> <87fus6mfbe.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:36456) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bkjxP-00061s-Jl for guix-devel@gnu.org; Thu, 15 Sep 2016 23:36:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bkjxM-0001le-Al for guix-devel@gnu.org; Thu, 15 Sep 2016 23:36:55 -0400 Received: from smtp16.openmailbox.org ([62.4.1.50]:55945 helo=smtp1.openmailbox.org) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bkjxL-0001j8-Uj for guix-devel@gnu.org; Thu, 15 Sep 2016 23:36:52 -0400 In-Reply-To: <87fus6mfbe.fsf@gnu.org> ("Ludovic =?utf-8?Q?Court=C3=A8s=22'?= =?utf-8?Q?s?= message of "Tue, 21 Jun 2016 22:56:21 +0200") List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: "Guix-devel" To: Maurizio Boriani Cc: guix-devel@gnu.org, guile-user@gnu.org --=-=-= Content-Type: text/plain Hi! To reall, curentlly, guile-dbi use dlopen to load its backends. So, for Guix we have to set LD_LIBRARY_PATH, which is not desired. > [...] > (me:) >> I think it will be great to introduce a new search path (eg: GUILE_DBD_PATH) >> in addition to LD_LIBRARY_PATH. Find the absolute so filepath in it >> ourself, then pass to dlopen. > > (ludo:) > Why not, but then it would be redundant with LD_LIBRARY_PATH and > LTDL_LIBRARY_PATH, which would further complicate the search rules. > Yeah, but I just learn that libltdl has a convenient function to do this.. So, here are patches for using libltdl and a new search path: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Use-libltdl-to-dlopen-backends.patch >From 59d529388d062ddad581bcd7f0c56690a84bf7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= Date: Fri, 16 Sep 2016 10:30:36 +0800 Subject: [PATCH 1/3] Use libltdl to dlopen backends. * include/guile-dbi/guile-dbi.h (gdbi_db_handle_t): Use 'lt_dlhandle'. * src/guile-dbi.c: Replace libdl calls with their libltdl equivalences. * Makefile.am (SUBDIRS): Add libltdl. * configure.ac: Use LTDL_INIT. Add LTDLINCL and LIBLTDL to flags. * src/Makefile.am (libguile_dbi_la_LIBDD): Remove '-ldl'. --- guile-dbi/Makefile.am | 2 +- guile-dbi/configure.ac | 8 +++++--- guile-dbi/include/guile-dbi/guile-dbi.h | 3 ++- guile-dbi/src/Makefile.am | 2 +- guile-dbi/src/guile-dbi.c | 25 ++++++++++--------------- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/guile-dbi/Makefile.am b/guile-dbi/Makefile.am index e4cae61..011740b 100644 --- a/guile-dbi/Makefile.am +++ b/guile-dbi/Makefile.am @@ -24,7 +24,7 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = gnu -SUBDIRS = src include doc +SUBDIRS = libltdl src include doc pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = guile-dbi.pc diff --git a/guile-dbi/configure.ac b/guile-dbi/configure.ac index cc45703..d902cb0 100644 --- a/guile-dbi/configure.ac +++ b/guile-dbi/configure.ac @@ -55,14 +55,16 @@ AC_CHECK_FUNCS([strerror]) # ltmain needs these: AC_CONFIG_MACRO_DIR([m4]) -LT_INIT +LT_INIT([dlopen]) +LT_CONFIG_LTDL_DIR([libltdl]) +LTDL_INIT # AC_PROG_INSTALL # AC_PROG_MAKE_SET m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [AC_SUBST([AM_DEFAULT_VERBOSITY],1)]) -CFLAGS=`$GUILECONFIG compile` -LIBS=`$GUILECONFIG link` +CFLAGS="$LTDLINCL `$GUILECONFIG compile`" +LIBS="$LIBLTDL `$GUILECONFIG link`" GUILE_SITE=`$GUILECONFIG info sitedir` AC_ARG_WITH([guile-site-dir], diff --git a/guile-dbi/include/guile-dbi/guile-dbi.h b/guile-dbi/include/guile-dbi/guile-dbi.h index b75d3dc..00449ee 100644 --- a/guile-dbi/include/guile-dbi/guile-dbi.h +++ b/guile-dbi/include/guile-dbi/guile-dbi.h @@ -24,6 +24,7 @@ #define __GUILE_DBI_H__ #include +#include /* guile smob struct */ typedef struct @@ -32,7 +33,7 @@ typedef struct SCM constr; SCM status; /* pair: car = error numeric code, cdr = status message */ SCM closed; /* boolean, TRUE if closed otherwise FALSE */ - void* handle; + lt_dlhandle handle; void* db_info; int in_free; /* boolean, used to avoid alloc during garbage collection */ const char * bcknd_str; diff --git a/guile-dbi/src/Makefile.am b/guile-dbi/src/Makefile.am index a3001db..0795899 100644 --- a/guile-dbi/src/Makefile.am +++ b/guile-dbi/src/Makefile.am @@ -35,7 +35,7 @@ SUFFIXES = .x lib_LTLIBRARIES = libguile-dbi.la libguile_dbi_la_SOURCES = guile-dbi.c guile-dbi.x -libguile_dbi_la_LIBADD = -ldl $(LIBS) +libguile_dbi_la_LIBADD = $(LIBS) libguile_dbi_la_LDFLAGS = -export-dynamic -version-info @DBI_INTERFACE@ libguile_dbi_la_DEPENDENCIES = $(LTLIBOBJS) diff --git a/guile-dbi/src/guile-dbi.c b/guile-dbi/src/guile-dbi.c index 5d797d9..d4ae040 100644 --- a/guile-dbi/src/guile-dbi.c +++ b/guile-dbi/src/guile-dbi.c @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -59,9 +58,8 @@ SCM_DEFINE (make_g_db_handle, "dbi-open", 2, 0, 0, g_db_handle->bcknd_str = scm_to_locale_string (bcknd); g_db_handle->bcknd_strlen = strlen(g_db_handle->bcknd_str); - /* The +20 allos for .so or .dylib on MacOS */ sodbd_len = sizeof(char) * (strlen("libguile-dbd-") + - g_db_handle->bcknd_strlen + 20); + g_db_handle->bcknd_strlen + 1); sodbd = (char*) malloc (sodbd_len); if (sodbd == NULL) { @@ -70,18 +68,14 @@ SCM_DEFINE (make_g_db_handle, "dbi-open", 2, 0, 0, SCM_RETURN_NEWSMOB (g_db_handle_tag, g_db_handle); } -#ifdef __APPLE__ - snprintf(sodbd, sodbd_len, "libguile-dbd-%s.dylib", g_db_handle->bcknd_str); -#else - snprintf(sodbd, sodbd_len, "libguile-dbd-%s.so", g_db_handle->bcknd_str); -#endif + snprintf(sodbd, sodbd_len, "libguile-dbd-%s", g_db_handle->bcknd_str); - g_db_handle->handle = dlopen(sodbd, RTLD_NOW); + g_db_handle->handle = lt_dlopenext(sodbd); if (g_db_handle->handle == NULL) { free(sodbd); g_db_handle->status = scm_cons(scm_from_int(1), - scm_from_locale_string(dlerror())); + scm_from_locale_string(lt_dlerror())); SCM_RETURN_NEWSMOB (g_db_handle_tag, g_db_handle); } @@ -174,7 +168,7 @@ SCM_DEFINE (close_g_db_handle, "dbi-close", 1, 0, 0, (*dbd_close)(g_db_handle); if (g_db_handle->handle) { - dlclose(g_db_handle->handle); + lt_dlclose(g_db_handle->handle); g_db_handle->handle = NULL; } scm_remember_upto_here_1(db_handle); @@ -311,6 +305,7 @@ init_dbi(void) if (is_inited) return; is_inited = 1; init_db_handle_type(); + lt_dlinit(); #ifndef SCM_MAGIC_SNARFER #include "guile-dbi.x" @@ -324,7 +319,7 @@ void __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, const char* function_name, void** function_pointer) { - char *ret = NULL; + const char *ret = NULL; char *func = NULL; size_t func_len; @@ -340,9 +335,9 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, const char* function_name, /* I assume this is correct for all OS'es */ snprintf(func, func_len, "__%s_%s", dbh->bcknd_str, function_name); - dlerror(); /* Clear any existing error -- Solaris needs this */ - *function_pointer = dlsym(dbh->handle, func); - if ((ret = dlerror()) != NULL) + lt_dlerror(); /* Clear any existing error -- Solaris needs this */ + *function_pointer = lt_dlsym(dbh->handle, func); + if ((ret = lt_dlerror()) != NULL) { free(func); if (dbh->in_free) return; /* do not SCM anything while in GC */ -- 2.10.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Prefer-GUILE_DBD_PATH-as-search-path-for-backends.patch >From 495a47aaf79fd501e793562a340a7528ef587144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= Date: Fri, 16 Sep 2016 11:07:59 +0800 Subject: [PATCH 2/3] Prefer GUILE_DBD_PATH as search path for backends. * src/guile-dbi.c (init_dbi): Call 'lt_dlsetsearchpath'. --- guile-dbi/src/guile-dbi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guile-dbi/src/guile-dbi.c b/guile-dbi/src/guile-dbi.c index d4ae040..b609a88 100644 --- a/guile-dbi/src/guile-dbi.c +++ b/guile-dbi/src/guile-dbi.c @@ -25,6 +25,7 @@ #include #include #include +#include static scm_t_bits g_db_handle_tag; @@ -306,6 +307,7 @@ init_dbi(void) is_inited = 1; init_db_handle_type(); lt_dlinit(); + lt_dlsetsearchpath(getenv("GUILE_DBD_PATH")); #ifndef SCM_MAGIC_SNARFER #include "guile-dbi.x" -- 2.10.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-Update-documentation-for-the-usage-of-libltdl.patch >From 1a2fc824fa81324ceb2a310104ea26d0ecd0be4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= Date: Fri, 16 Sep 2016 11:13:29 +0800 Subject: [PATCH 3/3] Update documentation for the usage of libltdl. * doc/guile-dbi.texi: Adjust to the usage of libltdl. --- guile-dbi/doc/guile-dbi.texi | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/guile-dbi/doc/guile-dbi.texi b/guile-dbi/doc/guile-dbi.texi index 4b0015f..02821c0 100644 --- a/guile-dbi/doc/guile-dbi.texi +++ b/guile-dbi/doc/guile-dbi.texi @@ -312,7 +312,7 @@ typedef struct g_db_handle SCM constr; SCM status; /* pair: car = error numeric code, cdr = status message */ SCM closed; /* boolean, TRUE if closed otherwise FALSE */ - void* handle; + lt_dlhandle handle; void* db_info; int in_free; /* boolean, used to avoid alloc during garbage collection */ @} gdbi_db_handle_t; @@ -327,7 +327,7 @@ backend to the dbi interface library. Its car is returns a status code number, cdr is a status return message. @item @code{closed} boolean, @code{#t} if the connection is closed, and @code{#f} otherwise. -@item @code{handle} is a void pointer used to point to dynamically +@item @code{handle} is a lt_dlhandle used to point to dynamically loaded back-end library, filled by dbi-open @code{__gdbi_dbd_wrap}. Set to ``NULL'' at connection close. @item @code{db_info} is a void pointer used by the backends as a data @@ -364,18 +364,21 @@ Used to expose guile-dbi symbols so, scheme can call them. @node How plugins are loaded, How to write plugins, Internal functions, Internals and Database Drivers @section How plugins are loaded -Everything starts at @code{s_make_db_handle}. This function uses dlopen -to load a shared library named ``libguile-dbd-bcknd.so''. bcknd is the -first param of dbi-open. +Everything starts at @code{s_make_db_handle}. This function uses +libltdl to load a shared library named ``libguile-dbd-bcknd'' with the +extension of ``.la'', ``.so'', etc. It's searched in the value of +environment variable @code{GUILE_DBD_PATH} first, then libltdl's +search patch and system library search path. bcknd is the first param +of dbi-open. @* If the shared library is successfully loaded, the dbh's field ``handle'' -is filled with the pointer returned by ``dlopen'' and dbh->status is +is filled with the pointer returned by ``lt_dlopen'' and dbh->status is set. Otherwise the status is set to an error code in the car location, while cdr is filled with an error message returned by @code{strerror}. @* -Once ``dlopen'' is ok, @code{__gdbi_dbd_wrap} is used to call the backend +Once ``lt_dlopen'' is ok, @code{__gdbi_dbd_wrap} is used to call the backend plugin connect function passing it the connection string. If this step also succeeds, then the db should be connected. @sp 1 -- 2.10.0 --=-=-= Content-Type: text/plain Hope they are obvious :-) --=-=-=--