From 708a9a47756fb7da8b6755e207d93bf09405821b Mon Sep 17 00:00:00 2001 From: Geert Janssens Date: Mon, 7 Aug 2017 11:37:53 +0200 Subject: [PATCH] Make all backend loading use the same build environment module path resolution This obsoletes some cmake hacks --- CMakeLists.txt | 6 +-- src/backend/dbi/CMakeLists.txt | 17 ------ src/backend/dbi/test/Makefile.am | 1 + src/backend/dbi/test/test-backend-dbi.cpp | 11 ++-- src/backend/sql/test/test-column-types.cpp | 4 -- src/backend/xml/CMakeLists.txt | 19 ------- src/backend/xml/test/test-load-backend.cpp | 4 +- src/backend/xml/test/test-load-xml2.cpp | 4 +- src/cmake_modules/GncAddTest.cmake | 5 +- src/engine/CMakeLists.txt | 19 +++---- src/engine/gnc-engine.c | 37 +------------ src/engine/gnc-engine.h | 10 ++-- src/engine/qof-backend.cpp | 60 +++++++++++++++++++--- src/import-export/aqb/test/Makefile.am | 3 +- src/import-export/aqb/test/test-aqb.c | 5 +- 15 files changed, 88 insertions(+), 117 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8ace797ed..cc02ebb035 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -527,12 +527,8 @@ ADD_CUSTOM_TARGET(check scm-test-core scm-test-report-system scm-standard-reports-2 scm-test-standard-reports foo gncmodfoo baz gncmodbaz 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 AUTHORS diff --git a/src/backend/dbi/CMakeLists.txt b/src/backend/dbi/CMakeLists.txt index e7432a2d3e..f8028bd81a 100644 --- a/src/backend/dbi/CMakeLists.txt +++ b/src/backend/dbi/CMakeLists.txt @@ -45,20 +45,3 @@ INSTALL(TARGETS gncmod-backend-dbi ARCHIVE DESTINATION lib/gnucash RUNTIME DESTINATION bin) # 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 $ ${_LINK_TARGET} - DEPENDS gnc-backend-dbi - ) - - ADD_CUSTOM_TARGET(gncmod-backend-dbi-link ALL DEPENDS gncmod-backend-dbi ${_LINK_TARGET}) -ENDIF() diff --git a/src/backend/dbi/test/Makefile.am b/src/backend/dbi/test/Makefile.am index 15e48fcffc..13e52cb8fd 100644 --- a/src/backend/dbi/test/Makefile.am +++ b/src/backend/dbi/test/Makefile.am @@ -35,6 +35,7 @@ GNC_TEST_DEPS = \ --library-dir ${top_builddir}/src/backend/xml TESTS_ENVIRONMENT = \ + GNC_BUILDDIR=${abs_top_builddir} \ GNC_ACCOUNT_PATH=${top_srcdir}/accounts/C \ SRCDIR=${srcdir} \ ${gnc_dbd_dir_override} \ diff --git a/src/backend/dbi/test/test-backend-dbi.cpp b/src/backend/dbi/test/test-backend-dbi.cpp index 6bf67856f3..4936ed06ac 100644 --- a/src/backend/dbi/test/test-backend-dbi.cpp +++ b/src/backend/dbi/test/test-backend-dbi.cpp @@ -29,20 +29,23 @@ extern "C" } 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 main (int argc, char* argv[]) { + g_setenv ("GNC_UNINSTALLED", "1", TRUE); qof_init (); /* equally initializes gobject system */ qof_log_init_filename_special ("stderr"); /* Init the log system */ 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 */ cashobjects_register (); - g_assert (qof_load_backend_library ("../.libs/", GNC_LIB_NAME)); - g_assert (qof_load_backend_library ("../../xml/.libs", - "gncmod-backend-xml")); + g_assert (qof_load_backend_library (GNC_LIB_REL_PATH_1, GNC_LIB_NAME_1)); + g_assert (qof_load_backend_library (GNC_LIB_REL_PATH_2, GNC_LIB_NAME_2)); test_suite_gnc_backend_dbi (); diff --git a/src/backend/sql/test/test-column-types.cpp b/src/backend/sql/test/test-column-types.cpp index b8f9b5302e..ce92fb82b2 100644 --- a/src/backend/sql/test/test-column-types.cpp +++ b/src/backend/sql/test/test-column-types.cpp @@ -38,10 +38,6 @@ int main (int argc, char** argv) { qof_init (); cashobjects_register (); - /* do_test( - qof_load_backend_library ("../.libs/", GNC_LIB_NAME), - " loading gnc-backend-gda GModule failed"); - */ print_test_results (); qof_close (); exit (get_rv ()); diff --git a/src/backend/xml/CMakeLists.txt b/src/backend/xml/CMakeLists.txt index e238f1ed32..fa10ebdd59 100644 --- a/src/backend/xml/CMakeLists.txt +++ b/src/backend/xml/CMakeLists.txt @@ -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 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) - -# ---- - -# 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 $ ${_LINK_TARGET} - DEPENDS gnc-backend-xml-utils - ) - - ADD_CUSTOM_TARGET(gncmod-backend-xml-link ALL DEPENDS gncmod-backend-xml ${_LINK_TARGET}) -ENDIF() diff --git a/src/backend/xml/test/test-load-backend.cpp b/src/backend/xml/test/test-load-backend.cpp index b89174360b..30dde8a2f8 100644 --- a/src/backend/xml/test/test-load-backend.cpp +++ b/src/backend/xml/test/test-load-backend.cpp @@ -33,13 +33,15 @@ extern "C" } #define GNC_LIB_NAME "gncmod-backend-xml" +#define GNC_LIB_REL_PATH "xml" int main (int argc, char** argv) { + g_setenv ("GNC_UNINSTALLED", "1", TRUE); qof_init (); cashobjects_register (); 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"); print_test_results (); qof_close (); diff --git a/src/backend/xml/test/test-load-xml2.cpp b/src/backend/xml/test/test-load-xml2.cpp index 9d0ce80266..08eb170c00 100644 --- a/src/backend/xml/test/test-load-xml2.cpp +++ b/src/backend/xml/test/test-load-xml2.cpp @@ -55,6 +55,7 @@ extern "C" #include "test-file-stuff.h" #define GNC_LIB_NAME "gncmod-backend-xml" +#define GNC_LIB_REL_PATH "xml" static void remove_files_pattern (const char* begining, const char* ending) @@ -120,13 +121,14 @@ test_load_file (const char* filename) int main (int argc, char** argv) { + g_setenv ("GNC_UNINSTALLED", "1", TRUE); const char* location = g_getenv ("GNC_TEST_FILES"); int files_tested = 0; GDir* xml2_dir; qof_init (); 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"); if (!location) diff --git a/src/cmake_modules/GncAddTest.cmake b/src/cmake_modules/GncAddTest.cmake index b76fd8e447..fc8771468c 100644 --- a/src/cmake_modules/GncAddTest.cmake +++ b/src/cmake_modules/GncAddTest.cmake @@ -76,14 +76,15 @@ FUNCTION(GNC_ADD_TEST _TARGET _SOURCE_FILES TEST_INCLUDE_VAR_NAME TEST_LIBS_VAR_ IF (${HAVE_ENV_VARS}) SET(CMAKE_COMMAND_TMP "") 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() ADD_TEST(${_TARGET} ${CMAKE_COMMAND_TMP} ${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() ADD_TEST(NAME ${_TARGET} COMMAND ${_TARGET}) + SET_TESTS_PROPERTIES(${_TARGET} PROPERTIES ENVIRONMENT "GNC_BUILDDIR=${CMAKE_BINARY_DIR}") ENDIF() ADD_DEPENDENCIES(check ${_TARGET}) ENDFUNCTION() diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index b325b02c5c..c47c102a1f 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -269,23 +269,18 @@ SET (engine_SCHEME_1 engine-utilities.scm gnc-numeric.scm ) -IF (NOT 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) +IF (WIN32) ADD_DEFINITIONS (-DOS_WIN32) SET (engine_SOURCES ${engine_SOURCES} qof-win32.cpp ../../lib/libc/strptime.c ) - SET(BACKEND_DEPENDS gncmod-backend-xml) - IF (WITH_SQL) - LIST(APPEND BACKEND_DEPENDS gncmod-backend-dbi) - ENDIF(WITH_SQL) -ENDIF (NOT WIN32) +ENDIF (WIN32) + +SET(BACKEND_DEPENDS gncmod-backend-xml) +IF (WITH_SQL) + LIST(APPEND BACKEND_DEPENDS gncmod-backend-dbi) +ENDIF(WITH_SQL) SET(GUILE_MODULES "") SET(GUILE_LOAD_DIRS src/gnc-module) diff --git a/src/engine/gnc-engine.c b/src/engine/gnc-engine.c index fd6bf11939..0cb344d63d 100644 --- a/src/engine/gnc-engine.c +++ b/src/engine/gnc-engine.c @@ -66,11 +66,6 @@ gnc_engine_init_part1() static void gnc_engine_init_part2() { - gchar *pkglibdir; - const gchar *builddir = g_getenv ("GNC_BUILDDIR"); - gboolean uninstalled = (g_getenv ("GNC_UNINSTALLED") != NULL - && builddir != NULL); - static struct { const gchar* subdir; @@ -85,50 +80,22 @@ gnc_engine_init_part2() { NULL, FALSE } }, *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++) { - gchar *libdir; - 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)) + if (qof_load_backend_library(lib->subdir, lib->lib)) { engine_is_initialized = 1; } 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 (lib->required) { g_critical("required library %s not found.\n", lib->lib); } } - if (uninstalled) - g_free (libdir); } - g_free (pkglibdir); } static void diff --git a/src/engine/gnc-engine.h b/src/engine/gnc-engine.h index 4522e1eb50..f8f1c986ef 100644 --- a/src/engine/gnc-engine.h +++ b/src/engine/gnc-engine.h @@ -220,19 +220,15 @@ typedef void (* gnc_engine_init_hook_t)(int, char **); /** PROTOTYPES ******************************************************/ /** gnc_engine_init should be called before gnc engine - * functions can be used - see also ::qof_init for a - * method that does not require Guile. */ + * functions can be used. */ void gnc_engine_init(int argc, char ** argv); /** This is the statically linked-in version of gnc_engine_init. It is - * identically to that function except that it doesn't load the - * loadable shared module, which means this function will not load the - * "(gnucash engine)" scheme module. + * identical to that function except that it doesn't load any backend library. */ void gnc_engine_init_static(int argc, char ** argv); -/** Called to shutdown the engine, see also ::qof_close - * for use without Guile. */ +/** Called to shutdown the engine. */ void gnc_engine_shutdown (void); /** check the engine is fully initialized */ diff --git a/src/engine/qof-backend.cpp b/src/engine/qof-backend.cpp index e779fc0089..24f58a9d62 100644 --- a/src/engine/qof-backend.cpp +++ b/src/engine/qof-backend.cpp @@ -27,6 +27,7 @@ extern "C" #include #include "qof.h" +#include } #include @@ -81,6 +82,48 @@ QofBackend::get_message () 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 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."); 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 */ 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); - g_free (fullpath); - fullpath = g_build_filename (directory, modname, NULL); - g_free (modname); + auto modname = g_strdup_printf ("lib%s.dylib", module_name); + g_free (fullpath); + fullpath = g_build_filename (directory, modname, NULL); + g_free (modname); } auto backend = g_module_open (fullpath, G_MODULE_BIND_LAZY); g_free (fullpath); diff --git a/src/import-export/aqb/test/Makefile.am b/src/import-export/aqb/test/Makefile.am index be4a096ede..e2abe129c6 100644 --- a/src/import-export/aqb/test/Makefile.am +++ b/src/import-export/aqb/test/Makefile.am @@ -61,7 +61,8 @@ test_aqb_CFLAGS = \ ${GLIB_CFLAGS} \ ${AQBANKING_CFLAGS} -TESTS_ENVIRONMENT = \ + TESTS_ENVIRONMENT = \ + GNC_BUILDDIR=${abs_top_builddir} \ SRCDIR=${srcdir} \ G_DEBUG= diff --git a/src/import-export/aqb/test/test-aqb.c b/src/import-export/aqb/test/test-aqb.c index aef78b34ef..95c8860de8 100644 --- a/src/import-export/aqb/test/test-aqb.c +++ b/src/import-export/aqb/test/test-aqb.c @@ -37,6 +37,7 @@ int main (int argc, char *argv[]) { + g_setenv ("GNC_UNINSTALLED", "1", TRUE); qof_init(); /* Initialize the GObject system */ qof_log_init_filename_special("stderr"); /* Init the log system */ g_test_init ( &argc, &argv, NULL ); /* initialize test program */ @@ -46,9 +47,7 @@ main (int argc, xaccLogDisable(); gnc_module_system_init(); - gnc_engine_init_static(argc, argv); - qof_load_backend_library ("../../../backend/xml/.libs/", - "gncmod-backend-xml"); + gnc_engine_init(argc, argv); /* Add test functions and suites. See * http://library.gnome.org/devel/glib/stable/glib-Testing.html for