Make all backend loading use the same build environment module path resolution

This obsoletes some cmake hacks
This commit is contained in:
Geert Janssens 2017-08-07 11:37:53 +02:00
parent 8687dfb1da
commit 708a9a4775
15 changed files with 88 additions and 117 deletions

View File

@ -527,12 +527,8 @@ ADD_CUSTOM_TARGET(check
scm-test-core scm-test-report-system scm-standard-reports-2 scm-test-core scm-test-report-system scm-standard-reports-2
scm-test-standard-reports foo gncmodfoo baz gncmodbaz scm-test-standard-reports foo gncmodfoo baz gncmodbaz
bar gncmodbar gncmod_agedver gncmod_incompatdep bar gncmodbar gncmod_agedver gncmod_incompatdep
gncmod_futuremodsys check-po test-core-guile gncmod_futuremodsys check-po test-core-guile gncmod-backend-xml
) )
IF (NOT WIN32)
ADD_DEPENDENCIES(check gncmod-backend-xml-link)
ENDIF()
SET(gnucash_DOCS SET(gnucash_DOCS
AUTHORS AUTHORS

View File

@ -45,20 +45,3 @@ INSTALL(TARGETS gncmod-backend-dbi
ARCHIVE DESTINATION lib/gnucash ARCHIVE DESTINATION lib/gnucash
RUNTIME DESTINATION bin) RUNTIME DESTINATION bin)
# No headers to install # No headers to install
# FIXME: Below is a hack to create .libs/libgncmod-backend-dbi to silence some complaints
# from guile when compiling. Eventually, fix the guile module loader to not expect items
# to be in .libs. At this time, WIN32 does not use guile-2, so no need for this.
IF (NOT WIN32)
SET(_LINK_TARGET ${CMAKE_CURRENT_BINARY_DIR}/.libs/libgncmod-backend-dbi${CMAKE_SHARED_LIBRARY_SUFFIX})
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.libs)
ADD_CUSTOM_COMMAND(
OUTPUT ${_LINK_TARGET}
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:gncmod-backend-dbi> ${_LINK_TARGET}
DEPENDS gnc-backend-dbi
)
ADD_CUSTOM_TARGET(gncmod-backend-dbi-link ALL DEPENDS gncmod-backend-dbi ${_LINK_TARGET})
ENDIF()

View File

@ -35,6 +35,7 @@ GNC_TEST_DEPS = \
--library-dir ${top_builddir}/src/backend/xml --library-dir ${top_builddir}/src/backend/xml
TESTS_ENVIRONMENT = \ TESTS_ENVIRONMENT = \
GNC_BUILDDIR=${abs_top_builddir} \
GNC_ACCOUNT_PATH=${top_srcdir}/accounts/C \ GNC_ACCOUNT_PATH=${top_srcdir}/accounts/C \
SRCDIR=${srcdir} \ SRCDIR=${srcdir} \
${gnc_dbd_dir_override} \ ${gnc_dbd_dir_override} \

View File

