Skip to content

Instantly share code, notes, and snippets.

@tpokorra
Last active October 18, 2019 19:37
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 tpokorra/e141b686abc12555851553aa3c2648ea to your computer and use it in GitHub Desktop.
Save tpokorra/e141b686abc12555851553aa3c2648ea to your computer and use it in GitHub Desktop.
simple c# build tool as alternative to xbuild
// a simple alternative to xbuild
// parse sln and csproj files, and call mcs to compile the projects.
// can only build libraries at the moment
// Copyright: Timotheus Pokorra <timotheus.pokorra@solidcharity.com>
// License: MIT
// to build: mcs builder.cs -r:System.Xml.Linq
using System;
using System.IO;
using System.Diagnostics;
using System.Xml.Linq;
namespace MyBuild
{
public class MyBuild
{
private static bool BuildProject(string csprojFile)
{
XDocument xmldoc = XDocument.Load(csprojFile);
XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
string mcs_params = "/noconfig /debug:full /debug:portable /optimize-";
mcs_params += " /target:library";
var propertyGroups = xmldoc.Element(msbuild + "Project").Elements(msbuild + "PropertyGroup");
string AssemblyName = "";
foreach (XElement propertyGroup in propertyGroups)
{
if (propertyGroup.Element(msbuild + "AssemblyName") != null)
{
AssemblyName = propertyGroup.Element(msbuild + "AssemblyName").Value;
break;
}
}
mcs_params += " /out:" + rootPath + "/bin/" + AssemblyName + ".dll";
foreach (var source in xmldoc.Descendants(msbuild + "Compile"))
{
string includePath = source.Attribute("Include").Value;
mcs_params += " " + includePath.Replace("\\", "/");
}
foreach (var reference in xmldoc.Descendants(msbuild + "Reference"))
{
string includePath = reference.Attribute("Include").Value;
XElement node = reference.Element(msbuild + "HintPath");
if (node != null)
{
mcs_params += " -r:" + node.Value.Replace("\\", "/");
}
else
{
mcs_params += " -r:" + includePath;
}
}
mcs_params += " /warn:4";
Console.WriteLine("change to dir " + (Path.GetDirectoryName(csprojFile)) + " to build " + csprojFile);
Directory.SetCurrentDirectory(Path.GetDirectoryName(csprojFile));
Console.WriteLine(mcs_params);
bool result = RunCompiler(mcs_params);
Directory.SetCurrentDirectory(rootPath);
return result;
}
private static bool BuildSolution(string solution)
{
using (StreamReader reader = new StreamReader(solution))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (!line.Trim().StartsWith("#"))
{
if (line.Contains(".csproj"))
{
int index=line.IndexOf(".csproj");
int startIndex=line.Substring(0, index).LastIndexOf('"')+1;
int EndIndex=line.Substring(startIndex + 1).IndexOf('"');
string projectFile = line.Substring(startIndex, EndIndex+1).Replace("\\", "/");
if (!BuildProject(projectFile))
{
return false;
}
}
}
}
}
return true;
}
private static bool RunCompiler(string mcs_params)
{
try
{
using (Process myProcess = new Process())
{
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = "mcs";
myProcess.StartInfo.Arguments = mcs_params;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
myProcess.WaitForExit();
return (myProcess.ExitCode == 0);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
}
private static string rootPath;
public static void Main(string[] args)
{
rootPath = Directory.GetCurrentDirectory();
Directory.CreateDirectory(rootPath + "/bin");
if (args.Length > 0)
{
if (args[0].EndsWith(".sln"))
{
BuildSolution(args[0]);
}
else if (args[0].EndsWith(".csproj"))
{
BuildProject(args[0]);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment