mob-sakai / CSharpCompilerSettingsForUnity

Change the C# compiler (csc) used on your Unity project, as you like!
MIT License
289 stars 22 forks source link

Support 2021.1 #11

Open mob-sakai opened 3 years ago

mob-sakai commented 3 years ago

On 2021.1.a9 the "Apply" button is causing an exception, so I couldn't test it yet.

[Exception] InvalidOperationException: Sequence contains no matching element
Enumerable.First[TSource]() at <351e49e2a5bf4fd6beabb458ce2255f3>:0

ReflectionExtensions.Call() at <26e68dbb771b4491aa5f1dc8f99cc436>:0

Utils.RequestCompilation() at <26e68dbb771b4491aa5f1dc8f99cc436>:0

CscSettingsProvider+<>c.<OnGUI>b__9_1() at Library/PackageCache/com.coffee.csharp-compiler-settings@88d8659a14/Editor/CscSettingsProvider.cs:100
98:       serializedObject.ApplyModifiedProperties();
99:       File.WriteAllText(CscSettingsAsset.k_SettingsPath, JsonUtility.ToJson(serializedObject.targetObject, true));
-->100:       Utils.RequestCompilation();
101:   },
102:   onReload: () =>

InspectorGUI.DrawControl() at Library/PackageCache/com.coffee.csharp-compiler-settings@88d8659a14/Editor/InspectorGUI.cs:175
174:       if (onApply != null && GUILayout.Button(s_ApplyText))
-->175:           onApply();
176:   }

CscSettingsProvider.OnGUI() at Library/PackageCache/com.coffee.csharp-compiler-settings@88d8659a14/Editor/CscSettingsProvider.cs:94
93:   // Controls
-->94:   InspectorGUI.DrawControl(serializedObject.hasModifiedProperties,
95:       onRevert: () => { serializedObject = new SerializedObject(CscSettingsAsset.instance); },
96:       onApply: () =>

SettingsProvider.OnGUI() at <a19e86c7bf354115a4c6a5953c0575cb>:0

Originally posted by @SugoiDev in https://github.com/mob-sakai/CSharpCompilerSettingsForUnity/issues/6#issuecomment-750290039

mob-sakai commented 3 years ago

@VolodymyrBS @SugoiDev

Up to Unity 2020.x, we used to replace the compile process from the script, but that is no longer possible. After a brief investigation, the compile task has changed significantly since Unity 2021.1:

KuraiAndras commented 3 years ago

https://forum.unity.com/threads/unity-c-8-support.663757/page-7#post-6749023 So apparently this is happening.

SugoiDev commented 3 years ago

I found a way to replace the compiler on newer Unity versions. It was only lightly tested, but seems to work. You need to install the desired .NET sdk version first (https://dotnet.microsoft.com/download/dotnet/6.0). Then, we do some symlinking (or copying). I'm using 2022.1.0a9 and 6.0.100-rc.1.21463.6 as example below. Your installed .NET might have different version. Note: You need to rename or delete the original folders.

symlink (or copy) c:\Program Files\dotnet\ as c:\Program Files\Unity\Hub\Editor\2022.1.0a9\Editor\Data\NetCoreRuntime\

symlink (or copy) c:\Program Files\dotnet\sdk\6.0.100-rc.1.21463.6\Roslyn\bincore\ as c:\Program Files\Unity\Hub\Editor\2022.1.0a9\Editor\Data\DotNetSdkRoslyn\

neon-age commented 3 years ago

@mob-sakai I'm trying to get OpenSesame working on 2021.1, and found that we can set cscPath during compilationStarted in a ScriptCompilationData that is stored in activeBeeBuild.Driver.DataForBuildProgram

image

Decompiled UnityEditor.dll using dnSpy. (Rider can do that too) image image

I don't think we can do this per-assembly anymore (assemblyCompilationStarted is now obsolete and invoked during assemblyCompilationFinished). So the problem is that now OpenSesame is used to compile all of the assemblies, which results in accessibility errors when IgnoresAccessChecksToAttribute is added in places it doesn't belong to.

It might be possible to remove assemblies from ScriptCompilationData, so we can compile them manually afterwards, but it breaks other parts of Unity's compiler and I did not get it to work..

The other solution might be to modify OpenSesame compiler to check if assembly actually wants IgnoreAccessibility

mob-sakai commented 2 years ago

@KuraiAndras @SugoiDev @neon-age Thank you for your cooperations! I have been trying some ideas for a few days. I found a way to set up csc configuration for each assembly in 2021.x. :+1: https://github.com/mob-sakai/CSharpCompilerSettingsForUnity/blob/develop/Plugins/CSharpCompilerSettings/CustomCompiler_2021.cs

mob-sakai commented 2 years ago

In Unity 2021, any user code cannot be executed prior to the first compilation. In other words, we have to pass the compilation even if we use the built-in compiler.

For example, if you have code that accesses non-public members (with the custom compiler OpenSesame.Net.Compilers.Toolset), you should use CUSTOM_COMPILE symbol as follows:

using System;
using NUnit.Framework;

namespace IgnoreAccessibility
{
    public class IgnoreAccessibilityContent
    {
        private int privateNumber = 999;
    }

    public class IgnoreAccessibilityTest
    {
        [Test]
        public void GetPrivateField()
        {
#if CUSTOM_COMPILE
            Assert.AreEqual(new IgnoreAccessibilityContent().privateNumber, 999);
#else
            throw new NotImplementedException();
#endif
        }
    }
}
mob-sakai commented 2 years ago

@KuraiAndras @SugoiDev @neon-age v1.5.0 supports Unity 2021.1 or later. 👍 See For Unity 2021.1 or later section.

KuraiAndras commented 2 years ago

Nice work!