diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b46458674..b712fa4921 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,9 @@ if (GNC_TEXT_PORTS_RESULT EQUAL 0) set (HAVE_TEXT_PORTS TRUE) endif () +# Determine where to install our guile modules libraries. +find_guile_dirs() + # ############################################################ if (WITH_AQBANKING) pkg_check_modules (GWENHYWFAR REQUIRED gwenhywfar>=4.9.99) @@ -770,9 +773,6 @@ add_definitions (-DHAVE_CONFIG_H) set (CONFIG_H ${CMAKE_CURRENT_BINARY_DIR}/common/config.h) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/common/config.h.cmake.in ${CONFIG_H}) -set(SCHEME_INSTALLED_SOURCE_DIR ${CMAKE_INSTALL_DATADIR}/gnucash/scm) -set(SCHEME_INSTALLED_CACHE_DIR ${PKGLIBDIR}/scm/ccache/${GUILE_EFFECTIVE_VERSION}) - # The subdirectories add_subdirectory (borrowed) add_subdirectory (data) diff --git a/common/cmake_modules/GncAddSchemeTargets.cmake b/common/cmake_modules/GncAddSchemeTargets.cmake index 1b72aadae3..5d61086d41 100644 --- a/common/cmake_modules/GncAddSchemeTargets.cmake +++ b/common/cmake_modules/GncAddSchemeTargets.cmake @@ -13,7 +13,7 @@ # 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 # Boston, MA 02110-1301, USA gnu@gnu.org -#Guile and ltdl require MSYS paths on MinGW-w64; this function transforms them. +# Guile and ltdl require MSYS paths on MinGW-w64; this function transforms them. function(make_unix_path PATH) string(REGEX REPLACE "^([A-Za-z]):" "/\\1" newpath ${${PATH}}) string(REGEX REPLACE "\\\\" "/" newpath ${newpath}) @@ -26,6 +26,82 @@ function(make_unix_path_list PATH) set(${PATH} ${newpath} PARENT_SCOPE) endfunction() +# This function will set two or four environment variables to a directory in the parent PARENT_SCOPE +# * _DIRCLASS (eg "prefix", "sitedir" is used to construct the variable name(s) and in error messages +# * _DIRCMD is the guile command to run to get the path for the given _DIRCLASS (eg "(display (%site-dir))") +# * _PREFIX: if set will be used to calculate paths relative to this prefix and +# set two more environment variable with this relative path. +# When run successfully this function will set following variables in the parent scope: +# * GUILE_${CMDCLASS} and GUILE_UNIX_${CMDCLASS} - the latter is the former transformed +# into an msys compatible format (c:\some\directory => /c/some/directory) +# * If _PREFIX was set: GUILE_${CMDCLASS} and GUILE_REL_UNIX_${CMDCLASS} +# which are the former two variables with _PREFIX removed +# (_PREFIX=/usr, GUILE_${CMDCLASS} = /usr/share/something +# => GUILE_REL_${CMDCLASS} = share/something +function(find_one_guile_dir _DIRCLASS _DIRCMD _PREFIX) + + string(TOUPPER ${_DIRCLASS} CLASS_UPPER) + string(TOLOWER ${_DIRCLASS} CLASS_LOWER) + execute_process( + COMMAND ${GUILE_EXECUTABLE} -c ${_DIRCMD} + RESULT_VARIABLE CMD_RESULT + OUTPUT_VARIABLE CMD_OUTPUT + ERROR_VARIABLE CMD_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + if (CMD_RESULT) + message(SEND_ERROR "Could not determine Guile ${CLASS_LOWER}:\n${CMD_ERROR}") + endif() + + set(GUILE_${CLASS_UPPER} ${CMD_OUTPUT} PARENT_SCOPE) + set(CMD_UNIX_OUTPUT ${CMD_OUTPUT}) + make_unix_path(CMD_UNIX_OUTPUT) + set(GUILE_UNIX_${CLASS_UPPER} ${CMD_UNIX_OUTPUT} PARENT_SCOPE) + + if (_PREFIX) + string(REGEX REPLACE "^${_PREFIX}[\\/]*" "" CMD_REL_OUTPUT ${CMD_OUTPUT}) + set(GUILE_REL_${CLASS_UPPER} ${CMD_REL_OUTPUT} PARENT_SCOPE) + set(CMD_REL_UNIX_OUTPUT ${CMD_REL_OUTPUT}) + make_unix_path(CMD_REL_UNIX_OUTPUT) + set(GUILE_REL_UNIX_${CLASS_UPPER} ${CMD_REL_UNIX_OUTPUT} PARENT_SCOPE) + endif() + +endfunction(find_one_guile_dir) + +# Query the guile executable for path information. We're interested in guile's +# datadir, libdir, sitedir, ccachedir and siteccachedir +macro(find_guile_dirs) + # Get GUILE_PREFIX and GUILE_UNIX_PREFIX + find_one_guile_dir("prefix" "(display (assoc-ref %guile-build-info 'prefix))" "") + # Get GUILE_DATADIR, GUILE_UNIX_DATADIR, GUILE_REL_DATADIR, GUILE_REL_UNIX_DATADIR + find_one_guile_dir("datadir" "(display (%package-data-dir))" ${GUILE_PREFIX}) + # Get GUILE_LIBDIR, GUILE_UNIX_LIBDIR, GUILE_REL_LIBDIR, GUILE_REL_UNIX_LIBDIR + find_one_guile_dir("libdir" "(display (%library-dir))" ${GUILE_PREFIX}) + # Get GUILE_CCACHEDIR, GUILE_UNIX_CCACHEDIR, GUILE_REL_CCACHEDIR, GUILE_REL_UNIX_CCACHEDIR + find_one_guile_dir("ccachedir" "(display (assoc-ref %guile-build-info 'ccachedir))" ${GUILE_PREFIX}) + # Get GUILE_SITEDIR, GUILE_UNIX_SITEDIR, GUILE_REL_SITEDIR, GUILE_REL_UNIX_SITEDIR + find_one_guile_dir("sitedir" "(display (%site-dir))" ${GUILE_PREFIX}) + # Get GUILE_SITECCACHEDIR, GUILE_UNIX_SITECCACHEDIR, GUILE_REL_SITECCACHEDIR, GUILE_REL_UNIX_SITECCACHEDIR + find_one_guile_dir("siteccachedir" "(display (%site-ccache-dir))" ${GUILE_PREFIX}) + string(REGEX REPLACE "[/\\]*${GUILE_EFFECTIVE_VERSION}$" "" GUILE_REL_TOP_SITEDIR ${GUILE_REL_SITEDIR}) + string(REGEX REPLACE "[/]*${GUILE_EFFECTIVE_VERSION}$" "" GUILE_REL_UNIX_TOP_SITEDIR ${GUILE_REL_UNIX_SITEDIR}) + + # Generate replacement strings for use in environment file. The paths used are + # the paths found in %load-path and %load-compiled-path by default but + # rebased on {GNC_HOME} (which is the runtime resolved variable to where gnucash + # gets installed). + set (GNC_GUILE_LOAD_PATH + "{GNC_HOME}/${GUILE_REL_UNIX_LIBDIR}" + "{GNC_HOME}/${GUILE_REL_UNIX_SITEDIR}" + "{GNC_HOME}/${GUILE_REL_UNIX_TOP_SITEDIR}" + "{GNC_HOME}/${GUILE_REL_UNIX_DATADIR}") + + set (GNC_GUILE_LOAD_COMPILED_PATH + "{GNC_HOME}/${GUILE_REL_UNIX_CCACHEDIR}" + "{GNC_HOME}/${GUILE_REL_UNIX_SITECCACHEDIR}") +endmacro(find_guile_dirs) + function(make_scheme_targets _TARGET _SOURCE_FILES _OUTPUT_DIR _GUILE_DEPENDS MAKE_LINKS) set(__DEBUG FALSE) @@ -54,9 +130,9 @@ function(make_scheme_targets _TARGET _SOURCE_FILES _OUTPUT_DIR _GUILE_DEPENDS make_unix_path(CMAKE_SOURCE_DIR) endif() - # If links are requested, we simple link (or copy, for Windows) each source file to the dest directory + # If links are requested, we simply link (or copy, for Windows) each source file to the dest directory if(MAKE_LINKS) - set(_LINK_DIR ${DATADIR_BUILD}/gnucash/scm/${_OUTPUT_DIR}) + set(_LINK_DIR ${CMAKE_BINARY_DIR}/${GUILE_REL_UNIX_SITEDIR}/${_OUTPUT_DIR}) file(MAKE_DIRECTORY ${_LINK_DIR}) set(_SCHEME_LINKS "") foreach(scheme_file ${_SOURCE_FILES}) @@ -88,9 +164,9 @@ function(make_scheme_targets _TARGET _SOURCE_FILES _OUTPUT_DIR _GUILE_DEPENDS list(APPEND _GUILE_LOAD_PATH ${guile_load_path}) list(APPEND _GUILE_LOAD_COMPILED_PATH ${guile_load_compiled_path}) endif() - set(_GUILE_CACHE_DIR ${LIBDIR_BUILD}/gnucash/scm/ccache/${GUILE_EFFECTIVE_VERSION}) - list(APPEND _GUILE_LOAD_PATH "${build_datadir}/gnucash/scm") - list(APPEND _GUILE_LOAD_COMPILED_PATH ${build_libdir}/gnucash/scm/ccache/${GUILE_EFFECTIVE_VERSION}) + set(_GUILE_CACHE_DIR ${CMAKE_BINARY_DIR}/${GUILE_REL_UNIX_SITECCACHEDIR}) + list(APPEND _GUILE_LOAD_PATH "${CMAKE_BINARY_DIR}/${GUILE_REL_UNIX_SITEDIR}") + list(APPEND _GUILE_LOAD_COMPILED_PATH ${_GUILE_CACHE_DIR}) set(_TARGET_FILES "") @@ -167,8 +243,8 @@ function(gnc_add_scheme_targets _TARGET _SOURCE_FILES _OUTPUT_DIR _GUILE_DEPENDS MAKE_LINKS) make_scheme_targets("${_TARGET}" "${_SOURCE_FILES}" "${_OUTPUT_DIR}" "${_GUILE_DEPENDS}" "${MAKE_LINKS}") - install(FILES ${_TARGET_FILES} DESTINATION ${SCHEME_INSTALLED_CACHE_DIR}/${_OUTPUT_DIR}) - install(FILES ${_SOURCE_FILES} DESTINATION ${SCHEME_INSTALLED_SOURCE_DIR}/${_OUTPUT_DIR}) + install(FILES ${_TARGET_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/${GUILE_REL_SITECCACHEDIR}/${_OUTPUT_DIR}) + install(FILES ${_SOURCE_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/${GUILE_REL_SITEDIR}/${_OUTPUT_DIR}) endfunction(gnc_add_scheme_targets) function(gnc_add_scheme_test_targets _TARGET _SOURCE_FILES _OUTPUT_DIR _GUILE_DEPENDS diff --git a/common/cmake_modules/GncAddTest.cmake b/common/cmake_modules/GncAddTest.cmake index b673f72f0c..17857c4fe8 100644 --- a/common/cmake_modules/GncAddTest.cmake +++ b/common/cmake_modules/GncAddTest.cmake @@ -24,7 +24,7 @@ function(get_guile_env) set(fpath "${fpath}${dir}:") endforeach(dir) list(APPEND env "PATH=${fpath}") - set(compiled_path "${LIBDIR_BUILD}/gnucash/scm/ccache/${GUILE_EFFECTIVE_VERSION}") + set(compiled_path "${CMAKE_BINARY_DIR}/${GUILE_REL_SITECCACHEDIR}") string(REGEX REPLACE "^([A-Za-z]):" "/\\1" compiled_path ${compiled_path}) list(APPEND env GUILE_LOAD_COMPILED_PATH=${compiled_path}) endif(MINGW64) @@ -32,7 +32,7 @@ function(get_guile_env) list(APPEND env "GUILE=${GUILE_EXECUTABLE}") if (NOT WIN32) - list(APPEND env "GUILE_LOAD_COMPILED_PATH=${LIBDIR_BUILD}/gnucash/scm/ccache/${GUILE_EFFECTIVE_VERSION}:${LIBDIR_BUILD}/gnucash/scm/ccache/${GUILE_EFFECTIVE_VERSION}/tests") + list(APPEND env "GUILE_LOAD_COMPILED_PATH=${CMAKE_BINARY_DIR}/${GUILE_REL_SITECCACHEDIR}:${CMAKE_BINARY_DIR}/${GUILE_REL_SITECCACHEDIR}/tests") endif() set(guile_load_paths "") list(APPEND guile_load_paths ${CMAKE_CURRENT_SOURCE_DIR}/mod-foo) diff --git a/gnucash/environment.in b/gnucash/environment.in index e275696371..e81a013256 100644 --- a/gnucash/environment.in +++ b/gnucash/environment.in @@ -57,11 +57,11 @@ GNC_MODULE_PATH={GNC_LIB};{GNC_MODULE_PATH} # modules. # GUILE_LIBS= # GUILE_COMPILED_LIBS= -GUILE_LOAD_PATH={GNC_DATA}/scm;{GNC_HOME}/share/guile//@GUILE_EFFECTIVE_VERSION@;{GUILE_LIBS};{GUILE_LOAD_PATH} +GUILE_LOAD_PATH=@GNC_GUILE_LOAD_PATH@;{GUILE_LIBS};{GUILE_LOAD_PATH} # On Windows {GNC_LIB} points to {GNC_HOME}/bin because that's where the DLLs # are. It's not where the compiled scheme files are so we use {SYS_LIB} here. -GUILE_LOAD_COMPILED_PATH={SYS_LIB}/guile/@GUILE_EFFECTIVE_VERSION@/ccache;{SYS_LIB}/gnucash/scm/ccache/@GUILE_EFFECTIVE_VERSION@;{GUILE_COMPILED_LIBS};{GUILE_LOAD_COMPILED_PATH} +GUILE_LOAD_COMPILED_PATH=@GNC_GUILE_LOAD_COMPILED_PATH@;{GUILE_COMPILED_LIBS};{GUILE_LOAD_COMPILED_PATH} # Tell Guile where to find GnuCash specific shared libraries GNC_LIBRARY_PATH={SYS_LIB};{GNC_LIB} diff --git a/gnucash/report/reports/support/CMakeLists.txt b/gnucash/report/reports/support/CMakeLists.txt index 23195aebe5..1a9582de05 100644 --- a/gnucash/report/reports/support/CMakeLists.txt +++ b/gnucash/report/reports/support/CMakeLists.txt @@ -7,7 +7,7 @@ set(support_DATA balsheet-eg.eguile.scm ) -install(FILES ${support_DATA} DESTINATION ${SCHEME_INSTALLED_SOURCE_DIR}/gnucash/report) +install(FILES ${support_DATA} DESTINATION ${CMAKE_INSTALL_PREFIX}/${GUILE_REL_SITEDIR}/gnucash/report) set(support_EXTRA_DIST README diff --git a/libgnucash/core-utils/gnc-path.c b/libgnucash/core-utils/gnc-path.c index 2d8a306aa3..f02d661413 100644 --- a/libgnucash/core-utils/gnc-path.c +++ b/libgnucash/core-utils/gnc-path.c @@ -171,24 +171,16 @@ gchar *gnc_path_get_accountsdir() } /** Returns the file path to the directory containing all guile scripts, usually - * "$prefix/share/gnucash/scm". + * "$prefix/guile/site/2.2". + * This path is determined by querying guile for its sitedir and then + * rebasing this to be relative to our own installation prefix. * * @returns A newly allocated string. */ gchar *gnc_path_get_scmdir() { - /* Careful: if the cmake variable SCHEME_INSTALLED_SOURCE_DIR gets changed - * in toplevel CMakeLists.txt, this path should probably change as well. - * Currently this code assumes SCHEME_INSTALLED_SOURCE_DIR is set to - * pkgdatadir/scm - * We can't use GNC_SCM_INSTALL_DIR directly at build time to - * get this information, because on Windows and OS X - * the final path may get installed in a different location - * than assumed during build, invalidating the build path at - * runtime. - */ - gchar *pkgdatadir = gnc_path_get_pkgdatadir (); - gchar *result = g_build_filename (pkgdatadir, "scm", (char*)NULL); - g_free (pkgdatadir); + gchar *prefix = gnc_path_get_prefix (); + gchar *result = g_build_filename (prefix, GUILE_REL_SITEDIR, (char*)NULL); + g_free (prefix); return result; } diff --git a/libgnucash/core-utils/gncla-dir.h.in b/libgnucash/core-utils/gncla-dir.h.in index d15dce7050..8ea68429b2 100644 --- a/libgnucash/core-utils/gncla-dir.h.in +++ b/libgnucash/core-utils/gncla-dir.h.in @@ -31,3 +31,5 @@ #define LIBDIR "@libdir@" #define LOCALEDIR "@localedir@" + +#define GUILE_REL_SITEDIR "@GUILE_REL_SITEDIR@"