From c7cc9a68fd6688d3a900f3905a335945f1cf91ba Mon Sep 17 00:00:00 2001 From: michaeldgg2 <119738087+michaeldgg2@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:01:58 +0200 Subject: [PATCH] =?UTF-8?q?Eradicate=20=E2=98=A0=20Mono=20=E2=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Gustas <37534529+punkpun@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/crash-report.md | 1 - .github/workflows/ci.yml | 18 ---- .gitignore | 4 - Directory.Build.props | 8 +- INSTALL.md | 10 +-- Makefile | 38 +++------ OpenRA.Game/Exts.cs | 42 +--------- OpenRA.Game/Game.cs | 7 -- OpenRA.Game/HttpExtension.cs | 4 - OpenRA.Game/ObjectCreator.cs | 17 ---- OpenRA.Game/OpenRA.Game.csproj | 7 +- OpenRA.Game/Platform.cs | 17 +--- OpenRA.Game/Scripting/ScriptObjectWrapper.cs | 16 ---- OpenRA.Game/StreamExts.cs | 7 +- OpenRA.Game/Support/AssemblyLoader.cs | 3 - OpenRA.Game/Support/HttpClientFactory.cs | 6 -- .../SpriteLoaders/ShpRemasteredLoader.cs | 5 +- .../UtilityCommands/ImportGen1MapCommand.cs | 18 ---- .../Orders/UnitOrderGenerator.cs | 7 -- OpenRA.Mods.Common/Traits/Buildings/Exit.cs | 7 +- OpenRA.sln | 7 -- configure-system-libraries.sh | 69 ++++++--------- launch-dedicated.sh | 7 +- launch-game.sh | 7 +- packaging/functions.sh | 56 ++----------- packaging/linux/buildpackage.sh | 2 +- packaging/linux/openra-server.in | 2 - packaging/linux/openra.in | 2 - packaging/macos/apphost-mono.c | 48 ----------- packaging/macos/buildpackage.sh | 38 ++++----- packaging/macos/checkmono.c | 73 ---------------- packaging/macos/launcher.m | 77 +++-------------- packaging/macos/utility.m | 84 +------------------ packaging/windows/buildpackage.sh | 2 +- utility.sh | 7 +- 35 files changed, 89 insertions(+), 634 deletions(-) delete mode 100644 packaging/macos/apphost-mono.c delete mode 100644 packaging/macos/checkmono.c diff --git a/.github/ISSUE_TEMPLATE/crash-report.md b/.github/ISSUE_TEMPLATE/crash-report.md index baea717531..4175ad395e 100644 --- a/.github/ISSUE_TEMPLATE/crash-report.md +++ b/.github/ISSUE_TEMPLATE/crash-report.md @@ -16,7 +16,6 @@ assignees: '' - OpenRA Version: ENGINE VERSION - OpenRA Mod: GAME MOD - Source: Official download package OR self-compiled OR third-party package -- For self-compiled or third-party packages: Mono version ## Exception log diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a319f51e0..a416c1a408 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,24 +33,6 @@ jobs: make check-scripts make TREAT_WARNINGS_AS_ERRORS=true test - linux-mono: - name: Linux (mono) - runs-on: ubuntu-22.04 - - steps: - - name: Clone Repository - uses: actions/checkout@v4 - - - name: Check Code - run: | - mono --version - make RUNTIME=mono check - - - name: Check Mods - run: | - # check-scripts does not depend on .net/mono, so is not needed here - make RUNTIME=mono TREAT_WARNINGS_AS_ERRORS=true test - windows: name: Windows (.NET 6.0) runs-on: windows-2019 diff --git a/.gitignore b/.gitignore index a84fd6521b..cc85d4c048 100644 --- a/.gitignore +++ b/.gitignore @@ -25,10 +25,6 @@ IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP \#* .*.sw? -# Monodevelop -*.pidb -*.userprefs - # Mac OS X .DS_Store diff --git a/Directory.Build.props b/Directory.Build.props index 06d2634799..0d842c1842 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -18,8 +18,7 @@ - net6.0 - netstandard2.1 + net6.0 @@ -54,8 +53,7 @@ - - - + + diff --git a/INSTALL.md b/INSTALL.md index aac1b179d7..004d1c217b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -17,11 +17,9 @@ Run the game with `launch-game.cmd`. It can be handed arguments that specify the Linux ===== -.NET 6 or Mono (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project. +.NET 6 is required to compile OpenRA. The [.NET 6 download page](https://dotnet.microsoft.com/download/dotnet/6.0) provides repositories for various package managers and binary releases for several architectures. -The [.NET 6 download page](https://dotnet.microsoft.com/download/dotnet/6.0) provides repositories for various package managers and binary releases for several architectures. If you prefer to use Mono, we suggest adding the [upstream repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version and the `msbuild` toolchain. - -To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). After this one can run the game with `./launch-game.sh`. It is also possible to specify the mod you wish to run from the command line, e.g. with `./launch-game.sh Game.Mod=ts` if you wish to try the experimental Tiberian Sun mod. +To compile OpenRA, run `make` from the command line. After this one can run the game with `./launch-game.sh`. It is also possible to specify the mod you wish to run from the command line, e.g. with `./launch-game.sh Game.Mod=ts` if you wish to try the experimental Tiberian Sun mod. The default behaviour on the x86_64 architecture is to download several pre-compiled native libraries using the Nuget packaging manager. If you prefer to use system libraries, compile instead using `make TARGETPLATFORM=unix-generic`. @@ -78,6 +76,6 @@ Type `sudo make install` for system-wide installation. Run `sudo make install-li macOS ===== -[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 unless you are running a very old version of macOS (10.9 through 10.14). +[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) is required to compile OpenRA. -To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). Run with `./launch-game.sh`. +To compile OpenRA, run `make` from the command line. Run with `./launch-game.sh`. diff --git a/Makefile b/Makefile index 23a67e1585..aaed58e5d5 100644 --- a/Makefile +++ b/Makefile @@ -3,20 +3,17 @@ # to compile, run: # make # -# to compile using Mono (version 6.12 or greater) instead of .NET 6, run: -# make RUNTIME=mono -# # to compile using system libraries for native dependencies, run: -# make [RUNTIME=net6] TARGETPLATFORM=unix-generic +# make TARGETPLATFORM=unix-generic # # to check the official mods for erroneous yaml files, run: -# make [RUNTIME=net6] test +# make test # # to check the engine and official mod dlls for code style violations, run: -# make [RUNTIME=net6] check +# make check # # to compile and install Red Alert, Tiberian Dawn, and Dune 2000, run: -# make [RUNTIME=net6] [prefix=/foo] [bindir=/bar/bin] install +# make [prefix=/foo] [bindir=/bar/bin] install # # to compile and install Red Alert, Tiberian Dawn, and Dune 2000 # using system libraries for native dependencies, run: @@ -50,13 +47,11 @@ gameinstalldir ?= $(libdir)/openra CWD = $(shell pwd) MSBUILD = msbuild -verbosity:m -nologo DOTNET = dotnet -MONO = mono RM = rm RM_R = $(RM) -r RM_F = $(RM) -f RM_RF = $(RM) -rf -RUNTIME ?= net6 CONFIGURATION ?= Release DOTNET_RID = $(shell ${DOTNET} --info | grep RID: | cut -w -f3) ARCH_X64 = $(shell echo ${DOTNET_RID} | grep x64) @@ -91,18 +86,12 @@ endif # all: @echo "Compiling in ${CONFIGURATION} mode..." -ifeq ($(RUNTIME), mono) - @command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.12."; exit 1) - @$(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM) -else @$(DOTNET) build -c ${CONFIGURATION} -nologo -p:TargetPlatform=$(TARGETPLATFORM) -endif ifeq ($(TARGETPLATFORM), unix-generic) @./configure-system-libraries.sh endif @./fetch-geoip.sh -# dotnet clean and msbuild -t:Clean leave files that cause problems when switching between mono/dotnet # Deleting the intermediate / output directories ensures the build directory is actually clean clean: @-$(RM_RF) ./bin ./*/obj @@ -111,12 +100,8 @@ clean: check: @echo @echo "Compiling in Debug mode..." -ifeq ($(RUNTIME), mono) - @$(MSBUILD) -t:clean\;build -restore -p:Configuration=Debug -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -else @$(DOTNET) clean -c Debug --nologo --verbosity minimal @$(DOTNET) build -c Debug -nologo -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -endif ifeq ($(TARGETPLATFORM), unix-generic) @./configure-system-libraries.sh endif @@ -161,7 +146,7 @@ endif @sh -c '. ./packaging/functions.sh; set_mod_version "$(VERSION)" mods/*/mod.yaml' install: - @sh -c '. ./packaging/functions.sh; install_assemblies $(CWD) $(DESTDIR)$(gameinstalldir) $(TARGETPLATFORM) $(RUNTIME) True True True' + @sh -c '. ./packaging/functions.sh; install_assemblies $(CWD) $(DESTDIR)$(gameinstalldir) $(TARGETPLATFORM) True True True' @sh -c '. ./packaging/functions.sh; install_data $(CWD) $(DESTDIR)$(gameinstalldir) cnc d2k ra' install-linux-shortcuts: @@ -178,24 +163,21 @@ help: @echo 'to compile, run:' @echo ' make' @echo - @echo 'to compile using Mono (version 6.12 or greater) instead of .NET 6, run:' - @echo ' make RUNTIME=mono' - @echo @echo 'to compile using system libraries for native dependencies, run:' - @echo ' make [RUNTIME=net6] TARGETPLATFORM=unix-generic' + @echo ' make TARGETPLATFORM=unix-generic' @echo @echo 'to check the official mods for erroneous yaml files, run:' - @echo ' make [RUNTIME=net6] [TREAT_WARNINGS_AS_ERRORS=false] test' + @echo ' make [TREAT_WARNINGS_AS_ERRORS=false] test' @echo @echo 'to check the engine and official mod dlls for code style violations, run:' - @echo ' make [RUNTIME=net6] check' + @echo ' make check' @echo @echo 'to compile and install Red Alert, Tiberian Dawn, and Dune 2000 run:' - @echo ' make [RUNTIME=net6] [prefix=/foo] [TARGETPLATFORM=unix-generic] install' + @echo ' make [prefix=/foo] [TARGETPLATFORM=unix-generic] install' @echo @echo 'to compile and install Red Alert, Tiberian Dawn, and Dune 2000' @echo 'using system libraries for native dependencies, run:' - @echo ' make [RUNTIME=net6] [prefix=/foo] [bindir=/bar/bin] TARGETPLATFORM=unix-generic install' + @echo ' make [prefix=/foo] [bindir=/bar/bin] TARGETPLATFORM=unix-generic install' @echo @echo 'to install FreeDesktop startup scripts, desktop files, icons, and MIME metadata' @echo ' make install-linux-shortcuts' diff --git a/OpenRA.Game/Exts.cs b/OpenRA.Game/Exts.cs index 2a9ae19272..f450b4201f 100644 --- a/OpenRA.Game/Exts.cs +++ b/OpenRA.Game/Exts.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using System.Text; using OpenRA.Primitives; using OpenRA.Support; @@ -119,17 +120,11 @@ namespace OpenRA public static V GetOrAdd(this Dictionary d, K k, V v) { -#if NET5_0_OR_GREATER // SAFETY: Dictionary cannot be modified whilst the ref is alive. - ref var value = ref System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(d, k, out var exists); + ref var value = ref CollectionsMarshal.GetValueRefOrAddDefault(d, k, out var exists); if (!exists) value = v; return value; -#else - if (!d.TryGetValue(k, out var ret)) - d.Add(k, ret = v); - return ret; -#endif } public static V GetOrAdd(this Dictionary d, K k, Func createFn) @@ -510,39 +505,6 @@ namespace OpenRA return result; } - public static T[,] ResizeArray(T[,] ts, T t, int width, int height) - { - var result = new T[width, height]; - for (var i = 0; i < width; i++) - { - for (var j = 0; j < height; j++) - { - // Workaround for broken ternary operators in certain versions of mono - // (3.10 and certain versions of the 3.8 series): https://bugzilla.xamarin.com/show_bug.cgi?id=23319 - if (i <= ts.GetUpperBound(0) && j <= ts.GetUpperBound(1)) - result[i, j] = ts[i, j]; - else - result[i, j] = t; - } - } - - return result; - } - - public static int ToBits(this IEnumerable bits) - { - var i = 0; - var result = 0; - foreach (var b in bits) - if (b) - result |= 1 << i++; - else - i++; - if (i > 33) - throw new InvalidOperationException("ToBits only accepts up to 32 values."); - return result; - } - public static byte ParseByteInvariant(string s) { return byte.Parse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo); diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index db21002d68..21da88f9ac 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -429,16 +429,9 @@ namespace OpenRA { var rendererPath = Path.Combine(Platform.BinDir, "OpenRA.Platforms." + platformName + ".dll"); -#if NET5_0_OR_GREATER var loader = new AssemblyLoader(rendererPath); var platformType = loader.LoadDefaultAssembly().GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t)); -#else - // NOTE: This is currently the only use of System.Reflection in this file, so would give an unused using error if we import it above - var assembly = System.Reflection.Assembly.LoadFile(rendererPath); - var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t)); -#endif - if (platformType == null) throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation."); diff --git a/OpenRA.Game/HttpExtension.cs b/OpenRA.Game/HttpExtension.cs index aa57081a35..5bba955e7b 100644 --- a/OpenRA.Game/HttpExtension.cs +++ b/OpenRA.Game/HttpExtension.cs @@ -26,11 +26,7 @@ namespace OpenRA var total = response.Content.Headers.ContentLength ?? -1; var canReportProgress = total > 0; -#if NET5_0_OR_GREATER using (var contentStream = await response.Content.ReadAsStreamAsync(token)) -#else - using (var contentStream = await response.Content.ReadAsStreamAsync()) -#endif { var totalRead = 0L; var buffer = new byte[8192]; diff --git a/OpenRA.Game/ObjectCreator.cs b/OpenRA.Game/ObjectCreator.cs index 5170ff26ca..44901f5df6 100644 --- a/OpenRA.Game/ObjectCreator.cs +++ b/OpenRA.Game/ObjectCreator.cs @@ -55,26 +55,9 @@ namespace OpenRA if (!ResolvedAssemblies.TryGetValue(hash, out var assembly)) { -#if NET5_0_OR_GREATER var loader = new Support.AssemblyLoader(resolvedPath); assembly = loader.LoadDefaultAssembly(); ResolvedAssemblies.Add(hash, assembly); -#else - assembly = Assembly.LoadFile(resolvedPath); - ResolvedAssemblies.Add(hash, assembly); - - // Allow mods to use libraries. - var assemblyPath = Path.GetDirectoryName(resolvedPath); - if (assemblyPath != null) - { - foreach (var referencedAssembly in assembly.GetReferencedAssemblies()) - { - var depedencyPath = Path.Combine(assemblyPath, referencedAssembly.Name + ".dll"); - if (File.Exists(depedencyPath)) - LoadAssembly(assemblyList, depedencyPath); - } - } -#endif } assemblyList.Add(assembly); diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 1f9a808104..4db46f265e 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -2,14 +2,9 @@ OpenRA - + - - - - - diff --git a/OpenRA.Game/Platform.cs b/OpenRA.Game/Platform.cs index 7b8b1e39b6..cfaf474522 100644 --- a/OpenRA.Game/Platform.cs +++ b/OpenRA.Game/Platform.cs @@ -12,7 +12,6 @@ using System; using System.Diagnostics; using System.IO; -using System.Reflection; using System.Runtime.InteropServices; namespace OpenRA @@ -63,21 +62,7 @@ namespace OpenRA return PlatformType.Unknown; } - public static string RuntimeVersion - { - get - { - var mono = Type.GetType("Mono.Runtime"); - if (mono == null) - return $".NET CLR {Environment.Version}"; - - var version = mono.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static); - if (version == null) - return $"Mono (unknown version) CLR {Environment.Version}"; - - return $"Mono {version.Invoke(null, null)} CLR {Environment.Version}"; - } - } + public static string RuntimeVersion => $".NET CLR {Environment.Version}"; public static string OperatingSystem { diff --git a/OpenRA.Game/Scripting/ScriptObjectWrapper.cs b/OpenRA.Game/Scripting/ScriptObjectWrapper.cs index 17c8fb00dd..60b281318b 100644 --- a/OpenRA.Game/Scripting/ScriptObjectWrapper.cs +++ b/OpenRA.Game/Scripting/ScriptObjectWrapper.cs @@ -24,10 +24,6 @@ namespace OpenRA.Scripting protected readonly ScriptContext Context; readonly Dictionary members = new(); -#if !NET5_0_OR_GREATER - readonly List membersToRemove = new List(); -#endif - protected ScriptObjectWrapper(ScriptContext context) { Context = context; @@ -67,22 +63,10 @@ namespace OpenRA.Scripting protected void Unbind(Type targetType) { -#if NET5_0_OR_GREATER // NOTE: In newer versions of .NET modifying the collection by calling Remove while iterating over it is valid foreach (var m in members) if (targetType == m.Value.Target.GetType()) members.Remove(m.Key); -#else - // PERF: Re-use instead of allocating a new list on each unbind - membersToRemove.Clear(); - - foreach (var m in members) - if (targetType == m.Value.Target.GetType()) - membersToRemove.Add(m.Key); - - foreach (var m in membersToRemove) - members.Remove(m); -#endif } public bool ContainsKey(string key) { return members.ContainsKey(key); } diff --git a/OpenRA.Game/StreamExts.cs b/OpenRA.Game/StreamExts.cs index fe3612bf67..6b4a6b5bd3 100644 --- a/OpenRA.Game/StreamExts.cs +++ b/OpenRA.Game/StreamExts.cs @@ -14,6 +14,7 @@ using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; namespace OpenRA @@ -160,11 +161,7 @@ namespace OpenRA while ((b = s.ReadUInt8()) != 0) bytes.Add(b); -#if NET5_0_OR_GREATER - return Encoding.ASCII.GetString(System.Runtime.InteropServices.CollectionsMarshal.AsSpan(bytes)); -#else - return Encoding.ASCII.GetString(bytes.ToArray()); -#endif + return Encoding.ASCII.GetString(CollectionsMarshal.AsSpan(bytes)); } public static string ReadAllText(this Stream s) diff --git a/OpenRA.Game/Support/AssemblyLoader.cs b/OpenRA.Game/Support/AssemblyLoader.cs index de6fa2ebd7..ed8bb9d97d 100644 --- a/OpenRA.Game/Support/AssemblyLoader.cs +++ b/OpenRA.Game/Support/AssemblyLoader.cs @@ -9,9 +9,7 @@ */ #endregion -// Not used/usable on Mono. Only used for Dotnet Core. // Based on https://github.com/natemcmaster/DotNetCorePlugins and used under the terms of the Apache 2.0 license -#if NET5_0_OR_GREATER using System; using System.Collections.Generic; using System.IO; @@ -362,4 +360,3 @@ namespace OpenRA.Support } } } -#endif diff --git a/OpenRA.Game/Support/HttpClientFactory.cs b/OpenRA.Game/Support/HttpClientFactory.cs index 7450e9d3aa..a9ab543d6c 100644 --- a/OpenRA.Game/Support/HttpClientFactory.cs +++ b/OpenRA.Game/Support/HttpClientFactory.cs @@ -16,10 +16,8 @@ namespace OpenRA.Support { public static class HttpClientFactory { -#if NET5_0_OR_GREATER const int MaxConnectionPerServer = 20; static readonly TimeSpan ConnectionLifeTime = TimeSpan.FromMinutes(1); -#endif static readonly Lazy Handler = new(GetHandler); @@ -30,7 +28,6 @@ namespace OpenRA.Support static HttpMessageHandler GetHandler() { -#if NET5_0_OR_GREATER return new SocketsHttpHandler { // https://github.com/dotnet/corefx/issues/26895 @@ -40,9 +37,6 @@ namespace OpenRA.Support PooledConnectionIdleTimeout = ConnectionLifeTime, MaxConnectionsPerServer = MaxConnectionPerServer }; -#else - return new HttpClientHandler(); -#endif } } } diff --git a/OpenRA.Mods.Cnc/SpriteLoaders/ShpRemasteredLoader.cs b/OpenRA.Mods.Cnc/SpriteLoaders/ShpRemasteredLoader.cs index 3bc3e785cb..87bd2f8057 100644 --- a/OpenRA.Mods.Cnc/SpriteLoaders/ShpRemasteredLoader.cs +++ b/OpenRA.Mods.Cnc/SpriteLoaders/ShpRemasteredLoader.cs @@ -98,13 +98,10 @@ namespace OpenRA.Mods.Cnc.SpriteLoaders if (metaStream != null) { string metaText; -#if NET5_0_OR_GREATER using (metaStream) using (var metaReader = new StreamReader(metaStream, bufferSize: 64)) metaText = metaReader.ReadToEnd(); -#else - metaText = metaStream.ReadAllText(); -#endif + var meta = MetaRegex.Match(metaText); var crop = Rectangle.FromLTRB( ParseGroup(meta, "left"), ParseGroup(meta, "top"), diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs index 734174be4c..c9927d5ed3 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs @@ -497,22 +497,4 @@ namespace OpenRA.Mods.Cnc.UtilityCommands Map.ActorDefinitions = Map.ActorDefinitions.Concat(nodes).ToArray(); } } - -#if !NET6_0_OR_GREATER - public static class Extensions - { - /// - /// Only used for Mono builds. .NET 6 added the exact same thing. - /// - public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) - { - var knownKeys = new HashSet(); - foreach (var element in source) - { - if (knownKeys.Add(keySelector(element))) - yield return element; - } - } - } -#endif } diff --git a/OpenRA.Mods.Common/Orders/UnitOrderGenerator.cs b/OpenRA.Mods.Common/Orders/UnitOrderGenerator.cs index d24077a52e..70847aa2d0 100644 --- a/OpenRA.Mods.Common/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Mods.Common/Orders/UnitOrderGenerator.cs @@ -159,15 +159,8 @@ namespace OpenRA.Mods.Common.Orders if (mi.Modifiers.HasModifier(Modifiers.Alt)) modifiers |= TargetModifiers.ForceMove; - // The Select(x => x) is required to work around an issue on mono 5.0 - // where calling OrderBy* on SelectManySingleSelectorIterator can in some - // circumstances (which we were unable to identify) replace entries in the - // enumeration with duplicates of other entries. - // Other action that replace the SelectManySingleSelectorIterator with a - // different enumerator type (e.g. .Where(true) or .ToList()) also work. var orders = self.TraitsImplementing() .SelectMany(trait => trait.Orders.Select(x => new { Trait = trait, Order = x })) - .Select(x => x) .OrderByDescending(x => x.Order.OrderPriority) .ToList(); diff --git a/OpenRA.Mods.Common/Traits/Buildings/Exit.cs b/OpenRA.Mods.Common/Traits/Buildings/Exit.cs index c75fd5aa45..78c7be6a4d 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Exit.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Exit.cs @@ -48,14 +48,9 @@ namespace OpenRA.Mods.Common.Traits { public static Exit NearestExitOrDefault(this Actor actor, WPos pos, string productionType = null, Func p = null) { - // The .ToList() is required to work around a bug/unexpected behaviour in mono, where - // the ThenBy clause makes the FirstOrDefault behave differently than under .NET. - // This is important because p may have side-effects that trigger a desync if not - // called on the same exits in the same order! var all = Exits(actor, productionType) .OrderByDescending(e => e.Info.Priority) - .ThenBy(e => (actor.World.Map.CenterOfCell(actor.Location + e.Info.ExitCell) - pos).LengthSquared) - .ToList(); + .ThenBy(e => (actor.World.Map.CenterOfCell(actor.Location + e.Info.ExitCell) - pos).LengthSquared); #pragma warning disable RCS1077 // Optimize LINQ method call. return p != null ? all.FirstOrDefault(p) : all.FirstOrDefault(); diff --git a/OpenRA.sln b/OpenRA.sln index 7625a59d00..79a8cd8bad 100644 --- a/OpenRA.sln +++ b/OpenRA.sln @@ -72,11 +72,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9E2FAACA-DADB-4EEB-9898-2B0269F45E69} EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = OpenRA.Game\OpenRA.Game.csproj - Policies = $0 - $0.DotNetNamingPolicy = $1 - $0.TextStylePolicy = $7 - outputpath = . - EndGlobalSection EndGlobal diff --git a/configure-system-libraries.sh b/configure-system-libraries.sh index 1c2ceb1c3f..363e07a255 100755 --- a/configure-system-libraries.sh +++ b/configure-system-libraries.sh @@ -8,48 +8,29 @@ set -o errexit || exit $? -patch_config() +create_symlinks() { LABEL=$1 SEARCHDIRS=$2 - CONFIG=$3 - REPLACE=$4 - SEARCH=$5 + REPLACE=$3 + SEARCH=$4 - if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= bin/OpenRA.dll)" = "0" ]; then - # Exit early if the file has already been patched - grep -q "target=\"${REPLACE}\"" "${CONFIG}" || return 0 - - printf "Searching for %s... " "${LABEL}" - for DIR in ${SEARCHDIRS} ; do - for LIB in ${SEARCH}; do - if [ -f "${DIR}/${LIB}" ]; then - echo "${LIB}" - sed "s|target=\"${REPLACE}\"|target=\"${DIR}/${LIB}\"|" "${CONFIG}" > "${CONFIG}.temp" - mv "${CONFIG}.temp" "${CONFIG}" - return 0 - fi - done - done - else - # .NET 6 does not support .config files, so we must use symlinks instead - # Exit early if the symlink already exists - if [ -L "bin/${REPLACE}" ]; then - return 0 - fi - - printf "Searching for %s... " "${LABEL}" - for DIR in ${SEARCHDIRS} ; do - for LIB in ${SEARCH}; do - if [ -f "${DIR}/${LIB}" ]; then - echo "${LIB}" - ln -s "${DIR}/${LIB}" "bin/${REPLACE}" - return 0 - fi - done - done + # Exit early if the symlink already exists + if [ -L "bin/${REPLACE}" ]; then + return 0 fi + printf "Searching for %s... " "${LABEL}" + for DIR in ${SEARCHDIRS} ; do + for LIB in ${SEARCH}; do + if [ -f "${DIR}/${LIB}" ]; then + echo "${LIB}" + ln -s "${DIR}/${LIB}" "bin/${REPLACE}" + return 0 + fi + done + done + echo "FAILED" echo "OpenRA expects to find a file matching \"${SEARCH}\" in one of the following locations:" @@ -63,14 +44,14 @@ if [ "$(uname -s)" = "Darwin" ]; then else SEARCHDIRS="/usr/local/lib /usr/local/opt/openal-soft/lib" fi - patch_config "Lua 5.1" "${SEARCHDIRS}" bin/Eluant.dll.config lua51.dylib liblua5.1.dylib - patch_config SDL2 "${SEARCHDIRS}" bin/SDL2-CS.dll.config SDL2.dylib libSDL2-2.0.0.dylib - patch_config OpenAL "${SEARCHDIRS}" bin/OpenAL-CS.dll.config soft_oal.dylib libopenal.1.dylib - patch_config FreeType "${SEARCHDIRS}" bin/OpenRA.Platforms.Default.dll.config freetype6.dylib libfreetype.6.dylib + create_symlinks "Lua 5.1" "${SEARCHDIRS}" lua51.dylib liblua5.1.dylib + create_symlinks SDL2 "${SEARCHDIRS}" SDL2.dylib libSDL2-2.0.0.dylib + create_symlinks OpenAL "${SEARCHDIRS}" soft_oal.dylib libopenal.1.dylib + create_symlinks FreeType "${SEARCHDIRS}" freetype6.dylib libfreetype.6.dylib else SEARCHDIRS="/lib /lib64 /usr/lib /usr/lib64 /usr/lib/x86_64-linux-gnu /usr/lib/i386-linux-gnu /usr/lib/arm-linux-gnueabihf /usr/lib/aarch64-linux-gnu /usr/lib/powerpc64le-linux-gnu /usr/lib/mipsel-linux-gnu /usr/local/lib /opt/lib /opt/local/lib /app/lib" - patch_config "Lua 5.1" "${SEARCHDIRS}" bin/Eluant.dll.config lua51.so "liblua.so.5.1.5 liblua5.1.so.5.1 liblua5.1.so.0 liblua.so.5.1 liblua-5.1.so liblua5.1.so" - patch_config SDL2 "${SEARCHDIRS}" bin/SDL2-CS.dll.config SDL2.so "libSDL2-2.0.so.0 libSDL2-2.0.so libSDL2.so" - patch_config OpenAL "${SEARCHDIRS}" bin/OpenAL-CS.dll.config soft_oal.so "libopenal.so.1 libopenal.so" - patch_config FreeType "${SEARCHDIRS}" bin/OpenRA.Platforms.Default.dll.config freetype6.so "libfreetype.so.6 libfreetype.so" + create_symlinks "Lua 5.1" "${SEARCHDIRS}" lua51.so "liblua.so.5.1.5 liblua5.1.so.5.1 liblua5.1.so.0 liblua.so.5.1 liblua-5.1.so liblua5.1.so" + create_symlinks SDL2 "${SEARCHDIRS}" SDL2.so "libSDL2-2.0.so.0 libSDL2-2.0.so libSDL2.so" + create_symlinks OpenAL "${SEARCHDIRS}" soft_oal.so "libopenal.so.1 libopenal.so" + create_symlinks FreeType "${SEARCHDIRS}" freetype6.so "libfreetype.so.6 libfreetype.so" fi diff --git a/launch-dedicated.sh b/launch-dedicated.sh index 8f195f9002..2f728e81fc 100755 --- a/launch-dedicated.sh +++ b/launch-dedicated.sh @@ -9,11 +9,6 @@ set -o errexit || exit $? ENGINEDIR=$(dirname "$0") -if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= "${ENGINEDIR}/bin/OpenRA.Server.dll")" = "0" ]; then - RUNTIME_LAUNCHER="mono --debug" -else - RUNTIME_LAUNCHER="dotnet" -fi Name="${Name:-"Dedicated Server"}" Mod="${Mod:-"ra"}" @@ -38,7 +33,7 @@ FloodLimitJoinCooldown="${FloodLimitJoinCooldown:-"5000"}" SupportDir="${SupportDir:-""}" while true; do - ${RUNTIME_LAUNCHER} "${ENGINEDIR}/bin/OpenRA.Server.dll" Engine.EngineDir=".." Game.Mod="$Mod" \ + dotnet "${ENGINEDIR}/bin/OpenRA.Server.dll" Engine.EngineDir=".." Game.Mod="$Mod" \ Server.Name="$Name" \ Server.Map="$Map" \ Server.ListenPort="$ListenPort" \ diff --git a/launch-game.sh b/launch-game.sh index c9ed268a36..980306c3d5 100755 --- a/launch-game.sh +++ b/launch-game.sh @@ -2,11 +2,6 @@ set -o errexit || exit $? ENGINEDIR=$(dirname "$0") -if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= "${ENGINEDIR}/bin/OpenRA.dll")" = "0" ]; then - RUNTIME_LAUNCHER="mono --debug" -else - RUNTIME_LAUNCHER="dotnet" -fi if command -v python3 >/dev/null 2>&1; then LAUNCHPATH=$(python3 -c 'import os,sys; print(os.path.realpath(sys.argv[1]))' "$0") @@ -34,7 +29,7 @@ then fi # Launch the engine with the appropriate arguments -${RUNTIME_LAUNCHER} "${ENGINEDIR}/bin/OpenRA.dll" Engine.EngineDir=".." Engine.LaunchPath="${LAUNCHPATH}" ${MODARG} "$@" && rc=0 || rc=$? +dotnet "${ENGINEDIR}/bin/OpenRA.dll" Engine.EngineDir=".." Engine.LaunchPath="${LAUNCHPATH}" ${MODARG} "$@" && rc=0 || rc=$? # Show a crash dialog if something went wrong if [ "${rc}" != 0 ] && [ "${rc}" != 1 ]; then diff --git a/packaging/functions.sh b/packaging/functions.sh index 010e767c09..d1175ef893 100755 --- a/packaging/functions.sh +++ b/packaging/functions.sh @@ -11,7 +11,6 @@ # SRC_PATH: Path to the root OpenRA directory # DEST_PATH: Path to the root of the install destination (will be created if necessary) # TARGETPLATFORM: Platform type (win-x86, win-x64, osx-x64, osx-arm64, linux-x64, linux-arm64, unix-generic) -# RUNTIME: Runtime type (net6, mono) # COPY_GENERIC_LAUNCHER: If set to True the OpenRA.exe will also be copied (True, False) # COPY_CNC_DLL: If set to True the OpenRA.Mods.Cnc.dll will also be copied (True, False) # COPY_D2K_DLL: If set to True the OpenRA.Mods.D2k.dll will also be copied (True, False) @@ -29,59 +28,14 @@ install_assemblies() ( SRC_PATH="${1}" DEST_PATH="${2}" TARGETPLATFORM="${3}" - RUNTIME="${4}" - COPY_GENERIC_LAUNCHER="${5}" - COPY_CNC_DLL="${6}" - COPY_D2K_DLL="${7}" + COPY_GENERIC_LAUNCHER="${4}" + COPY_CNC_DLL="${5}" + COPY_D2K_DLL="${6}" ORIG_PWD=$(pwd) cd "${SRC_PATH}" - if [ "${RUNTIME}" = "mono" ]; then - echo "Building assemblies" - rm -rf "${SRC_PATH}/OpenRA."*/obj || : - rm -rf "${SRC_PATH:?}/bin" || : - - msbuild -verbosity:m -nologo -t:Build -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}" - if [ "${TARGETPLATFORM}" = "unix-generic" ]; then - ./configure-system-libraries.sh - fi - - if [ "${COPY_GENERIC_LAUNCHER}" != "True" ]; then - rm "${SRC_PATH}/bin/OpenRA.dll" - fi - - if [ "${COPY_CNC_DLL}" != "True" ]; then - rm "${SRC_PATH}/bin/OpenRA.Mods.Cnc.dll" - fi - - if [ "${COPY_D2K_DLL}" != "True" ]; then - rm "${SRC_PATH}/bin/OpenRA.Mods.D2k.dll" - fi - - cd "${ORIG_PWD}" - - echo "Installing engine to ${DEST_PATH}" - install -d "${DEST_PATH}" - - for LIB in "${SRC_PATH}/bin/"*.dll "${SRC_PATH}/bin/"*.dll.config; do - install -m644 "${LIB}" "${DEST_PATH}" - done - - if [ "${TARGETPLATFORM}" = "linux-x64" ] || [ "${TARGETPLATFORM}" = "linux-arm64" ]; then - for LIB in "${SRC_PATH}/bin/"*.so; do - install -m755 "${LIB}" "${DEST_PATH}" - done - fi - - if [ "${TARGETPLATFORM}" = "osx-x64" ] || [ "${TARGETPLATFORM}" = "osx-arm64" ]; then - for LIB in "${SRC_PATH}/bin/"*.dylib; do - install -m755 "${LIB}" "${DEST_PATH}" - done - fi - else - dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -p:CopyGenericLauncher="${COPY_GENERIC_LAUNCHER}" -p:CopyCncDll="${COPY_CNC_DLL}" -p:CopyD2kDll="${COPY_D2K_DLL}" -r "${TARGETPLATFORM}" -p:PublishDir="${DEST_PATH}" --self-contained true - fi + dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -p:CopyGenericLauncher="${COPY_GENERIC_LAUNCHER}" -p:CopyCncDll="${COPY_CNC_DLL}" -p:CopyD2kDll="${COPY_D2K_DLL}" -r "${TARGETPLATFORM}" -p:PublishDir="${DEST_PATH}" --self-contained true cd "${ORIG_PWD}" ) @@ -131,7 +85,7 @@ install_data() ( done ) -# Compile and publish (using Mono) a windows launcher with the specified mod details to the target directory +# Compile and publish a windows launcher with the specified mod details to the target directory # Arguments: # SRC_PATH: Path to the root OpenRA directory # DEST_PATH: Path to the root of the install destination (will be created if necessary) diff --git a/packaging/linux/buildpackage.sh b/packaging/linux/buildpackage.sh index 219554df5d..df5a2b79f8 100755 --- a/packaging/linux/buildpackage.sh +++ b/packaging/linux/buildpackage.sh @@ -67,7 +67,7 @@ build_appimage() { IS_D2K="True" fi - install_assemblies "${SRCDIR}" "${APPDIR}/usr/lib/openra" "linux-x64" "net6" "True" "True" "${IS_D2K}" + install_assemblies "${SRCDIR}" "${APPDIR}/usr/lib/openra" "linux-x64" "True" "True" "${IS_D2K}" install_data "${SRCDIR}" "${APPDIR}/usr/lib/openra" "${MOD_ID}" set_engine_version "${TAG}" "${APPDIR}/usr/lib/openra" set_mod_version "${TAG}" "${APPDIR}/usr/lib/openra/mods/${MOD_ID}/mod.yaml" "${APPDIR}/usr/lib/openra/mods/${MOD_ID}-content/mod.yaml" diff --git a/packaging/linux/openra-server.in b/packaging/linux/openra-server.in index a07ae65d07..c41f123177 100755 --- a/packaging/linux/openra-server.in +++ b/packaging/linux/openra-server.in @@ -5,8 +5,6 @@ cd "{GAME_INSTALL_DIR}" if test -f "OpenRA.Server"; then ./OpenRA.Server Game.Mod={MODID} "$@" -elif command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= OpenRA.Server.dll)" = "0" ]; then - mono {DEBUG} OpenRA.Server.dll Game.Mod={MODID} "$@" else dotnet OpenRA.Server.dll Game.Mod={MODID} "$@" fi diff --git a/packaging/linux/openra.in b/packaging/linux/openra.in index 3a02e3e87b..d1b09498f6 100755 --- a/packaging/linux/openra.in +++ b/packaging/linux/openra.in @@ -13,8 +13,6 @@ fi # Run the game if test -f "OpenRA"; then ./OpenRA Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@" && rc=0 || rc=$? -elif command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= OpenRA.dll)" = "0" ]; then - mono {DEBUG} OpenRA.dll Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@" && rc=0 || rc=$? else dotnet OpenRA.dll Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@" && rc=0 || rc=$? fi diff --git a/packaging/macos/apphost-mono.c b/packaging/macos/apphost-mono.c deleted file mode 100644 index 2648e48af6..0000000000 --- a/packaging/macos/apphost-mono.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ - -// -// A custom apphost is required (instead of just invoking `mono OpenRA.dll ...` directly) -// because macOS will only properly associate dock icons and tooltips to windows that are -// created by a process in the Contents/MacOS directory (not subdirectories). -// -// Based on https://github.com/mono/monodevelop/blob/main/main/build/MacOSX/monostub.mm - -#include -#include -#include - -typedef int (* mono_main)(int argc, char **argv); - -int main(int argc, char **argv) -{ - // TODO: This snippet increasing the open file limit was copied from - // the monodevelop launcher stub. It may not be needed for OpenRA. - struct rlimit limit; - if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < 1024) - { - limit.rlim_cur = limit.rlim_max < 1024 ? limit.rlim_max : 1024; - setrlimit(RLIMIT_NOFILE, &limit); - } - - void *libmono = dlopen(argv[1], RTLD_LAZY); - if (libmono == NULL) - { - fprintf(stderr, "Failed to load libmonosgen-2.0.dylib: %s\n", dlerror()); - return 1; - } - - mono_main _mono_main = (mono_main)dlsym(libmono, "mono_main"); - if (!_mono_main) - { - fprintf(stderr, "Could not load mono_main(): %s\n", dlerror()); - return 1; - } - - return _mono_main(argc - 1, &argv[1]); -} diff --git a/packaging/macos/buildpackage.sh b/packaging/macos/buildpackage.sh index 7d2847c7bb..8f11528364 100755 --- a/packaging/macos/buildpackage.sh +++ b/packaging/macos/buildpackage.sh @@ -75,9 +75,8 @@ build_app() { fi # Install engine and mod files - install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/x86_64" "osx-x64" "net6" "True" "True" "${IS_D2K}" - install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/arm64" "osx-arm64" "net6" "True" "True" "${IS_D2K}" - install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/mono" "osx-x64" "mono" "True" "True" "${IS_D2K}" + install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/x86_64" "osx-x64" "True" "True" "${IS_D2K}" + install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/arm64" "osx-arm64" "True" "True" "${IS_D2K}" install_data "${SRCDIR}" "${LAUNCHER_RESOURCES_DIR}" "${MOD_ID}" set_engine_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}" @@ -114,7 +113,6 @@ echo "Building launchers" # Prepare generic template for the mods to duplicate and customize TEMPLATE_DIR="${BUILTDIR}/template.app" mkdir -p "${TEMPLATE_DIR}/Contents/Resources" -mkdir -p "${TEMPLATE_DIR}/Contents/MacOS/mono" mkdir -p "${TEMPLATE_DIR}/Contents/MacOS/x86_64" mkdir -p "${TEMPLATE_DIR}/Contents/MacOS/arm64" @@ -122,22 +120,20 @@ echo "APPL????" > "${TEMPLATE_DIR}/Contents/PkgInfo" cp Info.plist.in "${TEMPLATE_DIR}/Contents/Info.plist" modify_plist "{DEV_VERSION}" "${TAG}" "${TEMPLATE_DIR}/Contents/Info.plist" modify_plist "{FAQ_URL}" "https://wiki.openra.net/FAQ" "${TEMPLATE_DIR}/Contents/Info.plist" -modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.11" "${TEMPLATE_DIR}/Contents/Info.plist" +modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.15" "${TEMPLATE_DIR}/Contents/Info.plist" # Compile universal (x86_64 + arm64) arch-specific apphosts clang apphost.c -o "${TEMPLATE_DIR}/Contents/MacOS/apphost-x86_64" -framework AppKit -target x86_64-apple-macos10.15 clang apphost.c -o "${TEMPLATE_DIR}/Contents/MacOS/apphost-arm64" -framework AppKit -target arm64-apple-macos10.15 -clang apphost-mono.c -o "${TEMPLATE_DIR}/Contents/MacOS/apphost-mono" -framework AppKit -target x86_64-apple-macos10.11 -clang checkmono.c -o "${TEMPLATE_DIR}/Contents/MacOS/checkmono" -framework AppKit -target x86_64-apple-macos10.11 # Compile universal (x86_64 + arm64) Launcher -clang launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" -framework AppKit -target x86_64-apple-macos10.11 +clang launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" -framework AppKit -target x86_64-apple-macos10.15 clang launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher-arm64" -framework AppKit -target arm64-apple-macos10.15 lipo -create -output "${TEMPLATE_DIR}/Contents/MacOS/Launcher" "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Launcher-arm64" rm "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Launcher-arm64" # Compile universal (x86_64 + arm64) Utility -clang utility.m -o "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" -framework AppKit -target x86_64-apple-macos10.11 +clang utility.m -o "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" -framework AppKit -target x86_64-apple-macos10.15 clang utility.m -o "${TEMPLATE_DIR}/Contents/MacOS/Utility-arm64" -framework AppKit -target arm64-apple-macos10.15 lipo -create -output "${TEMPLATE_DIR}/Contents/MacOS/Utility" "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Utility-arm64" rm "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Utility-arm64" @@ -197,7 +193,7 @@ SetFile -a C "/Volumes/OpenRA" # Replace duplicate .NET runtime files with hard links to improve compression for MOD in "Red Alert" "Tiberian Dawn"; do - for p in "x86_64" "arm64" "mono"; do + for p in "x86_64" "arm64"; do for f in "/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/${p}"/*; do g="/Volumes/OpenRA/OpenRA - Dune 2000.app/Contents/MacOS/${p}/"$(basename "${f}") hashf=$(shasum "${f}" | awk '{ print $1 }') || : @@ -212,19 +208,17 @@ for MOD in "Red Alert" "Tiberian Dawn"; do done for MOD in "Red Alert" "Tiberian Dawn" "Dune 2000"; do - for p in "arm64" "mono"; do - for f in "/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/x86_64"/*; do - g="/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/${p}/"$(basename "${f}") - if [ -e "${g}" ]; then - hashf=$(shasum "${f}" | awk '{ print $1 }') || : - hashg=$(shasum "${g}" | awk '{ print $1 }') || : - if [ -n "${hashf}" ] && [ "${hashf}" = "${hashg}" ]; then - echo "Deduplicating ${f}" - rm "${f}" - ln "${g}" "${f}" - fi + for f in "/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/x86_64"/*; do + g="/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/arm64/"$(basename "${f}") + if [ -e "${g}" ]; then + hashf=$(shasum "${f}" | awk '{ print $1 }') || : + hashg=$(shasum "${g}" | awk '{ print $1 }') || : + if [ -n "${hashf}" ] && [ "${hashf}" = "${hashg}" ]; then + echo "Deduplicating ${f}" + rm "${f}" + ln "${g}" "${f}" fi - done + fi done done diff --git a/packaging/macos/checkmono.c b/packaging/macos/checkmono.c deleted file mode 100644 index 708927bb7c..0000000000 --- a/packaging/macos/checkmono.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ - -// -// NOTE: Mono.framework only ships intel dylibs, so cannot be loaded by the arm64 slice of the Launcher utility. -// Splitting checkmono into its own intel-only utility allows it to be called through rosetta if the user -// wants to force the game to run under mono-through-rosetta. -// -// Based on https://github.com/mono/monodevelop/blob/main/main/build/MacOSX/monostub.mm and https://github.com/mono/monodevelop/blob/main/main/build/MacOSX/monostub-utils.h - -#include -#include -#include - -#define SYSTEM_MONO_PATH "/Library/Frameworks/Mono.framework/Versions/Current/" -#define SYSTEM_MONO_MIN_VERSION "6.12" - -typedef char *(* mono_get_runtime_build_info)(void); - -int main(int argc, char **argv) -{ - void *libmono = dlopen(SYSTEM_MONO_PATH "lib/libmonosgen-2.0.dylib", RTLD_LAZY); - if (libmono == NULL) - { - fprintf (stderr, "Failed to load libmonosgen-2.0.dylib: %s\n", dlerror()); - return 1; - } - - mono_get_runtime_build_info _mono_get_runtime_build_info = (mono_get_runtime_build_info)dlsym(libmono, "mono_get_runtime_build_info"); - if (!_mono_get_runtime_build_info) - { - fprintf(stderr, "Could not load mono_get_runtime_build_info(): %s\n", dlerror()); - return 1; - } - - char *version = _mono_get_runtime_build_info(); - char *req_end, *end; - long req_val, val; - char *req_version = SYSTEM_MONO_MIN_VERSION; - - while (*req_version && *version) - { - req_val = strtol(req_version, &req_end, 10); - if (req_version == req_end || (*req_end && *req_end != '.')) - { - fprintf(stderr, "Bad version requirement string '%s'\n", req_end); - return 1; - } - - val = strtol(version, &end, 10); - if (version == end || val < req_val) - return 1; - - if (val > req_val) - return 0; - - if (*req_end == '.' && *end != '.') - return 1; - - req_version = req_end; - if (*req_version) - req_version++; - - version = end + 1; - } - - return 0; -} diff --git a/packaging/macos/launcher.m b/packaging/macos/launcher.m index 17d9a3633c..8c529625a3 100644 --- a/packaging/macos/launcher.m +++ b/packaging/macos/launcher.m @@ -12,8 +12,6 @@ #include #include -#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/" -#define SYSTEM_MONO_MIN_VERSION @"6.12" #define DOTNET_MIN_MACOS_VERSION 10.15 @interface OpenRALauncher : NSObject @@ -38,29 +36,6 @@ NSTask *gameTask; return @"OpenRA"; } -- (void)exitWithMonoPrompt -{ - [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular]; - [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; - - NSString *modName = [self modName]; - NSString *title = [NSString stringWithFormat: @"Cannot launch %@", modName]; - NSString *message = [NSString stringWithFormat: @"%@ requires Mono %@ or later. Please install Mono and try again.", modName, SYSTEM_MONO_MIN_VERSION]; - - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:title]; - [alert setInformativeText:message]; - [alert addButtonWithTitle:@"Download Mono"]; - [alert addButtonWithTitle:@"Quit"]; - NSInteger answer = [alert runModal]; - [alert release]; - - if (answer == NSAlertFirstButtonReturn) - [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString:@"https://www.mono-project.com/download/"]]; - - exit(1); -} - - (void)exitWithCrashPrompt { [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular]; @@ -126,7 +101,7 @@ NSTask *gameTask; } [self launchGameWithArgs: gameArgs]; - [gameArgs release]; + [gameArgs release]; } - (void)applicationWillFinishLaunching:(NSNotification *)aNotification @@ -155,15 +130,6 @@ NSTask *gameTask; return YES; } -- (int)hasValidMono -{ - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath: [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/MacOS/checkmono"]]; - [task launch]; - [task waitUntilExit]; - - return [task terminationStatus] == 0; -} - (void)launchGameWithArgs: (NSArray *)gameArgs { @@ -175,16 +141,6 @@ NSTask *gameTask; launched = YES; - BOOL useMono = NO; - - if (@available(macOS 10.15, *)) - useMono = [[[NSProcessInfo processInfo] environment]objectForKey:@"OPENRA_PREFER_MONO"] != nil; - else - useMono = YES; - - if (useMono && ![self hasValidMono]) - [self exitWithMonoPrompt]; - // Default values - can be overriden by setting certain keys Info.plist NSString *modId = nil; @@ -203,30 +159,21 @@ NSTask *gameTask; NSString *dllPath; NSString *hostPath; - if (useMono) + size_t size; + cpu_type_t type; + size = sizeof(type); + + if (sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0 && (type & 0xFF) == CPU_TYPE_ARM) { - launchPath = [exePath stringByAppendingPathComponent: @"apphost-mono"]; - hostPath = [SYSTEM_MONO_PATH stringByAppendingPathComponent: @"lib/libmonosgen-2.0.dylib"];; - dllPath = [exePath stringByAppendingPathComponent: @"mono/OpenRA.dll"]; + launchPath = [exePath stringByAppendingPathComponent: @"apphost-arm64"]; + hostPath = [exePath stringByAppendingPathComponent: @"arm64/libhostfxr.dylib"];; + dllPath = [exePath stringByAppendingPathComponent: @"arm64/OpenRA.dll"]; } else { - size_t size; - cpu_type_t type; - size = sizeof(type); - - if (sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0 && (type & 0xFF) == CPU_TYPE_ARM) - { - launchPath = [exePath stringByAppendingPathComponent: @"apphost-arm64"]; - hostPath = [exePath stringByAppendingPathComponent: @"arm64/libhostfxr.dylib"];; - dllPath = [exePath stringByAppendingPathComponent: @"arm64/OpenRA.dll"]; - } - else - { - launchPath = [exePath stringByAppendingPathComponent: @"apphost-x86_64"]; - hostPath = [exePath stringByAppendingPathComponent: @"x86_64/libhostfxr.dylib"];; - dllPath = [exePath stringByAppendingPathComponent: @"x86_64/OpenRA.dll"]; - } + launchPath = [exePath stringByAppendingPathComponent: @"apphost-x86_64"]; + hostPath = [exePath stringByAppendingPathComponent: @"x86_64/libhostfxr.dylib"];; + dllPath = [exePath stringByAppendingPathComponent: @"x86_64/OpenRA.dll"]; } NSString *appPath = [exePath stringByAppendingPathComponent: @"Launcher"]; diff --git a/packaging/macos/utility.m b/packaging/macos/utility.m index 45f1121ad5..6eae6606e3 100644 --- a/packaging/macos/utility.m +++ b/packaging/macos/utility.m @@ -15,8 +15,6 @@ #include #include -#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/" -#define SYSTEM_MONO_MIN_VERSION @"6.12" #define DOTNET_MIN_MACOS_VERSION 10.15 typedef void* hostfxr_handle; @@ -35,56 +33,6 @@ typedef int32_t(*hostfxr_initialize_for_dotnet_command_line_fn)( typedef int32_t(*hostfxr_run_app_fn)(const hostfxr_handle host_context_handle); typedef int32_t(*hostfxr_close_fn)(const hostfxr_handle host_context_handle); -typedef int (*mono_main)(int argc, char **argv); - -int launch_mono(int argc, char **argv, char *modId) -{ - NSString *exePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/MacOS/"]; - NSString *hostPath = [SYSTEM_MONO_PATH stringByAppendingPathComponent: @"lib/libmonosgen-2.0.dylib"]; - NSString *dllPath = [exePath stringByAppendingPathComponent: @"mono/OpenRA.Utility.dll"]; - - // TODO: This snippet increasing the open file limit was copied from - // the monodevelop launcher stub. It may not be needed for OpenRA. - struct rlimit limit; - if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < 1024) - { - limit.rlim_cur = limit.rlim_max < 1024 ? limit.rlim_max : 1024; - setrlimit(RLIMIT_NOFILE, &limit); - } - - void *libmono = dlopen([hostPath UTF8String], RTLD_LAZY); - if (!libmono) - { - NSLog(@"Failed to load libmonosgen-2.0.dylib: %s\n", dlerror()); - return 1; - } - - mono_main _mono_main = (mono_main)dlsym(libmono, "mono_main"); - if (!_mono_main) - { - NSLog(@"Could not load mono_main(): %s\n", dlerror()); - return 1; - } - - // Insert hostpath, dll and modId as arguments. Overwrite the first argument which was used to launch this application. - char **newv = malloc((argc + 2) * sizeof(char*)); - if (!newv) - { - NSLog(@"Failed to allocate memory for args array.\n"); - return 1; - } - - newv[0] = (char*)[hostPath UTF8String]; - newv[1] = (char*)[dllPath UTF8String]; - newv[2] = modId; - for (int i = 1; i < argc; i++) - newv[i + 2] = argv[i]; - - int ret = _mono_main(argc + 2, newv); - free(newv); - - return ret; -} int launch_dotnet(int argc, char **argv, char *modId, bool isArmArchitecture) { @@ -173,32 +121,6 @@ int main(int argc, char **argv) size = sizeof(type); bool isArmArchitecture = sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0 && (type & 0xFF) == CPU_TYPE_ARM; - BOOL useMono = NO; - - // Before 10.15 macOS didn't support arm. - // Mono is compiled for intel only. - if (!isArmArchitecture) - { - if (@available(macOS 10.15, *)) - useMono = [[[NSProcessInfo processInfo] environment]objectForKey:@"OPENRA_PREFER_MONO"] != nil; - else - useMono = YES; - } - - if (useMono) - { - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath: [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/MacOS/checkmono"]]; - [task launch]; - [task waitUntilExit]; - - if ([task terminationStatus] != 0) - { - NSLog(@"Utility requires Mono %@ or later. Please install Mono and try again.\n", SYSTEM_MONO_MIN_VERSION); - return 1; - } - } - NSDictionary *plist = [[NSBundle mainBundle] infoDictionary]; char *modId; if (plist) @@ -216,11 +138,7 @@ int main(int argc, char **argv) setenv("ENGINE_DIR", (char*)[[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/Resources/"] UTF8String], 1); - int ret; - if (useMono) - ret = launch_mono(argc, argv, modId); - else - ret = launch_dotnet(argc, argv, modId, isArmArchitecture); + int ret = launch_dotnet(argc, argv, modId, isArmArchitecture); [pool release]; return ret; diff --git a/packaging/windows/buildpackage.sh b/packaging/windows/buildpackage.sh index caf2375410..9736acdb83 100755 --- a/packaging/windows/buildpackage.sh +++ b/packaging/windows/buildpackage.sh @@ -75,7 +75,7 @@ function build_platform() USE_PROGRAMFILES32="" fi - install_assemblies "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "net6" "False" "True" "True" + install_assemblies "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "False" "True" "True" install_data "${SRCDIR}" "${BUILTDIR}" "cnc" "d2k" "ra" set_engine_version "${TAG}" "${BUILTDIR}" set_mod_version "${TAG}" "${BUILTDIR}/mods/cnc/mod.yaml" "${BUILTDIR}/mods/d2k/mod.yaml" "${BUILTDIR}/mods/ra/mod.yaml" "${BUILTDIR}/mods/cnc-content/mod.yaml" "${BUILTDIR}/mods/d2k-content/mod.yaml" "${BUILTDIR}/mods/ra-content/mod.yaml" diff --git a/utility.sh b/utility.sh index 00ce9d467e..10bc7e080a 100755 --- a/utility.sh +++ b/utility.sh @@ -2,10 +2,5 @@ set -o errexit || exit $? ENGINEDIR=$(dirname "$0") -if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= "${ENGINEDIR}/bin/OpenRA.Utility.dll")" = "0" ]; then - RUNTIME_LAUNCHER="mono --debug" -else - RUNTIME_LAUNCHER="dotnet" -fi -ENGINE_DIR=.. ${RUNTIME_LAUNCHER} "${ENGINEDIR}/bin/OpenRA.Utility.dll" "$@" +ENGINE_DIR=.. dotnet "${ENGINEDIR}/bin/OpenRA.Utility.dll" "$@"