添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

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!

curtisw:

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

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.

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.

curtisw:

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

stevebaer:

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.

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