/// <summary> /// Load configuration information for a solution /// </summary> public void Load (Solution sol, SolutionItem project, SolutionItemRunConfiguration runConfig) { currentSolutionConfigurations.Clear (); currentTargetPartitions.Clear (); reducedConfigurations.Clear (); if (sol == null) return; // Create a set of configuration partitions. Each partition will contain configurations // which are implicitly selected when selecting an execution target. For example, in // an iOS project we would have two partitions: // 1) Debug|IPhoneSimulator, Release|IPhoneSimulator // targets: iPhone, iPad // 2) Debug|IPhone, Release|IPhone // targets: device List<TargetPartition> partitions = new List<TargetPartition> (); if (project != null) { foreach (var conf in project.Configurations) { var targets = project.GetExecutionTargets (conf.Selector, runConfig); if (!targets.Any ()) { targets = new ExecutionTarget[] { dummyExecutionTarget }; } var parts = partitions.Where (p => targets.Any (p.Targets.Contains)).ToArray(); if (parts.Length == 0) { // Create a new partition for this configuration var p = new TargetPartition (); p.Configurations.Add (conf.Id); p.Targets.UnionWith (targets); partitions.Add (p); } else if (parts.Length == 1) { // Register the configuration into an existing partition parts[0].Configurations.Add (conf.Id); parts[0].Targets.UnionWith (targets); } else { // The partitions have to be merged into a single one for (int n=1; n<parts.Length; n++) { parts[0].Configurations.UnionWith (parts[n].Configurations); parts[0].Targets.UnionWith (parts[n].Targets); partitions.Remove (parts[n]); } } } // The startup project configuration partitions are used to create solution configuration partitions foreach (var solConf in sol.Configurations) { var pconf = solConf.GetEntryForItem (project); if (pconf != null && pconf.Build) { var part = partitions.FirstOrDefault (p => p.Configurations.Contains (pconf.ItemConfiguration)); if (part != null) { part.SolutionConfigurations.Add (solConf.Id); continue; } } // The solution configuration is not bound to the startup project // Add it to all partitions so that it can still take part of // the solution configuration simplification process foreach (var p in partitions) p.SolutionConfigurations.Add (solConf.Id); } } if (partitions.Count == 0) { // There is no startup project, just use all solution configurations in this case var p = new TargetPartition (); p.SolutionConfigurations.AddRange (sol.GetConfigurations ()); partitions.Add (p); } // There can be several configurations with the same prefix and different platform but which build the same projects. // If all configurations with the same prefix are identical, all of them can be reduced into a single configuration // with no platform name. This loop detects such configurations var notReducibleConfigurations = new HashSet<string> (); foreach (var p in partitions) { var groupedConfigs = p.SolutionConfigurations.GroupBy (sc => { string name, plat; ItemConfiguration.ParseConfigurationId (sc, out name, out plat); return name; }).ToArray (); foreach (var confGroup in groupedConfigs) { var configs = confGroup.ToArray (); var baseConf = sol.Configurations[configs[0]]; if (configs.Skip (1).All (c => ConfigurationEquals (sol, baseConf, sol.Configurations[c]))) p.ReducedConfigurations.Add (confGroup.Key); else notReducibleConfigurations.Add (confGroup.Key); } } // To really be able to use reduced configuration names, all partitions must have that reduced configuration // Find the configurations that have been reduced in all partitions reducedConfigurations = new HashSet<string> (partitions.SelectMany (p => p.ReducedConfigurations)); reducedConfigurations.ExceptWith (notReducibleConfigurations); // Final merge of configurations var result = new HashSet<string> (); foreach (var p in partitions) result.UnionWith (p.SolutionConfigurations); // Replace reduced configurations foreach (var reducedConf in reducedConfigurations) { result.RemoveWhere (c => { string name, plat; ItemConfiguration.ParseConfigurationId (c, out name, out plat); return name == reducedConf; }); result.Add (reducedConf); } currentTargetPartitions = partitions; currentSolutionConfigurations.AddRange (result); currentSolutionConfigurations.Sort (); }
/// <summary> /// Load configuration information for a solution /// </summary> public void Load(Solution sol) { currentSolutionConfigurations.Clear(); currentTargetPartitions.Clear(); reducedConfigurations.Clear(); if (sol == null) { return; } var project = sol.StartupItem; // Create a set of configuration partitions. Each partition will contain configurations // which are implicitly selected when selecting an execution target. For example, in // an iOS project we would have two partitions: // 1) Debug|IPhoneSimulator, Release|IPhoneSimulator // targets: iPhone, iPad // 2) Debug|IPhone, Release|IPhone // targets: device List <TargetPartition> partitions = new List <TargetPartition> (); if (project != null) { foreach (var conf in project.Configurations) { var targets = project.GetExecutionTargets(conf.Selector); if (!targets.Any()) { targets = new ExecutionTarget[] { dummyExecutionTarget }; } var parts = partitions.Where(p => targets.Any(t => p.Targets.Contains(t))).ToArray(); if (parts.Length == 0) { // Create a new partition for this configuration var p = new TargetPartition(); p.Configurations.Add(conf.Id); p.Targets.UnionWith(targets); partitions.Add(p); } else if (parts.Length == 1) { // Register the configuration into an existing partition parts[0].Configurations.Add(conf.Id); parts[0].Targets.UnionWith(targets); } else { // The partitions have to be merged into a single one for (int n = 1; n < parts.Length; n++) { parts[0].Configurations.UnionWith(parts[n].Configurations); parts[0].Targets.UnionWith(parts[n].Targets); partitions.Remove(parts[n]); } } } // The startup project configuration partitions are used to create solution configuration partitions foreach (var solConf in sol.Configurations) { var pconf = solConf.GetEntryForItem(project); if (pconf != null && pconf.Build) { var part = partitions.FirstOrDefault(p => p.Configurations.Contains(pconf.ItemConfiguration)); if (part != null) { part.SolutionConfigurations.Add(solConf.Id); continue; } } // The solution configuration is not bound to the startup project // Add it to all partitions so that it can still take part of // the solution configuration simplification process foreach (var p in partitions) { p.SolutionConfigurations.Add(solConf.Id); } } } if (partitions.Count == 0) { // There is no startup project, just use all solution configurations in this case var p = new TargetPartition(); p.SolutionConfigurations.AddRange(sol.GetConfigurations()); partitions.Add(p); } // There can be several configurations with the same prefix and different platform but which build the same projects. // If all configurations with the same prefix are identical, all of them can be reduced into a single configuration // with no platform name. This loop detects such configurations var notReducibleConfigurations = new HashSet <string> (); foreach (var p in partitions) { var groupedConfigs = p.SolutionConfigurations.GroupBy(sc => { string name, plat; ItemConfiguration.ParseConfigurationId(sc, out name, out plat); return(name); }).ToArray(); foreach (var confGroup in groupedConfigs) { var configs = confGroup.ToArray(); var baseConf = sol.Configurations[configs[0]]; if (configs.Skip(1).All(c => ConfigurationEquals(sol, baseConf, sol.Configurations[c]))) { p.ReducedConfigurations.Add(confGroup.Key); } else { notReducibleConfigurations.Add(confGroup.Key); } } } // To really be able to use reduced configuration names, all partitions must have that reduced configuration // Find the configurations that have been reduced in all partitions reducedConfigurations = new HashSet <string> (partitions.SelectMany(p => p.ReducedConfigurations)); reducedConfigurations.ExceptWith(notReducibleConfigurations); // Final merge of configurations var result = new HashSet <string> (); foreach (var p in partitions) { result.UnionWith(p.SolutionConfigurations); } // Replace reduced configurations foreach (var reducedConf in reducedConfigurations) { result.RemoveWhere(c => { string name, plat; ItemConfiguration.ParseConfigurationId(c, out name, out plat); return(name == reducedConf); }); result.Add(reducedConf); } currentTargetPartitions = partitions; currentSolutionConfigurations.AddRange(result); currentSolutionConfigurations.Sort(); }
public void FlushAll() => TargetPartition.FlushAll();