in vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.cs [3225:3337]
internal virtual BuildSubmission DoMSBuildSubmission(BuildKind buildKind, string target, ref ProjectInstance projectInstance, MSBuildCoda uiThreadCallback, IEnumerable<KeyValuePair<string, string>> extraProperties = null)
{
UIThread.MustBeCalledFromUIThread();
IVsBuildManagerAccessor accessor = null;
Microsoft.Build.Framework.ILogger[] loggers;
BuildSubmission submission;
BuildAccessorAccess buildAccessorAccess = null;
try
{
accessor = (IVsBuildManagerAccessor)this.Site.GetService(typeof(SVsBuildManagerAccessor));
this.SetHostObject("CoreCompile", "Fsc", this);
// Do the actual Build
var loggerList = new System.Collections.Generic.List<Microsoft.Build.Framework.ILogger>(this.buildEngine.Loggers);
if (buildLogger != null)
loggerList.Add(buildLogger);
if (myDebugLogger != null)
loggerList.Add(myDebugLogger);
loggers = loggerList.ToArray();
var ba = new BuildAccessorAccess(buildKind, accessor);
if (!ba.IsOk)
{
ba.Dispose();
if (uiThreadCallback != null) uiThreadCallback(MSBuildResult.Failed, projectInstance);
return null;
}
buildAccessorAccess = ba;
string[] targetsToBuild = new string[target != null ? 1 : 0];
if (target != null)
{
targetsToBuild[0] = target;
}
if (projectInstance == null)
{
projectInstance = BuildProject.CreateProjectInstance();
}
// F#-specific properties
projectInstance.SetProperty(GlobalProperty.VisualStudioStyleErrors.ToString(), "true");
if (extraProperties != null)
{
foreach (var prop in extraProperties)
{
projectInstance.SetProperty(prop.Key, prop.Value);
}
}
projectInstance.SetProperty("UTFOutput", "true");
// The CoreCLR build of FSC will use the CultureName since lcid doesn't apply very well
// so that the errors reported by fsc.exe are in the right locale
projectInstance.SetProperty("PREFERREDUILANG", System.Threading.Thread.CurrentThread.CurrentUICulture.Name);
this.BuildProject.ProjectCollection.HostServices.SetNodeAffinity(projectInstance.FullPath, NodeAffinity.InProc);
BuildRequestData requestData = new BuildRequestData(projectInstance, targetsToBuild, this.BuildProject.ProjectCollection.HostServices, BuildRequestDataFlags.ReplaceExistingProjectInstance);
submission = BuildManager.DefaultBuildManager.PendBuildRequest(requestData);
}
catch (Exception)
{
if (buildAccessorAccess != null)
{
buildAccessorAccess.Dispose();
}
throw;
}
try
{
foreach (var logger in loggers)
{
accessor.RegisterLogger(submission.SubmissionId, logger);
}
ProjectInstance tempProjectInstance = projectInstance;
if (buildKind == BuildKind.ASYNC)
{
submission.ExecuteAsync(sub =>
{
UIThread.Run(() =>
{
FinishSubmission(sub, buildAccessorAccess);
uiThreadCallback((sub.BuildResult.OverallResult == BuildResultCode.Success) ? MSBuildResult.Successful : MSBuildResult.Failed, tempProjectInstance);
});
}, null);
}
else
{
submission.Execute();
}
}
catch (Exception e)
{
Debug.Fail(e.ToString());
// our callback may not have been registered, but must always do coda
FinishSubmission(submission, buildAccessorAccess);
if (uiThreadCallback != null)
uiThreadCallback(MSBuildResult.Failed, projectInstance);
throw;
}
if (buildKind == BuildKind.SYNC)
{
FinishSubmission(submission, buildAccessorAccess);
var msbuildResult = (submission.BuildResult.OverallResult == BuildResultCode.Success) ? MSBuildResult.Successful : MSBuildResult.Failed;
if (uiThreadCallback != null) uiThreadCallback(msbuildResult, projectInstance);
}
return submission;
}