diff options
author | unmush <unmush@hashbang.sh> | 2024-11-27 01:37:40 +0200 |
---|---|---|
committer | Efraim Flashner <efraim@flashner.co.il> | 2024-12-22 15:37:35 +0200 |
commit | 84df0c4f396bcde7b0d0f5a6bb7455efa4a2f643 (patch) | |
tree | 076a0861787655528b4a6344e4e1e4f9a371eea5 /gnu/packages/patches | |
parent | a46816dcd155e0544e745deb7256362574fe3154 (diff) |
gnu: Add mono-6.12.0.
This includes a patch to add support for a <runpath> element to
mono's *.dll.config and *.exe.config files. See
mono-6.12.0-add-runpath.patch for details.
* gnu/packages/dotnet.scm (mono-6.12.0-external-repo-specs,
mono-6.12.0): New variable.
* gnu/packages/patches/mono-6.12.0-add-runpath.patch,
gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch,
gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch: New patches.
* gnu/local.mk (dist_patch_DATA): Register new patches.
Signed-off-by: Efraim Flashner <efraim@flashner.co.il>
Change-Id: I937715ad00df17b92137b8cd364652e7d445e22e
Diffstat (limited to 'gnu/packages/patches')
3 files changed, 467 insertions, 0 deletions
diff --git a/gnu/packages/patches/mono-6.12.0-add-runpath.patch b/gnu/packages/patches/mono-6.12.0-add-runpath.patch new file mode 100644 index 0000000000..3062bd6a0d --- /dev/null +++ b/gnu/packages/patches/mono-6.12.0-add-runpath.patch @@ -0,0 +1,185 @@ +mono: metadata: add <runpath> element to .config files. + +This new element is of the form: + +<runpath path="/path1/to/libs:/path2/to/libs:..."/> + +(the : will actually be whatever G_SEARCHPATH_SEPARATOR_S is, so likely ; on +windows and : elsewhere). + +* mono/metadata/metadata-internals.h (struct _MonoImage): new 'runpath' field. +* mono/metadata/mono-config.c (runpath_init, runpath_start, runpath_handler): + new functions and parser using them to populate runpath field from <runpath> + element. + (mono_config_init): register runpath_handler. +* mono/metadata/assembly.c (mono_assembly_load_full_gac_base_default): new + 'requesting' parameter, use it to search the requesting assembly's runpath + first. + (mono_assembly_request_byname_nosearch): use it. + + +diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c +index f9feaacf2c1..8c71ad0eb95 100644 +--- a/mono/metadata/assembly.c ++++ b/mono/metadata/assembly.c +@@ -376,7 +376,7 @@ mono_assembly_invoke_search_hook_internal (MonoAssemblyLoadContext *alc, MonoAss + static MonoAssembly* + mono_assembly_request_byname_nosearch (MonoAssemblyName *aname, const MonoAssemblyByNameRequest *req, MonoImageOpenStatus *status); + static MonoAssembly* +-mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, const char *basedir, MonoAssemblyLoadContext *alc, MonoAssemblyContextKind asmctx, MonoImageOpenStatus *status); ++mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, MonoAssembly *requesting, const char *basedir, MonoAssemblyLoadContext *alc, MonoAssemblyContextKind asmctx, MonoImageOpenStatus *status); + static MonoAssembly* + chain_redirections_loadfrom (MonoAssemblyLoadContext *alc, MonoImage *image, MonoImageOpenStatus *out_status); + static MonoAssembly* +@@ -4655,7 +4655,7 @@ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname, + } + + #ifndef ENABLE_NETCORE +- result = mono_assembly_load_full_gac_base_default (aname, req->basedir, req->request.alc, req->request.asmctx, status); ++ result = mono_assembly_load_full_gac_base_default (aname, req->requesting_assembly, req->basedir, req->request.alc, req->request.asmctx, status); + #endif + return result; + } +@@ -4667,6 +4667,7 @@ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname, + */ + MonoAssembly* + mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, ++ MonoAssembly *requesting, + const char *basedir, + MonoAssemblyLoadContext *alc, + MonoAssemblyContextKind asmctx, +@@ -4718,6 +4719,23 @@ mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, + filename = g_strconcat (aname->name, ext, (const char*)NULL); + } + ++ if (requesting ++ && requesting->image ++ && requesting->image->runpath) { ++ char **runpath = requesting->image->runpath; ++ int j; ++ for (j = 0; runpath[j]; j++) { ++ fullpath = g_build_filename (runpath[j], filename, NULL); ++ result = mono_assembly_request_open (fullpath, &req, status); ++ g_free (fullpath); ++ if (result) { ++ result->in_gac = FALSE; ++ g_free (filename); ++ return result; ++ } ++ } ++ } ++ + #ifndef DISABLE_GAC + const gboolean refonly = asmctx == MONO_ASMCTX_REFONLY; + +diff --git a/mono/metadata/image.c b/mono/metadata/image.c +index e0b86dd3d09..12a8094e4e0 100644 +--- a/mono/metadata/image.c ++++ b/mono/metadata/image.c +@@ -2363,6 +2363,9 @@ mono_image_close_except_pools (MonoImage *image) + + mono_metadata_clean_for_image (image); + ++ if (image->runpath) ++ g_strfreev (image->runpath); ++ + /* + * The caches inside a MonoImage might refer to metadata which is stored in referenced + * assemblies, so we can't release these references in mono_assembly_close () since the +diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h +index 9388d69b0fd..93f4b880c61 100644 +--- a/mono/metadata/metadata-internals.h ++++ b/mono/metadata/metadata-internals.h +@@ -423,6 +423,12 @@ struct _MonoImage { + /**/ + MonoTableInfo tables [MONO_TABLE_NUM]; + ++ /* ++ Search path to be tried first when looking for assemblies referenced by ++ this image, or NULL. Is a NULL-terminated vector. ++ */ ++ char **runpath; ++ + /* + * references is initialized only by using the mono_assembly_open + * function, and not by using the lowlevel mono_image_open. +diff --git a/mono/metadata/mono-config.c b/mono/metadata/mono-config.c +index d973de53c8c..8888c7b4fac 100644 +--- a/mono/metadata/mono-config.c ++++ b/mono/metadata/mono-config.c +@@ -21,6 +21,7 @@ + #include "mono/metadata/metadata-internals.h" + #include "mono/metadata/object-internals.h" + #include "mono/utils/mono-logger-internals.h" ++#include "mono/utils/mono-path.h" + + #if defined(TARGET_PS3) + #define CONFIG_OS "CellOS" +@@ -464,6 +465,59 @@ aot_cache_handler = { + NULL, /* finish */ + }; + ++static void* ++runpath_init (MonoImage *assembly) ++{ ++ return assembly; ++} ++ ++static void ++runpath_start (gpointer user_data, ++ const gchar *element_name, ++ const gchar **attribute_names, ++ const gchar **attribute_values) ++{ ++ MonoImage *assembly = (MonoImage *) user_data; ++ int i; ++ ++ if (strcmp (element_name, "runpath") != 0) ++ return; ++ ++ for (i = 0; attribute_names[i]; i++) ++ { ++ if(!strcmp (attribute_names [i], "path")) ++ { ++ char **splitted, **dest; ++ ++ splitted = g_strsplit (attribute_values[i], ++ G_SEARCHPATH_SEPARATOR_S, ++ 1000); ++ if (assembly->runpath) ++ g_strfreev (assembly->runpath); ++ assembly->runpath = dest = splitted; ++ while (*splitted) { ++ char *tmp = *splitted; ++ if (*tmp) ++ *dest++ = mono_path_canonicalize (tmp); ++ g_free (tmp); ++ splitted++; ++ } ++ *dest = *splitted; ++ break; ++ } ++ } ++} ++ ++static const MonoParseHandler ++runpath_handler = { ++ "runpath", ++ runpath_init, ++ runpath_start, ++ NULL, /* text */ ++ NULL, /* end */ ++ NULL, /* finish */ ++}; ++ + static int inited = 0; + + static void +@@ -476,6 +530,7 @@ mono_config_init (void) + #endif + g_hash_table_insert (config_handlers, (gpointer) legacyUEP_handler.element_name, (gpointer) &legacyUEP_handler); + g_hash_table_insert (config_handlers, (gpointer) aot_cache_handler.element_name, (gpointer) &aot_cache_handler); ++ g_hash_table_insert (config_handlers, (gpointer) runpath_handler.element_name, (gpointer) &runpath_handler); + } + + /** diff --git a/gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch b/gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch new file mode 100644 index 0000000000..05db7b9cdd --- /dev/null +++ b/gnu/packages/patches/mono-6.12.0-fix-AssemblyResolver.patch @@ -0,0 +1,236 @@ +diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs +index 5e0ec480956..9daf9d6920b 100644 +--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs ++++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs +@@ -67,54 +67,56 @@ public void ResetSearchLogger () + search_log.Clear (); + } + +- string GetGacPath () ++ string[] GetGacPaths () + { + // NOTE: code from mcs/tools/gacutil/driver.cs +- PropertyInfo gac = typeof (System.Environment).GetProperty ("GacPath", BindingFlags.Static | BindingFlags.NonPublic); ++ PropertyInfo gacs = typeof (System.Environment).GetProperty ("GacPaths", BindingFlags.Static | BindingFlags.NonPublic); + +- if (gac == null) ++ if (gacs == null) + return null; + +- MethodInfo get_gac = gac.GetGetMethod (true); +- return (string) get_gac.Invoke (null, null); ++ MethodInfo get_gacs = gacs.GetGetMethod (true); ++ return (string[]) get_gacs.Invoke (null, null); + } + + void GatherGacAssemblies () + { +- string gac_path = GetGacPath (); +- if (gac_path == null) +- throw new InvalidOperationException ("XBuild must be run on Mono runtime"); +- if (!Directory.Exists (gac_path)) +- return; // in case mono isn't "installed". +- +- Version version; +- DirectoryInfo version_info, assembly_info; +- +- foreach (string assembly_name in Directory.GetDirectories (gac_path)) { +- assembly_info = new DirectoryInfo (assembly_name); +- foreach (string version_token in Directory.GetDirectories (assembly_name)) { +- foreach (string file in Directory.GetFiles (version_token, "*.dll")) { +- version_info = new DirectoryInfo (version_token); +- version = new Version (version_info.Name.Split ( +- new char [] {'_'}, StringSplitOptions.RemoveEmptyEntries) [0]); +- +- Dictionary<Version, string> assembliesByVersion = new Dictionary <Version, string> (); +- if (!gac.TryGetValue (assembly_info.Name, out assembliesByVersion)) { +- assembliesByVersion = new Dictionary <Version, string> (); +- gac.Add (assembly_info.Name, assembliesByVersion); +- } +- +- string found_file; +- if (assembliesByVersion.TryGetValue (version, out found_file) && +- File.GetLastWriteTime (file) <= File.GetLastWriteTime (found_file)) +- // Duplicate found, take the newer file +- continue; +- +- assembliesByVersion [version] = file; +- } +- } +- } +- } ++ string[] gac_paths = GetGacPaths (); ++ if (gac_paths == null) ++ throw new InvalidOperationException ("XBuild must be run on Mono runtime"); ++ if (gac_paths.Length == 0 || !Directory.Exists (gac_paths[0])) ++ return; // in case mono isn't "installed". ++ ++ Version version; ++ DirectoryInfo version_info, assembly_info; ++ ++ foreach (string gac_path in gac_paths) { ++ foreach (string assembly_name in Directory.GetDirectories (gac_path)) { ++ assembly_info = new DirectoryInfo (assembly_name); ++ foreach (string version_token in Directory.GetDirectories (assembly_name)) { ++ foreach (string file in Directory.GetFiles (version_token, "*.dll")) { ++ version_info = new DirectoryInfo (version_token); ++ version = new Version (version_info.Name.Split ( ++ new char [] {'_'}, StringSplitOptions.RemoveEmptyEntries) [0]); ++ ++ Dictionary<Version, string> assembliesByVersion = new Dictionary <Version, string> (); ++ if (!gac.TryGetValue (assembly_info.Name, out assembliesByVersion)) { ++ assembliesByVersion = new Dictionary <Version, string> (); ++ gac.Add (assembly_info.Name, assembliesByVersion); ++ } ++ ++ string found_file; ++ if (assembliesByVersion.TryGetValue (version, out found_file) && ++ File.GetLastWriteTime (file) <= File.GetLastWriteTime (found_file)) ++ // Duplicate found, take the newer file ++ continue; ++ ++ assembliesByVersion [version] = file; ++ } ++ } ++ } ++ } ++ } + + public ResolvedReference FindInTargetFramework (ITaskItem reference, string framework_dir, bool specific_version) + { +diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs +index fd936ab21a4..b5a5c77c1a3 100644 +--- a/mcs/class/corlib/System/Environment.cs ++++ b/mcs/class/corlib/System/Environment.cs +@@ -984,9 +984,18 @@ private static string GacPath { + return Path.Combine (Path.Combine (internalGetGacPath (), "mono"), "gac"); + } + } ++ ++ private static string[] GacPaths { ++ get { ++ return internalGetGacPaths (); ++ } ++ } + #pragma warning restore 169 + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal extern static string internalGetGacPath (); ++ ++ [MethodImplAttribute (MethodImplOptions.InternalCall)] ++ internal extern static string [] internalGetGacPaths (); + #endif + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal extern static string [] GetLogicalDrivesInternal (); +diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c +index 8c71ad0eb95..759d5aefbcf 100644 +--- a/mono/metadata/assembly.c ++++ b/mono/metadata/assembly.c +@@ -854,6 +854,11 @@ mono_assembly_getrootdir (void) + return default_path [0]; + } + ++char **mono_assembly_get_extra_gac_paths() ++{ ++ return extra_gac_paths; ++} ++ + /** + * mono_native_getrootdir: + * +diff --git a/mono/metadata/assembly.h b/mono/metadata/assembly.h +index e9c02ee26f5..e5f060e8238 100644 +--- a/mono/metadata/assembly.h ++++ b/mono/metadata/assembly.h +@@ -50,6 +50,7 @@ MONO_API MONO_RT_EXTERNAL_ONLY 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 char **mono_assembly_get_extra_gac_paths (void); + MONO_API 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); +diff --git a/mono/metadata/icall-decl.h b/mono/metadata/icall-decl.h +index a77fcf38598..3f0f1758ec2 100644 +--- a/mono/metadata/icall-decl.h ++++ b/mono/metadata/icall-decl.h +@@ -152,6 +152,7 @@ ICALL_EXPORT gint32 ves_icall_System_Environment_get_TickCount (void); + #if ENABLE_NETCORE + ICALL_EXPORT gint64 ves_icall_System_Environment_get_TickCount64 (void); + #endif ++ICALL_EXPORT MonoArray *ves_icall_System_Environment_GetGacPaths (void); + ICALL_EXPORT gint64 ves_icall_System_DateTime_GetSystemTimeAsFileTime (void); + ICALL_EXPORT gint64 ves_icall_System_Diagnostics_Process_GetProcessData (int, gint32, MonoProcessError*); + ICALL_EXPORT gint64 ves_icall_System_Diagnostics_Stopwatch_GetTimestamp (void); +diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h +index 0a44729674b..59c803ba488 100644 +--- a/mono/metadata/icall-def.h ++++ b/mono/metadata/icall-def.h +@@ -327,6 +327,7 @@ HANDLES(ENV_16b, "get_bundled_machine_config", ves_icall_System_Environment_get_ + HANDLES(ENV_16m, "internalBroadcastSettingChange", ves_icall_System_Environment_BroadcastSettingChange, void, 0, ()) + HANDLES(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Environment_GetEnvironmentVariable_native, MonoString, 1, (const_char_ptr)) + HANDLES(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath, MonoString, 0, ()) ++NOHANDLES(ICALL(ENV_18_1, "internalGetGacPaths", ves_icall_System_Environment_GetGacPaths)) + HANDLES(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome, MonoString, 0, ()) + NOHANDLES(ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set)) + ICALL_TYPE(GC, "System.GC", GC_10) +diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c +index 6d16b9c3540..1e592c30e27 100644 +--- a/mono/metadata/icall.c ++++ b/mono/metadata/icall.c +@@ -7781,6 +7781,56 @@ ves_icall_System_Environment_GetGacPath (MonoError *error) + } + #endif + ++ICALL_EXPORT MonoArray * ++ves_icall_System_Environment_GetGacPaths () ++{ ++ char **extra_gac_paths = mono_assembly_get_extra_gac_paths(); ++ const char *rootdir = mono_assembly_getrootdir (); ++ char **e; ++ int n; ++ MonoDomain *domain; ++ MonoArray *out; ++ MonoString *str; ++ gchar *tmp; ++ MonoError error; ++ n = 0; ++ if (rootdir) n++; ++ if (extra_gac_paths) { ++ for (e = extra_gac_paths; *e != 0; e++); ++ n += (e - extra_gac_paths); ++ } ++ ++ domain = mono_domain_get (); ++ out = mono_array_new_checked (domain, mono_defaults.string_class, n, &error); ++ ++ if (mono_error_set_pending_exception (&error)) ++ return NULL; ++ ++ n = 0; ++ if (rootdir) { ++ tmp = g_build_path (G_DIR_SEPARATOR_S, rootdir, "mono", "gac", NULL); ++ str = mono_string_new_checked (domain, tmp, &error); ++ g_free (tmp); ++ if (mono_error_set_pending_exception (&error)) ++ return NULL; ++ mono_array_setref_internal (out, n, str); ++ n++; ++ } ++ if (extra_gac_paths) { ++ for (e = extra_gac_paths; *e != 0; e++) { ++ tmp = g_build_path (G_DIR_SEPARATOR_S, *e, "lib", "mono", "gac", NULL); ++ str = mono_string_new_checked (domain, tmp, &error); ++ g_free (tmp); ++ if (mono_error_set_pending_exception (&error)) ++ return NULL; ++ mono_array_setref_internal (out, n, str); ++ n++; ++ } ++ } ++ ++ return out; ++} ++ + #ifndef HOST_WIN32 + static inline MonoStringHandle + mono_icall_get_windows_folder_path (int folder, MonoError *error) diff --git a/gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch b/gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch new file mode 100644 index 0000000000..4ecde07d42 --- /dev/null +++ b/gnu/packages/patches/mono-6.12.0-fix-ConditionParser.patch @@ -0,0 +1,46 @@ +diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs +index b5e2e809ae4..757492d15e4 100644 +--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs ++++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConditionParser.cs +@@ -205,19 +205,30 @@ ConditionExpression ParseFunctionExpression (string function_name) + { + List <ConditionFactorExpression> list = new List <ConditionFactorExpression> (); + ConditionFactorExpression e; +- ++ ++ /* starts looking at the open paren, move past it */ ++ tokenizer.GetNextToken (); ++ if (tokenizer.Token.Type == TokenType.RightParen) { ++ /* leave us looking past the end of the argument list */ ++ tokenizer.GetNextToken (); ++ return list; ++ } + while (true) { +- tokenizer.GetNextToken (); +- if (tokenizer.Token.Type == TokenType.RightParen) { +- tokenizer.GetNextToken (); +- break; +- } +- if (tokenizer.Token.Type == TokenType.Comma) ++ e = (ConditionFactorExpression) ParseFactorExpression (); ++ list.Add (e); ++ /* ParseFactorExpression leaves us looking at what follows the ++ * expression */ ++ if (tokenizer.Token.Type == TokenType.RightParen) { ++ /* leave us looking past the end of the argument list */ ++ tokenizer.GetNextToken (); ++ break; ++ } ++ if (tokenizer.Token.Type == TokenType.Comma) { ++ tokenizer.GetNextToken (); + continue; +- +- tokenizer.Putback (tokenizer.Token); +- e = (ConditionFactorExpression) ParseFactorExpression (); +- list.Add (e); ++ } ++ ++ throw new ExpressionParseException (String.Format ("Unexpected token {0} in argument list while parsing condition \"{1}\"", tokenizer.Token, conditionStr)); + } + + return list; |