K
K
Kishir2017-02-08 22:35:39
C++ / C#
Kishir, 2017-02-08 22:35:39

Unity - gmcs - Error running gmcs: Cannot find the specified file - What to do?

faf48a5b3c924f43a7a997124a16c080.pngSystemException: Error running gmcs: Cannot find the specified file
An error occurred while starting the project.
The bottom line is that after starting the project, you need to compile the code that is conditionally in a variable of type string.
Test code:

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;
using UnityEngine;

public class RuntimeCompileTest : MonoBehaviour
{
  void Start()
  {
    var assembly = Compile(@"
        using UnityEngine;

        public class RuntimeCompiled : MonoBehaviour
        {
            public static RuntimeCompiled AddYourselfTo(GameObject host)
            {
                return host.AddComponent<RuntimeCompiled>();
            }

            void Start()
            {
                Debug.Log(""The runtime compiled component was successfully attached to"" + gameObject.name);
            }
        }");    

    var runtimeType = assembly.GetType("RuntimeCompiled");
    var method = runtimeType.GetMethod("AddYourselfTo");
    var del = (Func<GameObject, MonoBehaviour>)
      Delegate.CreateDelegate(
        typeof(Func<GameObject, MonoBehaviour>), 
        method
      );

    // We ask the compiled method to add its component to this.gameObject
    var addedComponent = del.Invoke(gameObject);

    // The delegate pre-bakes the reflection, so repeated calls don't
    // cost us every time, as long as we keep re-using the delegate.
  }

  public static Assembly Compile(string source)
  {
    // Replace this Compiler.CSharpCodeProvider wth aeroson's version
    // if you're targeting non-Windows platforms:
    var provider = new CSharpCodeProvider();
    var param = new CompilerParameters();

    // Add ALL of the assembly references
    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
      param.ReferencedAssemblies.Add(assembly.Location);
    }

    // Or, uncomment just the assemblies you need...

    // System namespace for common types like collections.
    //param.ReferencedAssemblies.Add("System.dll");

    // This contains methods from the Unity namespaces:
    //param.ReferencedAssemblies.Add("UnityEngines.dll");

    // This assembly contains runtime C# code from your Assets folders:
    // (If you're using editor scripts, they may be in another assembly)
    //param.ReferencedAssemblies.Add("CSharp.dll");


    // Generate a dll in memory
    param.GenerateExecutable = false;
    param.GenerateInMemory = true;

    // Compile the source
    var result = provider.CompileAssemblyFromSource(param, source);

    if (result.Errors.Count > 0) {
      var msg = new StringBuilder();
      foreach (CompilerError error in result.Errors) {
        msg.AppendFormat("Error ({0}): {1}\n",
          error.ErrorNumber, error.ErrorText);
      }
      throw new Exception(msg.ToString());
    }

    // Return the assembly
    return result.CompiledAssembly;
  }
}

It throws an error:
SystemException: Error running gmcs: Cannot find the specified file (in the picture)
I tried installing the MonoRuntime package , tried linking to the /usr/local/bin folder of this compiler, nothing helps. Installed .NET 2.0 in player as some advise. Nothing helps. OS X 10.11.6 Error
showing what is in line:
var result = provider.CompileAssemblyFromSource(param, source);
Tell me what should I do?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question