kwsch / pkNX

Pokémon (Nintendo Switch) ROM Editor & Randomizer
https://projectpokemon.org/home/forums/topic/48647-pknx-nintendo-switch-rom-editor-randomizer/
GNU General Public License v3.0
352 stars 108 forks source link

Fix Linux support #129

Closed CodingKoopa closed 3 years ago

CodingKoopa commented 3 years ago

This PR fixes some things so that this program can be compiled on Linux using msbuild from Mono, or dotnet build from the .NET SDK, and then ran using Mono.

image

The fixes are:

Known issues/concerns:

ColonelThirtyTwo commented 3 years ago

How did you get this to build on Linux? Having issues with dotnet build saying that the windows forms libraries are not available.

CodingKoopa commented 3 years ago

Ah, indeed I never documented what I did. I've went through both of the two methods of compiling pkNX, and fought with them until they both work. For you, I would recommend installing the .NET SDK preview if you can, that's what fixed that issue for me when it comes to building with dotnet build.

General Tips

Building with the .NET Core SDK

Steps

  1. Install the .NET Core SDK. You may install this using your distribution's package manager, or with the dotnet-install.sh script provided by the .NET Foundation. As of writing, the latest stable .NET Core SDK (5.x) doesn't seem to properly provide the Microsoft.NET.Sdk.WindowsDesktop SDK. It was necessary for me to install the .NET Core 6.0 SDK preview to successfully compile.
  2. Direct msbuild to the SDK locations (see here and here for the origins of this workaround). If you only have one .NET Core SDK installed and don't have Mono installed, this isn't necessary, but it doesn't seem to hurt in any case:
    export MSBuildSDKsPath=/usr/share/dotnet/sdk/$(dotnet --version)/Sdks
  3. Build the program:
    dotnet build

Troubleshooting

.NET Desktop SDK not found

error MSB4236: The SDK 'Microsoft.NET.Sdk.WindowsDesktop' specified could not be found.

Strangely, this issue I fixed by switching to the .NET SDK 6.0 preview.

Building with Mono

Steps

  1. Install the Mono framework from your distribution's package manager. As of writing, the version of the Roslyn compile included in latest stable Mono release (6.12.0) does not support C# 9 - it was necessary for me to install the latest Git version of Mono, although the nightly, alpha, or beta versions may work too.
  2. Install the Mono fork of msbuild from your distributions package manager. The Arch Linux package refers to this as the "Xamarin implementation" of msbuild, and retrieves it from here.
  3. Restore the Nuget dependencies and build the program, from the root of the repository. This certainly won't work right away - see the troubleshooting section for steps for making the build work.
    msbuild /r

Troubleshooting

Too old Mono Version

CSC : error CS1617: Invalid option '9' for /langversion. Use '/langversion:?' to list supported values.

Your Mono version isn't recent enough.

Too many open files

Cannot write to the output file "/home/koopa/Fountain/Documents/Projects/C#/pkNX/pkNX.Sprites/obj/Debug/net461/pkNX.Sprites.Properties.Resources.resources". Too many open files

I worked around this by raising the open file limit by running ulimit -n 70000.

.NET Desktop SDK not found

error MSB4236: The SDK 'Microsoft.NET.Sdk.WindowsDesktop' specified could not be found.
warning NETSDK1107: Microsoft.NET.Sdk.WindowsDesktop is required to build Windows desktop applications. 'UseWpf' and 'UseWindowsForms' are not supported by the current SDK.

Microsoft.NET.Sdk.WindowsDesktop is a type of .NET project SDK, specifically the .NET Desktop SDK, which includes WinForms. Mono has an implementation of WinForms, and for that reason I feel that it should be able to provide this. I couldn't get this error to go away, though. The maintainer of the pkHex AUR package has this same issue, and they never seemed to be able to work around it either. All in all, this feels like a bug or shortcoming in Mono to me. I did the bare minimum to get the project to compile without referencing this SDK.

Strangely, even when the error is resolved, but the warning is still outputted, the build process still can output a working Windows desktop application.

pkNX.WinForms/pkNX.WinForms.csproj

- <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
+ <Project Sdk="Microsoft.NET.Sdk">
   <ItemGroup Condition="'$(TargetFramework)' == 'net46'">
     <Reference Include="System.Configuration" />
   </ItemGroup>

+  <ItemGroup Condition="'$(TargetFramework)' == 'net461'">
+    <Reference Include="System.Windows.Forms" />
+  </ItemGroup>

Reference assemblies for .NET 5.0 not found

error MSB3971: The reference assemblies for ".NETFramework,Version=v5.0" were not found. You might be using an older .NET SDK to target .NET 5.0 or higher. Update Visual Studio and/or your .NET SDK.

I don't really know what the right solution to this would be, but I fixed this by hardcoding the .NET Framework version to one that seems to work. pkNX.Tests/pkNX.Tests.csproj

-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net461</TargetFramework>

pkNX.Sprites/pkNX.Sprites.csproj

-    <TargetFrameworks>net5.0;net461</TargetFrameworks>
+    <TargetFramework>net461</TargetFramework>

Usage

The built EXE, pkNX.WinForms/bin/Debug/net461/pkNX.exe, can be run with:

ColonelThirtyTwo commented 3 years ago

@CodingKoopa Thank you for the writeup.