Hi all, I implemented the feature noted in $subject on top of libzdb 2.7 (trunk@380). My initial goal was to produce a nicer package which would not require to install client libraries for database system I don't use. I made the feature optional (disabled by default in configure, new option '--enable-libdl'), and it is lightly tested (test/select still works after the 2 below patches are applied, both with the libdl enabled or not). The only extra-requirement is that the patch uses GCC non-standard "__attribute__ ((constructor))" to not have to modify any user. I didn't even try to implement driver unloading, although it is certainly possible too. Let me know what you think of it. Thanks,
Matthieu
From 234b8f8145872ee6dc02d66e4aa6cd39c5a603b4 Mon Sep 17 00:00:00 2001
From: Matthieu Verbert matthieu.verbert@aitb.org Date: Sat, 6 Nov 2010 13:02:04 +0100 Subject: [PATCH 1/2] Update autotools to support multiple libs and libdl
Create separate variables for each database 'driver', and add them only where they need to be used (Oracle untested). configure's behaviour is unchanged if libdl is not enabled, else multiple libraries will be created. Note that the test program breaks at link time if this option is enabled. --- Makefile.am | 76 +++++++++++++++++++++++++++++++++++++++--------- configure.ac | 90 ++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 117 insertions(+), 49 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 31d92cd..2061c3d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,7 @@ RE2C = @RE2C@ RE2CFLAGS = -b FILTERH = ./tools/bin/filterh
-AM_CPPFLAGS = $(CPPFLAGS) $(DBCPPFLAGS) +AM_CPPFLAGS = INCLUDES = -Isrc -Isrc/util -Isrc/net -Isrc/db -Isrc/exceptions
lib_LTLIBRARIES = libzdb.la @@ -23,29 +23,75 @@ libzdb_la_SOURCES = src/util/Util.c src/util/Str.c src/util/Mem.c \ src/db/Connection.c src/db/ResultSet.c \ src/db/PreparedStatement.c src/util/StringBuffer.c \ src/exceptions/assert.c src/exceptions/Exception.c - if ! WITH_ZILD libzdb_la_SOURCES += src/net/URL.c endif + +libzdb_la_LDFLAGS = +noinst_LTLIBRARIES = +libzdb_la_LIBADD = + +if WITH_LIBDL +libzdb_la_LDFLAGS += -ldl +endif + if WITH_MYSQL -libzdb_la_SOURCES += src/db/mysql/MysqlConnection.c \ - src/db/mysql/MysqlResultSet.c \ - src/db/mysql/MysqlPreparedStatement.c +if WITH_LIBDL +lib_LTLIBRARIES += libzdb-mysql.la +else +noinst_LTLIBRARIES += libzdb-mysql.la +libzdb_la_LIBADD += libzdb-mysql.la endif + +libzdb_mysql_la_SOURCES = src/db/mysql/MysqlConnection.c \ + src/db/mysql/MysqlResultSet.c \ + src/db/mysql/MysqlPreparedStatement.c +libzdb_mysql_la_CPPFLAGS = $(DB_MYSQL_CPPFLAGS) +libzdb_mysql_la_LDFLAGS = $(DB_MYSQL_LDFLAGS) +endif # WITH_MYSQL + if WITH_POSTGRESQL -libzdb_la_SOURCES += src/db/postgresql/PostgresqlConnection.c \ - src/db/postgresql/PostgresqlResultSet.c \ - src/db/postgresql/PostgresqlPreparedStatement.c +if WITH_LIBDL +lib_LTLIBRARIES += libzdb-postgresql.la +else +noinst_LTLIBRARIES += libzdb-postgresql.la +libzdb_la_LIBADD += libzdb-postgresql.la endif +libzdb_postgresql_la_SOURCES = src/db/postgresql/PostgresqlConnection.c \ + src/db/postgresql/PostgresqlResultSet.c \ + src/db/postgresql/PostgresqlPreparedStatement.c +libzdb_postgresql_la_CPPFLAGS = $(DB_POSTGRESQL_CPPFLAGS) +libzdb_postgresql_la_LDFLAGS = $(DB_POSTGRESQL_LDFLAGS) +endif # WITH_POSTGRESQL + if WITH_SQLITE -libzdb_la_SOURCES += src/db/sqlite/SQLiteConnection.c \ - src/db/sqlite/SQLiteResultSet.c \ - src/db/sqlite/SQLitePreparedStatement.c +if WITH_LIBDL +lib_LTLIBRARIES += libzdb-sqlite.la +else +noinst_LTLIBRARIES += libzdb-sqlite.la +libzdb_la_LIBADD += libzdb-sqlite.la endif + +libzdb_sqlite_la_SOURCES = src/db/sqlite/SQLiteConnection.c \ + src/db/sqlite/SQLiteResultSet.c \ + src/db/sqlite/SQLitePreparedStatement.c +libzdb_sqlite_la_CPPFLAGS = $(DB_SQLITE_CPPFLAGS) +libzdb_sqlite_la_LDFLAGS = $(DB_SQLITE_LDFLAGS) +endif # WITH_SQLITE + if WITH_ORACLE -libzdb_la_SOURCES += src/db/oracle/OracleConnection.c \ - src/db/oracle/OracleResultSet.c \ - src/db/oracle/OraclePreparedStatement.c +if WITH_LIBDL +lib_LTLIBRARIES += libzdb-oracle.la +else +noinst_LTLIBRARIES += libzdb-oracle.la +libzdb_la_LIBADD += libzdb-oracle.la +endif + +libzdb_oracle_la_SOURCES = src/db/oracle/OracleConnection.c \ + src/db/oracle/OracleResultSet.c \ + src/db/oracle/OraclePreparedStatement.c +libzdb_oracle_la_CPPFLAGS = $(DB_ORACLE_CPPFLAGS) +libzdb_oracle_la_LDFLAGS = $(DB_ORACLE_LDFLAGS) endif
@@ -55,7 +101,7 @@ API_INTERFACES = src/zdb.h src/db/ConnectionPool.h src/db/Connection.h \
nobase_nodist_include_HEADERS = $(patsubst %, $(LIBRARY_NAME)/%, $(notdir $(API_INTERFACES)))
-libzdb_la_LDFLAGS = $(DBLDFLAGS) -version-info 7:1:0 +AM_LDFLAGS = -version-info 7:1:0
BUILT_SOURCES = $(nobase_nodist_include_HEADERS)
diff --git a/configure.ac b/configure.ac index f771cda..ac51435 100644 --- a/configure.ac +++ b/configure.ac @@ -109,6 +109,18 @@ AC_ARG_ENABLE(profiling, ] )
+AC_ARG_ENABLE(libdl, + AS_HELP_STRING([--enable-libdl], + [Use libdl to dynamic load database drivers]), + [AC_CHECK_LIB([dl], [dlopen], [libdl="yes"], [libdl="no"])], + [libdl="no"] +) +if test "xyes" = "x$libdl"; then + AC_DEFINE([HAVE_LIBDL], 1, [Define to 1 to enable libdl]) +fi + +AM_CONDITIONAL([WITH_LIBDL], test "xyes" = "x$libdl") + AC_ARG_ENABLE([openssl], AS_HELP_STRING([--enable-openssl(=<path>)], [Link libzdb with openssl. If database libraries were linked static, @@ -205,6 +217,7 @@ AC_ARG_WITH([mysql], if test "xyes" = "x$mysql"; then svd_CPPFLAGS=$CPPFLAGS svd_LDFLAGS=$LDFLAGS + svd_LIBS=$LIBS CPPFLAGS="`$MYSQLCONFIG --include` $CPPFLAGS" LDFLAGS="`$MYSQLCONFIG --libs` $LDFLAGS" AC_CHECK_HEADERS([mysql.h]) @@ -226,13 +239,15 @@ if test "xyes" = "x$mysql"; then fi ], [mysql="no"], [-lz]) if test "xyes" = "x$mysql"; then - DBCPPFLAGS="$DBCPPFLAGS `$MYSQLCONFIG --include`" - DBLDFLAGS="$DBLDFLAGS `$MYSQLCONFIG --libs`" + DB_MYSQL_CPPFLAGS="`$MYSQLCONFIG --include`" + DB_MYSQL_LDFLAGS="`$MYSQLCONFIG --libs` -lz" AC_DEFINE([HAVE_LIBMYSQLCLIENT], 1, [Define to 1 to enable mysql]) - else - CPPFLAGS=$svd_CPPFLAGS - LDFLAGS=$svd_LDFLAGS + AC_SUBST(DB_MYSQL_LDFLAGS) + AC_SUBST(DB_MYSQL_CPPFLAGS) fi + CPPFLAGS=$svd_CPPFLAGS + LDFLAGS=$svd_LDFLAGS + LIBS=$svd_LIBS fi AM_CONDITIONAL([WITH_MYSQL], test "xyes" = "x$mysql")
@@ -273,13 +288,14 @@ if test "xyes" = "x$postgresql"; then LDFLAGS="-L`$PGCONFIG --libdir` $LDFLAGS" AC_CHECK_HEADERS([libpq-fe.h], [], [postgresql="no"]) if test "xyes" = "x$postgresql"; then - DBCPPFLAGS="$DBCPPFLAGS -I`$PGCONFIG --includedir`" - DBLDFLAGS="$DBLDFLAGS -L`$PGCONFIG --libdir` -lpq" + DB_POSTGRESQL_CPPFLAGS="-I`$PGCONFIG --includedir`" + DB_POSTGRESQL_LDFLAGS="-L`$PGCONFIG --libdir` -lpq" AC_DEFINE([HAVE_LIBPQ], 1, [Define to 1 to enable postgresql]) - else - CPPFLAGS=$svd_CPPFLAGS - LDFLAGS=$svd_LDFLAGS + AC_SUBST(DB_POSTGRESQL_LDFLAGS) + AC_SUBST(DB_POSTGRESQL_CPPFLAGS) fi + CPPFLAGS=$svd_CPPFLAGS + LDFLAGS=$svd_LDFLAGS fi AM_CONDITIONAL([WITH_POSTGRESQL], test "xyes" = "x$postgresql")
@@ -294,51 +310,52 @@ AC_ARG_WITH([sqlite], sqlite="no" else AC_MSG_RESULT([yes]) - svd_LDFLAGS=$LDFLAGS - svd_CPPFLAGS=$CPPFLAGS - LDFLAGS="-L$with_sqlite/lib $LDFLAGS" - CPPFLAGS="-I$with_sqlite/include $CPPFLAGS" - AC_CHECK_HEADERS([sqlite3.h], [ - sqlite="yes" - if test -r "$with_sqlite/lib/libsqlite3.a"; then - DBCPPFLAGS="$DBCPPFLAGS -I$with_sqlite/include" - DBLDFLAGS="$DBLDFLAGS -L$with_sqlite/lib/ -lsqlite3" - else - sqlite="no" - fi - ], [sqlite="no"]) - LDFLAGS=$svd_LDFLAGS - CPPFLAGS=$svd_CPPFLAGS fi ], [ - AC_MSG_RESULT([yes]) - AC_CHECK_LIB([sqlite3], [sqlite3_open], [], [sqlite="no"]) + AC_MSG_RESULT([yes]) ]) + if test "xyes" = "x$sqlite"; then - AC_DEFINE([HAVE_LIBSQLITE3]) + svd_LDFLAGS=$LDFLAGS + svd_CPPFLAGS=$CPPFLAGS + svd_LIBS=$LIBS + CPPFLAGS="-I$with_sqlite/include $CPPFLAGS" + LDFLAGS="-L$with_sqlite/lib $LDFLAGS" + AC_CHECK_HEADERS([sqlite3.h], [sqlite="yes"], [sqlite="no"]) + AC_CHECK_LIB([sqlite3], [sqlite3_open], [], [sqlite="no"]) + if test "xyes" = "x$sqlite"; then + DB_SQLITE_CPPFLAGS="-I$with_sqlite/include" + DB_SQLITE_LDFLAGS="-L$with_sqlite/lib/ -lsqlite3" + AC_SUBST(DB_SQLITE_CPPFLAGS) + AC_SUBST(DB_SQLITE_LDFLAGS) + fi + LDFLAGS=$svd_LDFLAGS + CPPFLAGS=$svd_CPPFLAGS + LIBS=$svd_LIBS fi + AM_CONDITIONAL([WITH_SQLITE], test "xyes" = "x$sqlite")
oracle="yes" AC_MSG_CHECKING(for oracle) AX_LIB_ORACLE_OCI if test -n "$ORACLE_OCI_CFLAGS" -a -n "$ORACLE_OCI_LDFLAGS"; then - DBCPPFLAGS="$DBCPPFLAGS $ORACLE_OCI_CFLAGS" - DBLDFLAGS="$DBLDFLAGS $ORACLE_OCI_LDFLAGS" + DB_ORACLE_CPPFLAGS="$ORACLE_OCI_CFLAGS" + DB_ORACLE_LDFLAGS="$ORACLE_OCI_LDFLAGS" AC_DEFINE([HAVE_ORACLE], 1, [Define to 1 to enable oracle]) + AC_SUBST(DB_ORACLE_CPPFLAGS) + AC_SUBST(DB_ORACLE_LDFLAGS) else oracle="no" fi AM_CONDITIONAL([WITH_ORACLE], test "xyes" = "x$oracle")
# Test if any database system was found -if test "xno" = "x$postgresql" -a "xno" = "x$mysql" -a "xno" = "x$sqlite" -a "xno" = "x$oracle"; then - AC_MSG_ERROR([No available database found or selected. Try configure --help]) +if test "xno" = "x$postgresql" -a "xno" = "x$mysql" -a "xno" = "x$sqlite" -a "xno" = "x$oracle" -a "xno" = "x$libdl" ; then + AC_MSG_ERROR([No available database found or selected, and dynamic loading disabled. Try configure --help]) fi
-AC_SUBST(DBLDFLAGS) -AC_SUBST(DBCPPFLAGS)
# --------------------------------------------------------------------------- # Header files @@ -413,6 +430,11 @@ echo "| Profiling: DISABLED |" else echo "| Profiling: ENABLED |" fi +if test "xno" = "x$libdl"; then +echo "| Dynamically load drivers: DISABLED |" +else +echo "| Dynamically load drivers: ENABLED |" +fi if test "xfalse" = "x$zild_protect"; then echo "| Zild: DISABLED |" else
Before starting work on a new patch it is a good idea to hear with the mailing-list if a new feature is wanted. Libzdb does not include dynamic loading of database libraries by design and there are no plans to add this. I personally very much dislike dynamic loading of libraries in the context of a database library of libzdb's design. Sorry.
Best regards -- Jan-Henrik Haukeland http://tildeslash.com/
On Nov 7, 2010, at 4:46 PM, Matthieu Verbert wrote:
Hi all, I implemented the feature noted in $subject on top of libzdb 2.7 (trunk@380). My initial goal was to produce a nicer package which would not require to install client libraries for database system I don't use. I made the feature optional (disabled by default in configure, new option '--enable-libdl'), and it is lightly tested (test/select still works after the 2 below patches are applied, both with the libdl enabled or not). The only extra-requirement is that the patch uses GCC non-standard "__attribute__ ((constructor))" to not have to modify any user. I didn't even try to implement driver unloading, although it is certainly possible too. Let me know what you think of it. Thanks,
Matthieu
Hi,
Before starting work on a new patch it is a good idea to hear with the
mailing-list if a new feature is wanted.
That was not really work, but more like 'scratch your itch' over a week-end. I would have done it whether people had wanted it or not.
Libzdb does not include dynamic loading of database libraries by design
and there are no plans to add this. I personally very much dislike dynamic loading of libraries in the context of a database library of libzdb's design.
That's fine, it's yours and I didn't expect the patches to be either acceptable or accepted. On the other hand, it's open-source and I'll maintain the patch separately. I can very well live with this situation ;-)
Again, the overall goal is not really to enable dynamic loading of database libraries but rather to allow me to not install _all_ the libraries on the systems where I have no use of them. Distros may be a more interested audience for such things...
Sorry.
Not need to be.
Best regards,
Matthieu