@ -29,20 +29,23 @@ extern "C"
} }
extern void test_suite_gnc_backend_dbi (); extern void test_suite_gnc_backend_dbi ();
#define GNC_LIB_NAME "gncmod-backend-dbi" #define GNC_LIB_NAME_1 "gncmod-backend-dbi"
#define GNC_LIB_REL_PATH_1 "dbi"
#define GNC_LIB_NAME_2 "gncmod-backend-xml"
#define GNC_LIB_REL_PATH_2 "xml"
int int
main (int argc, main (int argc,
char* argv[]) char* argv[])
{ {
g_setenv ("GNC_UNINSTALLED", "1", TRUE);
qof_init (); /* equally initializes gobject system */ qof_init (); /* equally initializes gobject system */
qof_log_init_filename_special ("stderr"); /* Init the log system */ qof_log_init_filename_special ("stderr"); /* Init the log system */
g_test_init (&argc, &argv, NULL); /* initialize test program */ g_test_init (&argc, &argv, NULL); /* initialize test program */
g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */ g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */
cashobjects_register (); cashobjects_register ();
g_assert (qof_load_backend_library ("../.libs/", GNC_LIB_NAME)); g_assert (qof_load_backend_library (GNC_LIB_REL_PATH_1, GNC_LIB_NAME_1));
g_assert (qof_load_backend_library ("../../xml/.libs", g_assert (qof_load_backend_library (GNC_LIB_REL_PATH_2, GNC_LIB_NAME_2));
"gncmod-backend-xml"));
test_suite_gnc_backend_dbi (); test_suite_gnc_backend_dbi ();

View File

@ -38,10 +38,6 @@ int main (int argc, char** argv)
{ {
qof_init (); qof_init ();
cashobjects_register (); cashobjects_register ();
/* do_test(
qof_load_backend_library ("../.libs/", GNC_LIB_NAME),
" loading gnc-backend-gda GModule failed");
*/
print_test_results (); print_test_results ();
qof_close (); qof_close ();
exit (get_rv ()); exit (get_rv ());

View File

@ -127,22 +127,3 @@ ADD_LIBRARY(gncmod-backend-xml-utils ${libgncmod_backend_xml_SOURCES})
TARGET_LINK_LIBRARIES(gncmod-backend-xml-utils gnc-backend-xml-utils gncmod-engine TARGET_LINK_LIBRARIES(gncmod-backend-xml-utils gnc-backend-xml-utils gncmod-engine
gnc-core-utils ${LIBXML2_LDFLAGS} ${GLIB2_LDFLAGS} ${ZLIB_LIBRARY}) gnc-core-utils ${LIBXML2_LDFLAGS} ${GLIB2_LDFLAGS} ${ZLIB_LIBRARY})
TARGET_COMPILE_DEFINITIONS (gncmod-backend-xml-utils PRIVATE -DG_LOG_DOMAIN=\"gnc.backend.xml\" -DU_SHOW_CPLUSPLUS_API=0) TARGET_COMPILE_DEFINITIONS (gncmod-backend-xml-utils PRIVATE -DG_LOG_DOMAIN=\"gnc.backend.xml\" -DU_SHOW_CPLUSPLUS_API=0)
# ----
# FIXME: Below is a hack to create .libs/libgncmod-backend-xml to silence some complaints
# from guile when compiling. Eventually, fix the guile module loader to not expect items
# to be in .libs. At this time, WIN32 does not use guile-2, so no need for this.
IF (NOT WIN32)
SET(_LINK_TARGET ${CMAKE_CURRENT_BINARY_DIR}/.libs/libgncmod-backend-xml${CMAKE_SHARED_MODULE_SUFFIX})
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.libs)
ADD_CUSTOM_COMMAND(
OUTPUT ${_LINK_TARGET}
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:gncmod-backend-xml> ${_LINK_TARGET}
DEPENDS gnc-backend-xml-utils
)
ADD_CUSTOM_TARGET(gncmod-backend-xml-link ALL DEPENDS gncmod-backend-xml ${_LINK_TARGET})
ENDIF()

View File

@ -33,13 +33,15 @@ extern "C"
} }
#define GNC_LIB_NAME "gncmod-backend-xml" #define GNC_LIB_NAME "gncmod-backend-xml"
#define GNC_LIB_REL_PATH "xml"
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
g_setenv ("GNC_UNINSTALLED", "1", TRUE);
qof_init (); qof_init ();
cashobjects_register (); cashobjects_register ();
do_test ( do_test (
qof_load_backend_library ("../.libs/", GNC_LIB_NAME), qof_load_backend_library (GNC_LIB_REL_PATH, GNC_LIB_NAME),
" loading gnc-backend-xml GModule failed"); " loading gnc-backend-xml GModule failed");
print_test_results (); print_test_results ();
qof_close (); qof_close ();

View File

@ -55,6 +55,7 @@ extern "C"
#include "test-file-stuff.h" #include "test-file-stuff.h"
#define GNC_LIB_NAME "gncmod-backend-xml" #define GNC_LIB_NAME "gncmod-backend-xml"
#define GNC_LIB_REL_PATH "xml"
static void static void
remove_files_pattern (const char* begining, const char* ending) remove_files_pattern (const char* begining, const char* ending)
@ -120,13 +121,14 @@ test_load_file (const char* filename)
int int
main (int argc, char** argv) main (int argc, char** argv)
{ {
g_setenv ("GNC_UNINSTALLED", "1", TRUE);
const char* location = g_getenv ("GNC_TEST_FILES"); const char* location = g_getenv ("GNC_TEST_FILES");
int files_tested = 0; int files_tested = 0;
GDir* xml2_dir; GDir* xml2_dir;
qof_init (); qof_init ();
cashobjects_register (); cashobjects_register ();
do_test (qof_load_backend_library ("../.libs/", GNC_LIB_NAME), do_test (qof_load_backend_library (GNC_LIB_REL_PATH, GNC_LIB_NAME),
" loading gnc-backend-xml GModule failed"); " loading gnc-backend-xml GModule failed");
if (!location) if (!location)

View File

@ -76,14 +76,15 @@ FUNCTION(GNC_ADD_TEST _TARGET _SOURCE_FILES TEST_INCLUDE_VAR_NAME TEST_LIBS_VAR_
IF (${HAVE_ENV_VARS}) IF (${HAVE_ENV_VARS})
SET(CMAKE_COMMAND_TMP "") SET(CMAKE_COMMAND_TMP "")
IF (${CMAKE_VERSION} VERSION_GREATER 3.1) IF (${CMAKE_VERSION} VERSION_GREATER 3.1)
SET(CMAKE_COMMAND_TMP ${CMAKE_COMMAND} -E env "${ARGN}") SET(CMAKE_COMMAND_TMP ${CMAKE_COMMAND} -E env "GNC_BUILDDIR=${CMAKE_BINARY_DIR};${ARGN}")
ENDIF() ENDIF()
ADD_TEST(${_TARGET} ${CMAKE_COMMAND_TMP} ADD_TEST(${_TARGET} ${CMAKE_COMMAND_TMP}
${CMAKE_BINARY_DIR}/bin/${_TARGET} ${CMAKE_BINARY_DIR}/bin/${_TARGET}
) )
SET_TESTS_PROPERTIES(${_TARGET} PROPERTIES ENVIRONMENT "${ARGN}") SET_TESTS_PROPERTIES(${_TARGET} PROPERTIES ENVIRONMENT "GNC_BUILDDIR=${CMAKE_BINARY_DIR};${ARGN}")
ELSE() ELSE()
ADD_TEST(NAME ${_TARGET} COMMAND ${_TARGET}) ADD_TEST(NAME ${_TARGET} COMMAND ${_TARGET})
SET_TESTS_PROPERTIES(${_TARGET} PROPERTIES ENVIRONMENT "GNC_BUILDDIR=${CMAKE_BINARY_DIR}")
ENDIF() ENDIF()
ADD_DEPENDENCIES(check ${_TARGET}) ADD_DEPENDENCIES(check ${_TARGET})
ENDFUNCTION() ENDFUNCTION()

View File

@ -269,23 +269,18 @@ SET (engine_SCHEME_1
engine-utilities.scm engine-utilities.scm
gnc-numeric.scm gnc-numeric.scm
) )
IF (NOT WIN32) IF (WIN32)
SET(BACKEND_DEPENDS gncmod-backend-xml-link)
IF(WITH_SQL)
LIST(APPEND BACKEND_DEPENDS gncmod-backend-dbi-link)
ENDIF(WITH_SQL)
ELSE (NOT WIN32)
ADD_DEFINITIONS (-DOS_WIN32) ADD_DEFINITIONS (-DOS_WIN32)
SET (engine_SOURCES ${engine_SOURCES} SET (engine_SOURCES ${engine_SOURCES}
qof-win32.cpp qof-win32.cpp
../../lib/libc/strptime.c ../../lib/libc/strptime.c
) )
SET(BACKEND_DEPENDS gncmod-backend-xml) ENDIF (WIN32)
IF (WITH_SQL)
LIST(APPEND BACKEND_DEPENDS gncmod-backend-dbi) SET(BACKEND_DEPENDS gncmod-backend-xml)
ENDIF(WITH_SQL) IF (WITH_SQL)
ENDIF (NOT WIN32) LIST(APPEND BACKEND_DEPENDS gncmod-backend-dbi)
ENDIF(WITH_SQL)
SET(GUILE_MODULES "") SET(GUILE_MODULES "")
SET(GUILE_LOAD_DIRS src/gnc-module) SET(GUILE_LOAD_DIRS src/gnc-module)

View File

@ -66,11 +66,6 @@ gnc_engine_init_part1()
static void static void
gnc_engine_init_part2() gnc_engine_init_part2()
{ {
gchar *pkglibdir;
const gchar *builddir = g_getenv ("GNC_BUILDDIR");
gboolean uninstalled = (g_getenv ("GNC_UNINSTALLED") != NULL
&& builddir != NULL);
static struct static struct
{ {
const gchar* subdir; const gchar* subdir;
@ -85,50 +80,22 @@ gnc_engine_init_part2()
{ NULL, FALSE } { NULL, FALSE }
}, *lib; }, *lib;
if (uninstalled)
#ifdef CMAKE_BUILD
pkglibdir = g_build_path (G_DIR_SEPARATOR_S, builddir, NULL);
#ifdef WIN32
#define LIBDIR "bin"
#else
#define LIBDIR "lib/gnucash"
#endif
#else
pkglibdir = g_build_path (G_DIR_SEPARATOR_S, builddir,
"src", "backend", NULL);
#endif
else
pkglibdir = gnc_path_get_pkglibdir ();
for (lib = libs; lib->lib ; lib++) for (lib = libs; lib->lib ; lib++)
{ {
gchar *libdir; if (qof_load_backend_library(lib->subdir, lib->lib))
if (uninstalled)
#ifdef CMAKE_BUILD
libdir = g_build_path (G_DIR_SEPARATOR_S, pkglibdir, LIBDIR, NULL);
#else
libdir = g_build_path (G_DIR_SEPARATOR_S, pkglibdir,
lib->subdir, ".libs", NULL);
#endif
else
libdir = pkglibdir;
if (qof_load_backend_library(libdir, lib->lib))
{ {
engine_is_initialized = 1; engine_is_initialized = 1;
} }
else else
{ {
g_warning("failed to load %s from %s\n", lib->lib, libdir); g_warning("failed to load %s from relative path %s\n", lib->lib, lib->subdir);
/* If this is a required library, stop now! */ /* If this is a required library, stop now! */
if (lib->required) if (lib->required)
{ {
g_critical("required library %s not found.\n", lib->lib); g_critical("required library %s not found.\n", lib->lib);
} }
} }
if (uninstalled)
g_free (libdir);
} }
g_free (pkglibdir);
} }
static void static void

View File

@ -220,19 +220,15 @@ typedef void (* gnc_engine_init_hook_t)(int, char **);
/** PROTOTYPES ******************************************************/ /** PROTOTYPES ******************************************************/
/** gnc_engine_init should be called before gnc engine /** gnc_engine_init should be called before gnc engine
* functions can be used - see also ::qof_init for a * functions can be used. */
* method that does not require Guile. */
void gnc_engine_init(int argc, char ** argv); void gnc_engine_init(int argc, char ** argv);
/** This is the statically linked-in version of gnc_engine_init. It is /** This is the statically linked-in version of gnc_engine_init. It is
* identically to that function except that it doesn't load the * identical to that function except that it doesn't load any backend library.
* loadable shared module, which means this function will not load the
* "(gnucash engine)" scheme module.
*/ */
void gnc_engine_init_static(int argc, char ** argv); void gnc_engine_init_static(int argc, char ** argv);
/** Called to shutdown the engine, see also ::qof_close /** Called to shutdown the engine. */
* for use without Guile. */
void gnc_engine_shutdown (void); void gnc_engine_shutdown (void);
/** check the engine is fully initialized */ /** check the engine is fully initialized */

View File

@ -27,6 +27,7 @@ extern "C"
#include <config.h> #include <config.h>
#include "qof.h" #include "qof.h"
#include <gnc-path.h>
} }
#include <string> #include <string>
@ -81,6 +82,48 @@ QofBackend::get_message ()
return std::move(m_error_msg); return std::move(m_error_msg);
} }
/* Helper function that return a directory from which the requested module
* can be loaded. This is needed because the location of the modules
* depends on
* - whether we're running in an installed environment or the build environment
* - the operation system
* - (in the build environment) which build system is used
*
* Note parameter rel_path is only used when invoked in the build environment
* because each backend module is likely to reside in its own directory. At
* install time it is assumed all backend modules reside in one single directory.
*/
static char* get_default_module_dir(const char* rel_path)
{
gchar *pkglibdir;
const gchar *builddir = g_getenv ("GNC_BUILDDIR");
gboolean uninstalled = (g_getenv ("GNC_UNINSTALLED") != NULL
&& builddir != NULL);
if (uninstalled)
{
#ifdef CMAKE_BUILD
#ifdef WIN32
#define LIBDIR "bin"
#else
#define LIBDIR "lib/gnucash"
#endif
pkglibdir = g_build_path (G_DIR_SEPARATOR_S, builddir, LIBDIR, NULL);
#else
if (rel_path)
pkglibdir = g_build_path (G_DIR_SEPARATOR_S, builddir,
"src", "backend", rel_path, ".libs", NULL);
else
pkglibdir = g_build_path (G_DIR_SEPARATOR_S, builddir,
"src", "backend", ".libs", NULL);
#endif
}
else
pkglibdir = gnc_path_get_pkglibdir ();
return pkglibdir;
}
bool bool
QofBackend::register_backend(const char* directory, const char* module_name) QofBackend::register_backend(const char* directory, const char* module_name)
{ {
@ -89,15 +132,20 @@ QofBackend::register_backend(const char* directory, const char* module_name)
PWARN("Modules not supported."); PWARN("Modules not supported.");
return false; return false;
} }
auto fullpath = g_module_build_path (directory, module_name);
auto absdir = g_strdup(directory);
if (!absdir || !g_path_is_absolute(absdir))
absdir = get_default_module_dir(directory);
auto fullpath = g_module_build_path (absdir, module_name);
g_free (absdir);
/* Darwin modules can have either .so or .dylib for a suffix */ /* Darwin modules can have either .so or .dylib for a suffix */
if (!g_file_test (fullpath, G_FILE_TEST_EXISTS) && if (!g_file_test (fullpath, G_FILE_TEST_EXISTS) &&
g_strcmp0 (G_MODULE_SUFFIX, "so") == 0) g_strcmp0 (G_MODULE_SUFFIX, "so") == 0)
{ {
auto modname = g_strdup_printf ("lib%s.dylib", module_name); auto modname = g_strdup_printf ("lib%s.dylib", module_name);
g_free (fullpath); g_free (fullpath);
fullpath = g_build_filename (directory, modname, NULL); fullpath = g_build_filename (directory, modname, NULL);
g_free (modname); g_free (modname);
} }
auto backend = g_module_open (fullpath, G_MODULE_BIND_LAZY); auto backend = g_module_open (fullpath, G_MODULE_BIND_LAZY);
g_free (fullpath); g_free (fullpath);

