/// <summary> /// Updates the solution build configurations. /// </summary> /// <param name="platform">The platform.</param> /// <param name="solution">The solution.</param> /// <param name="projectProcessorContexts">The project processor contexts.</param> private static void UpdateSolutionBuildConfigurations(string platform, Solution solution, List <ProjectProcessorContext> projectProcessorContexts) { var configurations = new Dictionary <string, string>(); bool needDeploy = false; PlatformType requestedPlatform; if (!PlatformType.TryParse(platform, out requestedPlatform)) { throw new ArgumentOutOfRangeException(nameof(platform), "Invalid platform specified"); } switch (requestedPlatform) { case PlatformType.Windows: // Nothing to do here. break; case PlatformType.Android: configurations.Add(platform, platform); needDeploy = true; break; case PlatformType.Linux: case PlatformType.macOS: case PlatformType.UWP: configurations.Add("Any CPU", "Any CPU"); needDeploy = true; break; case PlatformType.iOS: configurations.Add("iPhone", "iPhone"); configurations.Add("iPhoneSimulator", "iPhoneSimulator"); needDeploy = true; break; default: throw new InvalidOperationException("Unknown platform " + requestedPlatform); } // Remove any reference of shared projects in the GlobalSections. var projects = solution.GlobalSections.FirstOrDefault(s => s.Name == "SharedMSBuildProjectFiles"); if (projects != null) { List <PropertyItem> toRemove = new List <PropertyItem>(); foreach (var projRef in projects.Properties) { // We assume here that we do not have the same project name in 2 or more locations var splitted = projRef.Name.Split('*'); if (splitted.Length >= 2) { Guid guid; if (Guid.TryParse(splitted[1], out guid) && !solution.Projects.Contains(guid)) { toRemove.Add(projRef); } } } foreach (var projRef in toRemove) { projects.Properties.Remove(projRef); } } // Update .sln for build configurations if (configurations.Count > 0) { var regex = new Regex(@"^(.*)\|((.*?)(?:\.(.*))?)$"); var solutionConfigurations = solution.GlobalSections["SolutionConfigurationPlatforms"].Properties .Select(x => Tuple.Create(x, regex.Match(x.Name), regex.Match(x.Value))) .ToArray(); solution.GlobalSections["SolutionConfigurationPlatforms"].Properties.Clear(); // Generate solution configurations foreach (var solutionConfiguration in solutionConfigurations) { var name = solutionConfiguration.Item2; var value = solutionConfiguration.Item3; foreach (var configuration in configurations) { solution.GlobalSections["SolutionConfigurationPlatforms"].Properties.Add( new PropertyItem(name.Groups[1].Value + "|" + configuration.Key, value.Groups[1] + "|" + configuration.Key)); } } // Generate project configurations foreach (var context in projectProcessorContexts) { // Check if platform is forced (in which case configuration line value should be kept as is) var stridePlatformNode = context.Document.XPathSelectElement("/x:Project/x:PropertyGroup/x:StridePlatform", context.NamespaceManager); // Keep project platform only if StridePlatform is set manually to Windows and not a platform specific project bool keepProjectPlatform = (stridePlatformNode != null && stridePlatformNode.Value == "Windows") && !context.Modified; // Extract config, we want to parse {78A3E406-EC0E-43B8-8EF2-30D3A149FBB6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU // into: // - {78A3E406-EC0E-43B8-8EF2-30D3A149FBB6}.Debug| // - .ActiveCfg // - Debug| var projectConfigLines = context.Project.PlatformProperties .Select(x => Tuple.Create(x, regex.Match(x.Name), regex.Match(x.Value))) .ToArray(); context.Project.PlatformProperties.Clear(); var matchingProjectConfigLines = new List <Tuple <PropertyItem, Match, Match> >(); foreach (var projectConfigLine in projectConfigLines) { var name = projectConfigLine.Item2; var value = projectConfigLine.Item3; // Simply copy lines that doesn't match pattern if (!name.Success || !name.Groups[4].Success || !value.Success) { context.Project.PlatformProperties.Add(projectConfigLine.Item1); } else { matchingProjectConfigLines.Add(projectConfigLine); } } // Print configuration again foreach (var configuration in configurations) { foreach (var projectConfigLine in matchingProjectConfigLines) { var name = projectConfigLine.Item2; var value = projectConfigLine.Item3; var newName = name.Groups[1].Value + "|" + configuration.Key + "." + name.Groups[4].Value; var newValue = keepProjectPlatform ? projectConfigLine.Item1.Value : value.Groups[1] + "|" + configuration.Value; context.Project.PlatformProperties.Add(new PropertyItem(newName, newValue)); // Active Deploy in solution configuration if (needDeploy && !keepProjectPlatform && newName.EndsWith("Build.0")) { context.Project.PlatformProperties.Add(new PropertyItem(newName.Replace("Build.0", "Deploy.0"), newValue)); } } } } } }