Emulate xbuild targeting behavior on Mono. Closes #1.
- Added subprocess startup with assembly binding redirection to enforce MSBuild version 12 system (https://github.com/mono/mono/blob/master/mcs/tools/xbuild/data/xbuild.exe.config.in). I don't know how many nasty side effects this causes as the code is pretty poor, so pleeeeeaaaaaase do report bugs on this.release-1.1.0
parent
364fee11dd
commit
853140b905
|
@ -1,6 +1,16 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<runtime>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
<generatePublisherEvidence enabled="false" />
|
||||||
</startup>
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="12.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="12.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
</configuration>
|
</configuration>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<runtime>
|
||||||
|
<generatePublisherEvidence enabled="false" />
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="12.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="12.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
|
</configuration>
|
|
@ -62,6 +62,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="CommandLineOptions.cs" />
|
<Compile Include="CommandLineOptions.cs" />
|
||||||
|
<Compile Include="Extensions.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="RepositoryExtensions.cs" />
|
<Compile Include="RepositoryExtensions.cs" />
|
||||||
|
@ -88,6 +89,7 @@
|
||||||
<EmbeddedResource Include="costura64\git2-91fa31f.dll" />
|
<EmbeddedResource Include="costura64\git2-91fa31f.dll" />
|
||||||
<EmbeddedResource Include="costura32\*.so" />
|
<EmbeddedResource Include="costura32\*.so" />
|
||||||
<EmbeddedResource Include="costura64\*.so" />
|
<EmbeddedResource Include="costura64\*.so" />
|
||||||
|
<EmbeddedResource Include="AppDomainConfigurations\BuildNET45.xml" />
|
||||||
<Content Include="FodyWeavers.xml">
|
<Content Include="FodyWeavers.xml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CitizenMP.Server.Installer
|
||||||
|
{
|
||||||
|
internal static class Extensions
|
||||||
|
{
|
||||||
|
public static bool IsWin32(this OperatingSystem os)
|
||||||
|
{
|
||||||
|
return os.Platform == PlatformID.Win32NT ||
|
||||||
|
os.Platform == PlatformID.Win32S ||
|
||||||
|
os.Platform == PlatformID.Win32Windows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,6 @@ using Microsoft.Build.Evaluation;
|
||||||
using Microsoft.Build.Execution;
|
using Microsoft.Build.Execution;
|
||||||
using Microsoft.Build.Framework;
|
using Microsoft.Build.Framework;
|
||||||
using Mono.Unix.Native;
|
using Mono.Unix.Native;
|
||||||
using Project = Microsoft.Build.BuildEngine.Project;
|
|
||||||
using UnixSyscall = Mono.Unix.Native.Syscall;
|
using UnixSyscall = Mono.Unix.Native.Syscall;
|
||||||
|
|
||||||
namespace CitizenMP.Server.Installer
|
namespace CitizenMP.Server.Installer
|
||||||
|
@ -59,6 +58,13 @@ namespace CitizenMP.Server.Installer
|
||||||
|
|
||||||
private static int Main(string[] args)
|
private static int Main(string[] args)
|
||||||
{
|
{
|
||||||
|
var monoRun = RunWithMonoConfiguration(args);
|
||||||
|
if (monoRun.Item1)
|
||||||
|
{
|
||||||
|
// The main stuff already ran in a subprocess
|
||||||
|
return monoRun.Item2;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse cmdline arguments
|
// Parse cmdline arguments
|
||||||
var options = new CommandLineOptions();
|
var options = new CommandLineOptions();
|
||||||
//args = args.DefaultIfEmpty("--help").ToArray();
|
//args = args.DefaultIfEmpty("--help").ToArray();
|
||||||
|
@ -238,7 +244,7 @@ namespace CitizenMP.Server.Installer
|
||||||
{
|
{
|
||||||
{"Configuration", "Release"},
|
{"Configuration", "Release"},
|
||||||
{"Platform", "Any CPU"},
|
{"Platform", "Any CPU"},
|
||||||
{"DebugType", IsWin32() ? "None" : "pdbonly"},
|
{"DebugType", Environment.OSVersion.IsWin32() ? "None" : "pdbonly"},
|
||||||
{"DebugSymbols", false.ToString()},
|
{"DebugSymbols", false.ToString()},
|
||||||
{"OutputPath", binOutputDirectory.FullName},
|
{"OutputPath", binOutputDirectory.FullName},
|
||||||
{"AllowedReferenceRelatedFileExtensions", "\".mdb\"=\"\";\".pdb\"=\"\";\".xml\"=\"\""}
|
{"AllowedReferenceRelatedFileExtensions", "\".mdb\"=\"\";\".pdb\"=\"\";\".xml\"=\"\""}
|
||||||
|
@ -315,6 +321,62 @@ namespace CitizenMP.Server.Installer
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Tuple<bool, int> RunWithMonoConfiguration(string[] args)
|
||||||
|
{
|
||||||
|
if (Environment.OSVersion.IsWin32())
|
||||||
|
{
|
||||||
|
// .NET Framework does everything properly anyways
|
||||||
|
return new Tuple<bool, int>(false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var engineAssembly =
|
||||||
|
Assembly.Load(
|
||||||
|
"Microsoft.Build.Engine, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
|
||||||
|
.GetName();
|
||||||
|
if (engineAssembly.Version.Major < 12)
|
||||||
|
{
|
||||||
|
//var baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
var baseDir = Path.GetDirectoryName(Assembly.Load("CommandLine").Location);
|
||||||
|
if (baseDir == null)
|
||||||
|
throw new DirectoryNotFoundException("Could not find base directory");
|
||||||
|
|
||||||
|
var tempExePath = Path.Combine(baseDir, new Random().Next(10000, 99999) + ".exe");
|
||||||
|
File.Copy(Assembly.GetExecutingAssembly().Location, tempExePath);
|
||||||
|
|
||||||
|
var tempConfigPath = tempExePath + ".config";
|
||||||
|
using (var tempConfig = File.OpenWrite(tempConfigPath))
|
||||||
|
{
|
||||||
|
using (
|
||||||
|
var srcConfig =
|
||||||
|
Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream(
|
||||||
|
"CitizenMP.Server.Installer.AppDomainConfigurations.BuildNET45.xml"))
|
||||||
|
{
|
||||||
|
if (srcConfig == null)
|
||||||
|
throw new FileNotFoundException("Could not find config resource");
|
||||||
|
srcConfig.CopyTo(tempConfig);
|
||||||
|
srcConfig.Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.DomainUnload += (sender, e) =>
|
||||||
|
{
|
||||||
|
File.Delete(tempConfigPath);
|
||||||
|
File.Delete(tempExePath);
|
||||||
|
};
|
||||||
|
|
||||||
|
var arguments = string.Join(" ",
|
||||||
|
new[] {tempExePath}.Concat(args)
|
||||||
|
.Select(a => "\"" + a.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""));
|
||||||
|
var exitCode = RunProcess("mono", arguments, new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"MONO_IOMAP", "all"}
|
||||||
|
});
|
||||||
|
return new Tuple<bool, int>(true, exitCode);
|
||||||
|
}
|
||||||
|
return new Tuple<bool, int>(false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private static bool Build(string projectFilePath, IDictionary<string, string> buildProperties,
|
private static bool Build(string projectFilePath, IDictionary<string, string> buildProperties,
|
||||||
LoggerVerbosity verbosity, string logPath = null)
|
LoggerVerbosity verbosity, string logPath = null)
|
||||||
{
|
{
|
||||||
|
@ -349,7 +411,7 @@ namespace CitizenMP.Server.Installer
|
||||||
loggers.Add(new ConsoleLogger(verbosity) {ShowSummary = false});
|
loggers.Add(new ConsoleLogger(verbosity) {ShowSummary = false});
|
||||||
|
|
||||||
// Import/Update Mozilla certs for NuGet to not fail out on non-Windows machines
|
// Import/Update Mozilla certs for NuGet to not fail out on non-Windows machines
|
||||||
if (!IsWin32())
|
if (!Environment.OSVersion.IsWin32())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -357,15 +419,18 @@ namespace CitizenMP.Server.Installer
|
||||||
{
|
{
|
||||||
if (s == null || !s.Contains("X.509 Certificate"))
|
if (s == null || !s.Contains("X.509 Certificate"))
|
||||||
return;
|
return;
|
||||||
writer.WriteLine("y");
|
writer.WriteLine("yes");
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Make sure this does not fail out by checking if mozroots is installed
|
// TODO: Make sure this does not fail out by checking if mozroots is installed
|
||||||
Console.WriteLine("Updating SSL certificates for NuGet...");
|
Console.WriteLine("Updating SSL certificates for NuGet...");
|
||||||
Run("mozroots", "--import --sync --quiet");
|
RunProcessThrowOnException("mozroots", "--import --sync --quiet");
|
||||||
Run("certmgr", "-ssl https://go.microsoft.com", automaticYesResponder);
|
RunProcessThrowOnException("certmgr", "-ssl https://go.microsoft.com",
|
||||||
Run("certmgr", "-ssl https://nugetgallery.blob.core.windows.net", automaticYesResponder);
|
lineProcessor: automaticYesResponder);
|
||||||
Run("certmgr", "-ssl https://nuget.org", automaticYesResponder);
|
RunProcessThrowOnException("certmgr", "-ssl https://nugetgallery.blob.core.windows.net",
|
||||||
|
lineProcessor: automaticYesResponder);
|
||||||
|
RunProcessThrowOnException("certmgr", "-ssl https://nuget.org",
|
||||||
|
lineProcessor: automaticYesResponder);
|
||||||
}
|
}
|
||||||
catch (Exception error)
|
catch (Exception error)
|
||||||
{
|
{
|
||||||
|
@ -386,18 +451,27 @@ namespace CitizenMP.Server.Installer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a different build route if running on the Mono interpreter
|
// Use a different build route if running on the Mono interpreter
|
||||||
if (!IsWin32())
|
if (!Environment.OSVersion.IsWin32())
|
||||||
{
|
{
|
||||||
// Build doesn't work with the new API on Mono, use the deprecated api
|
|
||||||
Console.WriteLine("Building server binaries...");
|
Console.WriteLine("Building server binaries...");
|
||||||
#pragma warning disable 618
|
#pragma warning disable 618
|
||||||
|
// Build doesn't work with the new API on Mono, use the deprecated api
|
||||||
|
var engine = Engine.GlobalEngine;
|
||||||
|
|
||||||
|
// loggers
|
||||||
foreach (var logger in loggers)
|
foreach (var logger in loggers)
|
||||||
Engine.GlobalEngine.RegisterLogger(logger);
|
engine.RegisterLogger(logger);
|
||||||
var project = new Project(Engine.GlobalEngine) {BuildEnabled = true};
|
|
||||||
project.Load(projectFilePath);
|
// Apply build properties
|
||||||
|
var buildPropertiesConverted = new BuildPropertyGroup();
|
||||||
|
engine.GlobalProperties = buildPropertiesConverted;
|
||||||
foreach (var property in buildProperties)
|
foreach (var property in buildProperties)
|
||||||
project.GlobalProperties.SetProperty(property.Key, property.Value);
|
buildPropertiesConverted.SetProperty(property.Key, property.Value);
|
||||||
var result = project.Build();
|
|
||||||
|
// Load project
|
||||||
|
var result = engine.BuildProjectFile(projectFilePath, new string[0], null, null,
|
||||||
|
BuildSettings.None,
|
||||||
|
null);
|
||||||
#pragma warning restore 618
|
#pragma warning restore 618
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +480,8 @@ namespace CitizenMP.Server.Installer
|
||||||
{
|
{
|
||||||
Console.WriteLine("Building server binaries...");
|
Console.WriteLine("Building server binaries...");
|
||||||
|
|
||||||
var buildReq = new BuildRequestData(projectFilePath, buildProperties, null, new[] {"Build"}, null);
|
var buildReq = new BuildRequestData(projectFilePath, buildProperties, null, new[] {"Build"},
|
||||||
|
null);
|
||||||
|
|
||||||
var result = BuildManager.DefaultBuildManager.Build(
|
var result = BuildManager.DefaultBuildManager.Build(
|
||||||
new BuildParameters(pc)
|
new BuildParameters(pc)
|
||||||
|
@ -424,18 +499,42 @@ namespace CitizenMP.Server.Installer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Run(string name, string args, Action<string, StreamWriter> lineProcessor = null)
|
private static void RunProcessThrowOnException(string name, string args,
|
||||||
|
IDictionary<string, string> envVars = null,
|
||||||
|
Action<string, StreamWriter> lineProcessor = null)
|
||||||
{
|
{
|
||||||
using (var p = Process.Start(new ProcessStartInfo
|
var exitCode = RunProcess(name, args, envVars, lineProcessor);
|
||||||
|
|
||||||
|
if (exitCode != 0)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format("Process \"{0} {1}\" exited with error code {2}",
|
||||||
|
name, args, exitCode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int RunProcess(string name, string args, IDictionary<string, string> envVars = null,
|
||||||
|
Action<string, StreamWriter> lineProcessor = null)
|
||||||
|
{
|
||||||
|
using (var p = new Process
|
||||||
|
{
|
||||||
|
StartInfo =
|
||||||
{
|
{
|
||||||
Arguments = args,
|
Arguments = args,
|
||||||
FileName = name,
|
FileName = name,
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
CreateNoWindow = true,
|
CreateNoWindow = true,
|
||||||
|
WorkingDirectory = Environment.CurrentDirectory,
|
||||||
RedirectStandardInput = lineProcessor != null,
|
RedirectStandardInput = lineProcessor != null,
|
||||||
RedirectStandardOutput = lineProcessor != null
|
RedirectStandardOutput = lineProcessor != null
|
||||||
}))
|
}
|
||||||
|
})
|
||||||
{
|
{
|
||||||
|
if (envVars != null)
|
||||||
|
foreach (KeyValuePair<string, string> i in envVars)
|
||||||
|
p.StartInfo.EnvironmentVariables.Add(i.Key, i.Value);
|
||||||
|
|
||||||
|
p.Start();
|
||||||
|
|
||||||
if (lineProcessor == null)
|
if (lineProcessor == null)
|
||||||
{
|
{
|
||||||
p.WaitForExit();
|
p.WaitForExit();
|
||||||
|
@ -449,19 +548,8 @@ namespace CitizenMP.Server.Installer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.ExitCode != 0)
|
return p.ExitCode;
|
||||||
{
|
|
||||||
throw new Exception(string.Format("Process \"{0} {1}\" exited with error code {2}",
|
|
||||||
name, args, p.ExitCode));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsWin32()
|
|
||||||
{
|
|
||||||
return Environment.OSVersion.Platform == PlatformID.Win32NT ||
|
|
||||||
Environment.OSVersion.Platform == PlatformID.Win32S ||
|
|
||||||
Environment.OSVersion.Platform == PlatformID.Win32Windows;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,6 +1,16 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<runtime>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
<generatePublisherEvidence enabled="false" />
|
||||||
</startup>
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="12.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="12.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
</configuration>
|
</configuration>
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Weavers>
|
<Weavers>
|
||||||
<Costura/>
|
<Costura CreateTemporaryAssemblies="true"/>
|
||||||
</Weavers>
|
</Weavers>
|
Loading…
Reference in New Issue