View File

@ -61,7 +61,8 @@ test_aqb_CFLAGS = \
${GLIB_CFLAGS} \ ${GLIB_CFLAGS} \
${AQBANKING_CFLAGS} ${AQBANKING_CFLAGS}
TESTS_ENVIRONMENT = \ TESTS_ENVIRONMENT = \
GNC_BUILDDIR=${abs_top_builddir} \
SRCDIR=${srcdir} \ SRCDIR=${srcdir} \
G_DEBUG= G_DEBUG=

View File

@ -37,6 +37,7 @@ int
main (int argc, main (int argc,
char *argv[]) char *argv[])
{ {
g_setenv ("GNC_UNINSTALLED", "1", TRUE);
qof_init(); /* Initialize the GObject system */ qof_init(); /* Initialize the GObject system */
qof_log_init_filename_special("stderr"); /* Init the log system */ qof_log_init_filename_special("stderr"); /* Init the log system */
g_test_init ( &argc, &argv, NULL ); /* initialize test program */ g_test_init ( &argc, &argv, NULL ); /* initialize test program */
@ -46,9 +47,7 @@ main (int argc,
xaccLogDisable(); xaccLogDisable();
gnc_module_system_init(); gnc_module_system_init();
gnc_engine_init_static(argc, argv); gnc_engine_init(argc, argv);
qof_load_backend_library ("../../../backend/xml/.libs/",
"gncmod-backend-xml");
/* Add test functions and suites. See /* Add test functions and suites. See
* http://library.gnome.org/devel/glib/stable/glib-Testing.html for * http://library.gnome.org/devel/glib/stable/glib-Testing.html for