Eradicate ☠ Mono ☠

Co-Authored-By: Gustas <37534529+punkpun@users.noreply.github.com>
This commit is contained in:
michaeldgg2
2024-09-13 23:01:58 +02:00
committed by Pavel Penev
parent 5450572e0a
commit c7cc9a68fd
35 changed files with 89 additions and 634 deletions

View File

@@ -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

View File

@@ -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

4
.gitignore vendored
View File

@@ -25,10 +25,6 @@ IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP
\#*
.*.sw?
# Monodevelop
*.pidb
*.userprefs
# Mac OS X
.DS_Store

View File

@@ -18,8 +18,7 @@
</PropertyGroup>
<PropertyGroup>
<TargetFramework Condition="'$(MSBuildRuntimeType)'!='Mono'">net6.0</TargetFramework>
<TargetFramework Condition="'$(MSBuildRuntimeType)'=='Mono'">netstandard2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
@@ -54,8 +53,7 @@
<!-- StyleCop/Roslynator -->
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" />
<!-- Roslynator analyzers fail to run under Mono (AD0001) -->
<PackageReference Include="Roslynator.Analyzers" Version="4.2.0" PrivateAssets="All" Condition="'$(MSBuildRuntimeType)'!='Mono'" />
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.2.0" PrivateAssets="All" Condition="'$(MSBuildRuntimeType)'!='Mono'" />
<PackageReference Include="Roslynator.Analyzers" Version="4.2.0" PrivateAssets="All" />
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.2.0" PrivateAssets="All" />
</ItemGroup>
</Project>

View File

@@ -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`.

View File

@@ -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'

View File

@@ -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<K, V>(this Dictionary<K, V> 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<K, V>(this Dictionary<K, V> d, K k, Func<K, V> createFn)
@@ -510,39 +505,6 @@ namespace OpenRA
return result;
}
public static T[,] ResizeArray<T>(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<bool> 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);

View File

@@ -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.");

View File

@@ -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];

View File

@@ -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);

View File

@@ -2,14 +2,9 @@
<PropertyGroup>
<RootNamespace>OpenRA</RootNamespace>
</PropertyGroup>
<ItemGroup Condition="'$(MSBuildRuntimeType)'!='Mono'">
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="6.0.2" />
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition="'$(MSBuildRuntimeType)'=='Mono'">
<PackageReference Include="System.Collections.Immutable" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Linguini.Bundle" Version="0.8.1" />
<PackageReference Include="OpenRA-Eluant" Version="1.0.22" />
<PackageReference Include="Mono.NAT" Version="3.0.4" />

View File

@@ -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
{

View File

@@ -24,10 +24,6 @@ namespace OpenRA.Scripting
protected readonly ScriptContext Context;
readonly Dictionary<string, ScriptMemberWrapper> members = new();
#if !NET5_0_OR_GREATER
readonly List<string> membersToRemove = new List<string>();
#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); }

View File

@@ -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)

View File

@@ -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

View File

@@ -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<HttpMessageHandler> 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
}
}
}

View File

@@ -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"),

View File

@@ -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
{
/// <summary>
/// Only used for Mono builds. .NET 6 added the exact same thing.
/// </summary>
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var knownKeys = new HashSet<TKey>();
foreach (var element in source)
{
if (knownKeys.Add(keySelector(element)))
yield return element;
}
}
}
#endif
}

View File

@@ -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<IIssueOrder>()
.SelectMany(trait => trait.Orders.Select(x => new { Trait = trait, Order = x }))
.Select(x => x)
.OrderByDescending(x => x.Order.OrderPriority)
.ToList();

View File

@@ -48,14 +48,9 @@ namespace OpenRA.Mods.Common.Traits
{
public static Exit NearestExitOrDefault(this Actor actor, WPos pos, string productionType = null, Func<Exit, bool> 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();

View File

@@ -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

View File

@@ -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

View File

@@ -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" \

View File

@@ -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

View File

@@ -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)

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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 <dlfcn.h>
#include <stdio.h>
#include <sys/resource.h>
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]);
}

View File

@@ -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

View File

@@ -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 <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#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;
}

View File

@@ -12,8 +12,6 @@
#include <sys/sysctl.h>
#include <mach/machine.h>
#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 <NSApplicationDelegate>
@@ -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"];

View File

@@ -15,8 +15,6 @@
#include <sys/resource.h>
#include <mach/machine.h>
#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;

View File

@@ -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"

View File

@@ -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" "$@"