Skip to content

Instantly share code, notes, and snippets.

@jagt jagt/BuildUSDll.cs
Last active Aug 29, 2015

Embed
What would you like to do?
/*
* 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
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.