Rename to Rhino 7.app breaks mono c# compiler

As per the subject, I find that the rename to Rhino 7.app apparently breaks something with the csharp compiler, and with it my plugin, which compiles various types at runtime. Here’s a test command:

public class TestCsharpCompiler : Rhino.Commands.Command
{
    public override string EnglishName => typeof(TestCsharpCompiler).Name;

    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        try
        {
            var code = @"
                using System;

                class TestClass
                {
                    static void Main(string[] args)
                    {
                        Console.WriteLine(args.Length);
                    }
                }";

            var cp = new CompilerParameters();
            cp.GenerateInMemory = true;
            cp.GenerateExecutable = false;

            var cscp = new CSharpCodeProvider();
            var res = cscp.CompileAssemblyFromSource(cp, code);

            if (res.CompiledAssembly == null)
                throw new Exception("Compiler succeeded but compiled assembly is null.");

            RhinoApp.WriteLine("C# compiler test OK.");
            return Result.Success;
        }
        catch(Exception ex)
        {
            RhinoApp.WriteLine("C# compiler test failed: {0}", ex.Message);
            return Result.Success;
        }
    }
}

If you run this in Rhino 7.app you should find that it prints this:

Command: TestCsharpCompiler
C# compiler test failed: Compiler failed to produce the assembly. Output: '/Applications/Rhino 7.app/Contents/Frameworks/RhCore.framework/Versions/Current/Frameworks/Mono64Rhino.framework/Versions/6.10.0/Resources/bin/mcs /target:library /debug- /optimize+ /out:"/var/folders/0x/7rmxmrc95hb5v8cxk25mq1p80000gn/T/s5qd0gml.dll" /noconfig  -- "/var/folders/0x/7rmxmrc95hb5v8cxk25mq1p80000gn/T/s5qd0gml.0.cs" 

/Applications/Rhino 7.app/Contents/Frameworks/RhCore.framework/Versions/Current/Frameworks/Mono64Rhino.framework/Versions/6.10.0/Resources/bin/mcs: line 3: /Applications/Rhino: No such file or directory
/Applications/Rhino 7.app/Contents/Frameworks/RhCore.framework/Versions/Current/Frameworks/Mono64Rhino.framework/Versions/6.10.0/Resources/bin/mcs: line 3: exec: /Applications/Rhino: cannot execute: No such file or directory

And if you then re-run it after renaming Rhino to Rhino7.app (i.e. removing the space), you should get this output:

Command: TestCsharpCompiler
C# compiler test OK.

In looking into this I found something interesting, when I cd into the mcs directory and execute “mcs” I get the compiler complaining about no input files, but if I execute it as “./mcs” I reproduce the same two errors complaining about file not found. So I guess that makes it seem unlikely there’s any way around it from within plugin code, or I guess, even from within Rhino code.

Bella for Rhino users may now download the Bella 20.16 build, which implements a temporary workaround for this issue, from our builds page.

1 Like

@brian can you help here?

No, but I bet @Curtisw or @stevebaer probably could.

Hi @jdhill,

Looks like it doesn’t like the space in the name, which is probably a mono bug. I’ve logged that as RH-62177 to see if we can do anything about it.

I would however recommend for you to use the Roslyn compiler instead, as CSharpCodeProvider does not support newer C# constructs and is very limited under mono. This is what we use in Grasshopper on Mac. A quick overview of how to use the Roslyn based compiler is here.

Another option could be to simply rename it without a space, e.g. Rhino7.app.

Hope this helps!

This sounds weird. Grasshopper uses the same technique to compile C# and VB scripts. Why are things working for grasshopper and not for bella?

I couldn’t say at this point, please try reproducing with the provided test command, so I can see if I should try to diagnose further here (I tested the command in my plugin, did not create a fresh plugin for it).

@stevebaer on Mac we use Roslyn as I described above, we don’t use CSharpCodeProvider at all as it is all sorts of broken on mono.

Thanks for the info Curtis, seems a pretty heavy solution to an extra space in a file name, but if it’s necessary, I guess that’ll be that.

No problem. Keep a watch on the above YT issue, it might not be a difficult fix for us to at least get it working in that case. You’ll still run into issues with only supporting an older C# version, but it would at least work.

I didn’t realize that. We should enforce the C# 5 syntax if we aren’t already doing so already as someone using a feature like interpolated strings is going to be surprised when they don’t work on Windows.

Well I don’t need anything advanced, this is just the only way I found to define concrete rhino sdk subclasses (i.e. with guids) at runtime, for node definitions my system creates at runtime.

We don’t do that currently, I didn’t realize that CSharpCodeProvider was limited to C# 5 on windows as well.

It might make sense to update the script components on Windows to use Roslyn in that case, perhaps when I merge the two GH codebases.

For V8 that may make sense, but we need to be careful about this. It may involve creating an entirely new scripting component class as they would not be backward compatible with V7 or V6

Good point, I’ll create a few YT’s so I don’t forget about this.

1 Like

@curtisw , how would you approach using roslyn from a fairly complex project (have c++ code with interop libs, cross platform) that currently targets .net framework 4.5.1.

First thing I tried is loading the Microsoft.CodeAnalysis & Microsoft.CodeAnalysis.CSharp assemblies and calling via reflection, and this has worked from within Rhino 7, but the loads fail in 6. Probably just happenstance that they succeed in 7.

@jdhill Is there a particular reason you can’t update to .NET 4.6.1? You would then not need to use reflection.

To use these assemblies the system requires at least the above to be installed anyway. We use Microsoft.CodeAnalysis.CSharp v2.10.0 in v6, and 3.7.0 in v7, so it could be an API change that is causing the load failure, incompatibility with the older version of mono in v6, or possibly something else I’m not sure without more detail.

In any case, I have had some success patching our mono to support spaces with CSharpCodeProvider, so look for that fix in an upcoming service release, likely 7.3.

Cheers!

Thanks @curtisw, I’ll have a look at that, I was just getting a bit lost in a jungle of versions with the various roslyn-related libraries and their dependencies, so that info is helpful. Great to hear about progress on the core problem too, thanks again and cheers to you too!

RH-62177 is fixed in the latest Rhino 7 Service Release Candidate