Closed pchote closed 3 years ago
Phase 2 is to merge and upgrade our windows and mono build processes, using msbuild
and the newer vs2017-format csproj. The new csproj format trims all the fat and rivals the Makefile in terms of conciseness and readability (i.e. still a bit weird and obtuse, but good enough) so we shouldn't lose anything by doing this. I have a local prototype which I aim to clean up and PR during this release cycle.
Phase 2.5 should be to replace our custom dependency fetching scripts with nuget references. I don't like Nuget, but we can't justify not using it at this point - and its mandatory if we want to switch over to .NET core in the future. Research and tests will be required here to work out how to handle our platform-specific dependencies.
Phase 3 is to remove the last uses of non-standard-2.0 code so so that we can switch to <TargetFramework>netstandard2.0</TargetFramework>
:
System.PlatformNotSupportedException
on mono.The game seems to otherwise run fine after hacking these out, so I don't expect any other major problems. This is a good motivation to investigate using Roslyn or another tool to compile the sync metadata during compilation, which I suspect will also help reduce the virus scanner false positives on Windows and reduce our load times.
The overall plan here has evolved a bit in the last year. Our goal is now to target netstandard2.1
as our baseline, with netcore3.1
as our primary runtime that is shipped inside our official packages. We aim to keep first-class (or as near as possible) support for mono to support older macOS, BSD, and anyone else who can't or doesn't want to run .NET Core.
The netstandard2.1
API includes System.Reflection.Emit
, so solves the sync code incompatibility. It also includes new networking APIs that would apparently allow us to use TLS for the game network connections.
This amended plan brings in some new constraints to work around:
.NET Core won't run <OutputType>Exe</OutputType>
+ <TargetFramework>netstandard2.1</TargetFramework>
. Applications must target <TargetFramework>netcoreapp3.1</TargetFramework>
directly. Mono does compile and run netstandard
-targeting exes, although the output binary confusingly has a dll extension. Compiling as <OutputType>Library</OutputType>
does not work, mono will not generate an entrypoint in this case.
Mod dlls depend on OpenRA.Game
, and netstandard
dlls cannot reference core or framework based projects. This means that mod dlls can't target netstandard
while OpenRA.Game
remains an exe.
.NET core does not parse <dllmap>
s, so projects must implement their own assembly handling if they want to be able to redirect to use system libraries. A silver lining here is that netstandard significantly improves the assembly handling APIs, which will allow us to eventually fix the mess inside ObjectCreator
.
NUnit test dlls cannot target netstandard
, and since there are no non-core TFMs that support netstandard2.1, we will have to disable OpenRA.Test.dll
when compiling under mono.
netstandard2.1
is only supported in mono >= 6.4. @jbeich raised the issue that freebsd currently only supports 5.10, but it looks like they are actively working towards 6.8 support. I'm not sure about the status of mono on the other major BSDs.
We don't yet have a consensus on exactly how to proceed, but my personal view (which may still contain factual inaccuracies/impossibilities) is that we should:
Change OpenRA.Game.exe
to a netstandard2.1
library, and change the mod and platform dlls to match.
Create a new OpenRA.Launcher
(or maybe just OpenRA
) project / executable to act as a single entry point for the game / server / utility (with --server
and --utility
args to distinguish the cases). This project dual targets netcoreapp3.1
/ netstandard2.1
for mono. The windows packaging (RedAlert.exe
etc) and SDK packaging would replace this with their own single-mod launchers.
OpenRA.PostProcess.exe
would similarly target dual netcore31
/ netstandard2.1
, and the csproj commands updated to call the exe or mono <path>.dll
.
Don't bother with the <dllmap>
replacement in the short term - people who want to use their system libraries can keep using mono for now.
Find a workaround to disable OpenRA.Test.dll
when compiling under mono.
Prototype and prepare PRs to support the above, but hold off merging until FreeBSD is ready to support it (provided this doesn't become too long). It may not be a major part of our player base, but I take our wide compatibility as a point of pride.
https://github.com/alanmcgovern/Mono.Nat/releases is back and it targets .NET Standard 2.0 now.
any news on this front? anyone working on this would like some help?
any news on this front? anyone working on this would like some help?
https://github.com/OpenRA/OpenRA/pull/17989 but neither me or pchote are having much time right now to fix the last issues, something wrong on osx for example.
well, you're in luck! my workstation is OSX! care to speed me up to the "something wrong"? you're talking about the
Unhandled exception. System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (0x80131040) File name: 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
???
Fixed by #17989.
The modern .NET ecosystem targets the .NET standard API, which defines a common set of APIs implemented by .NET Framework, NET Core, and Mono. The early standards were rather weak, limited by the narrow API surface of .NET Core. The 2.0 standard added, I believe, all the APIs that we need for OpenRA.
In addition to supporting .NET Core and bringing our tooling up to modern standards, this would allow us to use some useful third party libraries:
The main blocker is packaging Mono (>= 5.4) in the Linux AppImages, which is already a requirement for proper AppImage compatibility. .NET 4.7.1 is required on Windows, but raising this requirement shouldn't affect our compatibility there.