Changeset: e07a557a343b for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e07a557a343b Modified Files: common/options/monet_options.mx configure.ag monetdb5/mal/mal_linker.mx monetdb5/misc/monetdb5.conf.in Branch: default Log Message:
modpath: automatically deduce monet_mod_path when unset Locate the modpath dirs based on the executable location. Use platform specific hacks to find the executable location. The automatic determination of the modpath can overridden by setting monet_mod_path, such as what testing will want to do, or platforms where we can't get the executable path. This is not only just "nice", but also very handy for bundle installs, or merovingians started on random directories serving as dbfarm, as it won't require to rewrite the config file, or override the modpath in the call invocation. Note: get_mserver_bin_path isn't implemented for Windows, but there appears to be a similar functionality to get the executable path. diffs (228 lines): diff --git a/common/options/monet_options.mx b/common/options/monet_options.mx --- a/common/options/monet_options.mx +++ b/common/options/monet_options.mx @@ -361,14 +361,14 @@ if (Set == NULL) return 0; -#define N_OPTIONS 26 /*MUST MATCH # OPTIONS BELOW */ +#define N_OPTIONS 25 /*MUST MATCH # OPTIONS BELOW */ set = malloc(sizeof(opt) * N_OPTIONS); if (set == NULL) return 0; /* -------------------------------------------------------------- */ /* Please keep the below defaults aligned with the comments in */ - /* MonetDB4/conf/MonetDB.conf.in & MonetDB5/conf/monetdb5.conf.in */ + /* monetdb5/misc/monetdb5.conf.in */ /* -------------------------------------------------------------- */ set[i].kind = opt_builtin; @@ -424,19 +424,6 @@ set[i].value = strdup("yes"); i++; set[i].kind = opt_builtin; - set[i].name = strdup("monet_mod_path"); - /* on most platforms, we only need libdir/PACKAGE, but with - * MinGW, we also need libdir/bin */ -#ifdef __MINGW32__ - snprintf(buf, BUFSIZ, "%s%c%s%c%s%cbin", - LIBDIR, DIR_SEP, PACKAGE, PATH_SEP, - LIBDIR, DIR_SEP); -#else - snprintf(buf, BUFSIZ, "%s%c%s", LIBDIR, DIR_SEP, PACKAGE); -#endif - set[i].value = strdup(buf); - i++; - set[i].kind = opt_builtin; set[i].name = strdup("monet_daemon"); set[i].value = strdup("no"); i++; diff --git a/configure.ag b/configure.ag --- a/configure.ag +++ b/configure.ag @@ -2712,7 +2712,67 @@ # NOTE: these functions are in alphabetical order to ease maintenance save_LIBS="$LIBS" LIBS="$LIBS $MATH_LIBS" -AC_CHECK_FUNCS([asctime_r basename ctime_r drand48 fcntl fpclass fpclassify fstat fsync ftime ftruncate getlogin getopt getopt_long getrlimit GetSystemInfo gettimeofday getuid GlobalMemoryStatus GlobalMemoryStatusEx inet_ntop kill isinf localtime_r lockf madvise mrand48 nl_langinfo pipe popen posix_fadvise posix_madvise putenv QueryPerformanceCounter round sbrk setenv setlocale setsid shutdown sigaction strcasecmp strcasestr strdup strftime strncasecmp strndup strptime strsignal strtod strtof strtoll strtoull sysconf times trunc uname]) +AC_CHECK_FUNCS([\ + asctime_r \ + basename \ + ctime_r \ + drand48 \ + fcntl \ + fpclass \ + fpclassify \ + fstat \ + fsync \ + ftime \ + ftruncate \ + getexecname \ + getlogin \ + getopt \ + getopt_long \ + getrlimit \ + GetSystemInfo \ + gettimeofday \ + getuid \ + GlobalMemoryStatus \ + GlobalMemoryStatusEx \ + inet_ntop \ + isinf \ + kill \ + localtime_r \ + lockf \ + madvise \ + mrand48 \ + nl_langinfo \ + _NSGetExecutablePath \ + pipe \ + popen \ + posix_fadvise \ + posix_madvise \ + putenv \ + QueryPerformanceCounter \ + round \ + sbrk \ + setenv \ + setlocale \ + setsid \ + shutdown \ + sigaction \ + strcasecmp \ + strcasestr \ + strdup \ + strftime \ + strncasecmp \ + strndup \ + strptime \ + strsignal \ + strtod \ + strtof \ + strtoll \ + strtoull \ + sysconf \ + times \ + trunc \ + uname \ + ]) LIBS="$save_LIBS" dnl functions checked but result not used dnl AC_CHECK_FUNCS([closedir getcwd gethostname getpwuid memset mkdir nanosleep readdir rewinddir rmdir select strcspn strerror strstr strtol]) diff --git a/monetdb5/mal/mal_linker.mx b/monetdb5/mal/mal_linker.mx --- a/monetdb5/mal/mal_linker.mx +++ b/monetdb5/mal/mal_linker.mx @@ -103,6 +103,11 @@ #ifdef HAVE_FCNTL_H #include <fcntl.h> #endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#include <unistd.h> +#include <libgen.h> #if defined(_MSC_VER) && _MSC_VER >= 1400 #define open _open @@ -345,19 +350,84 @@ return strcmp(f1?f1:p1, f2?f2:p2); } +static char _mserver_bin_path[1024]; +static char * +get_mserver_bin_path() +{ + /* getting the path to the executable's binary, isn't all that + * simple, unfortunately */ +#if defined(HAVE__NSGETEXECUTABLEPATH) /* Darwin/OSX */ + uint32_t size = sizeof(_mserver_bin_path); + if (_NSGetExecutablePath(_mserver_bin_path, &size) == 0) + return _mserver_bin_path; +#elif defined(HAVE_SYS_SYSCTL_H) && defined(KERN_PROC_PATHNAME) /* BSD */ + int mib[4]; + size_t cb = sizeof(_mserver_bin_path); + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + if (sysctl(mib, 4, _mserver_bin_path, &cb, NULL, 0) == 0) + return _mserver_bin_path; +#elif defined(HAVE_GETEXECNAME) /* Solaris */ + char execn = getexecname(); + /* copy, such that the caller can actually modify this string */ + snprintf(_mserver_bin_path, sizeof(_mserver_bin_path), "%s", execn); +#else /* try Linux approach */ + if (readlink("/proc/self/exe", + _mserver_bin_path, sizeof(_mserver_bin_path)) != -1) + return _mserver_bin_path; +#endif + return NULL; +} + #define MAXMULTISCRIPT 48 static char * locate_file(const char *basename, const char *ext, bit recurse) { char *mod_path = GDKgetenv("monet_mod_path"); + char prmodpath[1024]; char *fullname; size_t fullnamelen; size_t filelen = strlen(basename) + strlen(ext); str strs[MAXMULTISCRIPT]; /* hardwired limit */ int lasts = 0; - if (mod_path == NULL) - return NULL; + if (mod_path == NULL) { + /* start probing based on some heuristics given the binary + * location: + * bin/mserver5 -> ../ + * libX/monetdb5/lib/ + * probe libX = lib, lib32, lib64, lib/64 */ + char *libdirs[] = { "lib", "lib64", "lib/64", "lib32", NULL }; + size_t i; + struct stat sb; + char *binpath = get_mserver_bin_path(); + if (binpath == NULL) + return NULL; + binpath = dirname(binpath); + binpath = dirname(binpath); + for (i = 0; libdirs[i] != NULL; i++) { + snprintf(prmodpath, sizeof(prmodpath), "%s%c%s%cmonetdb5%clib", + binpath, DIR_SEP, libdirs[i], DIR_SEP, DIR_SEP); + if (stat(prmodpath, &sb) == 0) { + snprintf(prmodpath, sizeof(prmodpath), + "%s%c%s%cmonetdb5:" +#ifndef __MINGW32__ + "%s%c%s%cmonetdb5%clib" +#else + "%s%c%s%cmonetdb5%cbin" +#endif + , + binpath, DIR_SEP, libdirs[i], DIR_SEP, + binpath, DIR_SEP, libdirs[i], DIR_SEP, DIR_SEP); + mod_path = prmodpath; + break; + } + } + if (mod_path == NULL) + return NULL; + } while (*mod_path == PATH_SEP) mod_path++; if (*mod_path == 0) diff --git a/monetdb5/misc/monetdb5.conf.in b/monetdb5/misc/monetdb5.conf.in --- a/monetdb5/misc/monetdb5.conf.in +++ b/monetdb5/misc/monetdb5.conf.in @@ -53,10 +53,6 @@ # Prompt when using MAL interface #monet_prompt=> # -# Where do the MonetDB modules reside? The second path is for windows -# dlls. -monet_mod_path=@Xlibdir@@DIRSEP@monetdb5@PATHSEP@@Xlibdir@@DIRSEP@monetdb5@DIRSEP@lib@PATHSEP@@Xlibdir@@DIRSEP@monetdb5@DIRSEP@bin -# # Start mserver in daemon mode, or start with MAL interactive # interface? #monet_daemon=no _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list