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