Skip to content

Instantly share code, notes, and snippets.

@jagt
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jagt/e8439770ddafac5f444c to your computer and use it in GitHub Desktop.
Save jagt/e8439770ddafac5f444c to your computer and use it in GitHub Desktop.
/*
* Compile UnityScripts in "<ProjectRoot>/<ScriptsDirName>" into DLL, Windows and Editor Only
*
*/
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public static class BuildUSDll
{
// scripts dir in project root
static readonly string ScriptsDirName = "AltMole";
// output dir name, MUST be under Assets folder
static readonly string OutputDLL = "Assets/AltMole.dll";
// put a compile error in your project and refresh, then check Editor.log for these compile command lines
static readonly string MonoBinary = String.Format(@" ""{0}/Mono/bin/mono.exe"" ", EditorApplication.applicationContentsPath).Trim();
static readonly string UsBinary = String.Format(@" ""{0}/Mono/lib/mono/unity/us.exe"" ", EditorApplication.applicationContentsPath).Trim();
static readonly string EnvMonoPath = String.Format("{0}/Mono/lib/mono/unity", EditorApplication.applicationContentsPath);
static readonly string EnvMonoCfg = String.Format("{0}/Mono/etc", EditorApplication.applicationContentsPath);
static readonly string BuildCommand = @"
{1}
-debug
-target:library
-i:UnityEngine
-i:System.Collections
-base:UnityEngine.MonoBehaviour
-nowarn:BCW0016
-nowarn:BCW0003
-method:Main
-out:{2}
-x-type-inference-rule-attribute:UnityEngineInternal.TypeInferenceRuleAttribute
{3}
-r:""{0}/Managed/UnityEngine.dll""
-r:Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll
-r:Library/ScriptAssemblies/Assembly-UnityScript-firstpass.dll
-r:""{0}/Managed/UnityEditor.dll""
{4}
-i:UnityEditor
{5}
";
static string Normalize(string root, string path)
{
path = path.Replace("\\", "/");
if (path.IndexOf(root) == 0)
{
path = path.Substring(root.Length+1);
}
if (path.Contains(" "))
{
path = String.Format("\"{0}\"", path);
}
return path;
}
// verbatim BuildCommand might have either '\r\n' or '\n' based on the editor setting...
static string NewlineToSpace(string str)
{
return Regex.Replace(str, @"\r\n?|\n", " ");
}
[MenuItem("Tools/Build Unity Script DLL")]
static void Build()
{
var projectRoot = Path.GetDirectoryName(Application.dataPath);
var altScriptsRoot = Path.Combine(projectRoot, ScriptsDirName);
var assetsDir = Path.Combine(projectRoot, "Assets");
var files = Directory.GetFiles(altScriptsRoot, "*.js", SearchOption.AllDirectories);
for (var ix = 0; ix < files.Length; ++ix)
{
files[ix] = Normalize(projectRoot, files[ix]);
}
var defines = new string[EditorUserBuildSettings.activeScriptCompilationDefines.Length];
for (var ix = 0; ix < defines.Length; ++ix)
{
defines[ix] = String.Format("-define:{0}", EditorUserBuildSettings.activeScriptCompilationDefines[ix]);
}
// find all dlls and reference whose path has 'Plugins' and is not OutputDLL
var plugins = Directory.GetFiles(assetsDir, "*.dll", SearchOption.AllDirectories);
var pluginsList = new List<string>();
for (var ix = 0; ix < plugins.Length; ++ix)
{
plugins[ix] = Normalize(projectRoot, plugins[ix]);
plugins[ix] = String.Format("-r:{0}", plugins[ix]);
if (plugins[ix].Contains("Plugins/")
&& !plugins[ix].Equals(OutputDLL))
{
pluginsList.Add(plugins[ix]);
}
}
plugins = pluginsList.ToArray();
var proc = new System.Diagnostics.Process();
var args = String.Format(BuildCommand,
EditorApplication.applicationContentsPath,
UsBinary,
OutputDLL,
String.Join("\r\n", defines),
String.Join("\r\n", plugins),
String.Join("\r\n", files)
);
Debug.LogError(args);
try
{
proc.StartInfo.FileName = MonoBinary;
proc.StartInfo.Arguments = NewlineToSpace(args.Trim());
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.EnvironmentVariables.Add("MONO_PATH", EnvMonoPath);
proc.StartInfo.EnvironmentVariables.Add("MONO_CFG_DIR", EnvMonoCfg);
proc.Start();
var output = proc.StandardOutput.ReadToEnd();
var err = proc.StandardError.ReadToEnd();
AssetDatabase.Refresh();
proc.WaitForExit();
Debug.Log(output);
if (!String.IsNullOrEmpty(err.Trim()))
{
Debug.LogError(err);
}
Debug.Log("done");
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment