Merge pull request #3591 from directhex/mono_libdir_fallback
authorBernhard Urban <bernhard.urban@xamarin.com>
Thu, 13 Oct 2016 14:39:38 +0000 (16:39 +0200)
committerGitHub <noreply@github.com>
Thu, 13 Oct 2016 14:39:38 +0000 (16:39 +0200)
Handle relocatable libMonoPosixHelper.so when --libdir= isn't lib/

configure.ac
mono/metadata/Makefile.am
mono/metadata/assembly.c
mono/metadata/assembly.h
mono/metadata/mono-config-dirs.c
mono/metadata/mono-config-dirs.h
mono/metadata/mono-config.c

index 96cff1c8d5c4ccddd464c213b03afd6c687d4f1d..491e142eb5056354f8b63eaf4e4f3ad67afe6090 100644 (file)
@@ -68,7 +68,11 @@ AC_SUBST(libmono_cflags)
 AC_SUBST(libmono_ldflags)
 
 # Variable to have relocatable .pc files (lib, or lib64)
-reloc_libdir=`basename ${libdir}`
+# realpath isn't always available, and requires that all but the tip of the provided
+# path exists. Fall back to the old behaviour, but realpath allows depth >1
+# e.g. Debian puts Mono in /usr/bin and libs in /usr/lib/x86_64-linux-gnu/ which is
+# too deep for the old method to work
+reloc_libdir=`realpath --relative-to=${prefix} ${libdir} 2> /dev/null || basename ${libdir}`
 AC_SUBST(reloc_libdir)
 
 # Set to yes if Unix sockets cannot be created in an anonymous namespace
index c662c8c76f8ee4d9a4a14dc115279e5e7c77e5d4..3f754d04f3f26b85edc3d982fa69080c81d79737 100644 (file)
@@ -108,7 +108,7 @@ mono-config-dirs.lo: Makefile
 libmonoruntime_config_la_SOURCES = \
        mono-config-dirs.h              \
        mono-config-dirs.c
-libmonoruntime_config_la_CPPFLAGS = $(AM_CPPFLAGS) -DMONO_BINDIR=\"$(bindir)/\" -DMONO_ASSEMBLIES=\"$(assembliesdir)\" -DMONO_CFG_DIR=\"$(confdir)\"
+libmonoruntime_config_la_CPPFLAGS = $(AM_CPPFLAGS) -DMONO_BINDIR=\"$(bindir)/\" -DMONO_ASSEMBLIES=\"$(assembliesdir)\" -DMONO_CFG_DIR=\"$(confdir)\" -DMONO_RELOC_LIBDIR=\"../$(reloc_libdir)\"
 
 CLEANFILES = mono-bundle.stamp
 
index 64d1000bbb63b8f896164af207e176969b6ece3c..643c4930b1a29360e4c80fc4cae1df1cf51da0bf 100644 (file)
@@ -559,6 +559,21 @@ mono_assembly_getrootdir (void)
        return default_path [0];
 }
 
+/**
+ * mono_native_getrootdir:
+ * 
+ * Obtains the root directory used for looking up native libs (.so, .dylib).
+ *
+ * Returns: a string with the directory, this string should be freed by
+ * the caller.
+ */
+G_CONST_RETURN gchar *
+mono_native_getrootdir (void)
+{
+       gchar* fullpath = g_build_path (G_DIR_SEPARATOR_S, mono_assembly_getrootdir (), mono_config_get_reloc_lib_dir(), NULL);
+       return fullpath;
+}
+
 /**
  * mono_set_dirs:
  * @assembly_dir: the base directory for assemblies
index b414971e171dd40e479f0a4e7198fdf1691fbf0b..6126feda0e1c9053ddc792e2a466a1aa60dd2953 100644 (file)
@@ -37,6 +37,7 @@ MONO_RT_EXTERNAL_ONLY MONO_API MonoImage*    mono_assembly_load_module (MonoAsse
 MONO_API void          mono_assembly_close      (MonoAssembly *assembly);
 MONO_API void          mono_assembly_setrootdir (const char *root_dir);
 MONO_API MONO_CONST_RETURN char *mono_assembly_getrootdir (void);
+MONO_API MONO_CONST_RETURN char *mono_native_getrootdir (void);
 MONO_API void        mono_assembly_foreach    (MonoFunc func, void* user_data);
 MONO_API void          mono_assembly_set_main   (MonoAssembly *assembly);
 MONO_API MonoAssembly *mono_assembly_get_main   (void);
index ece67d1286cd4fef23ca0b3389e7af6b58171f82..2e61a1b3373548162adf8a0291ebc00c3411fe4a 100644 (file)
@@ -41,3 +41,13 @@ mono_config_get_bin_dir (void)
 #endif
 }
 
+const char*
+mono_config_get_reloc_lib_dir (void)
+{
+#ifdef MONO_RELOC_LIBDIR
+       return MONO_RELOC_LIBDIR;
+#else
+       return NULL;
+#endif
+}
+
index 9488511bde4b719d7f0ba0a1f779915250eb5812..25e765122539c04384aad6f75ade2ee5efb39637 100644 (file)
@@ -13,4 +13,7 @@ mono_config_get_cfg_dir (void);
 const char*
 mono_config_get_bin_dir (void);
 
+const char*
+mono_config_get_reloc_lib_dir (void);
+
 #endif
index 2bedf12cd8fa713149e7ee88a43ad09cd2912988..cfe15393594f0ab94ec70b8f9479f1f4837d3aca 100644 (file)
@@ -314,13 +314,14 @@ dllmap_start (gpointer user_data,
                        else if (strcmp (attribute_names [i], "target") == 0){
                                char *p = strstr (attribute_values [i], "$mono_libdir");
                                if (p != NULL){
-                                       const char *libdir = mono_assembly_getrootdir ();
+                                       const char *libdir = mono_native_getrootdir ();
                                        size_t libdir_len = strlen (libdir);
                                        char *result;
                                        
                                        result = (char *)g_malloc (libdir_len-strlen("$mono_libdir")+strlen(attribute_values[i])+1);
                                        strncpy (result, attribute_values[i], p-attribute_values[i]);
                                        strcpy (result+(p-attribute_values[i]), libdir);
+                                       g_free (libdir);
                                        strcat (result, p+strlen("$mono_libdir"));
                                        info->target = result;
                                } else