SolutionSection GenerateProjectConfigurationSection(ISolution solution) { SolutionSection section = new SolutionSection("ProjectConfigurationPlatforms", "postSolution"); foreach (var project in solution.AllItems.OfType <IProject>()) { foreach (var configuration in solution.ConfigurationNames) { foreach (var platform in solution.PlatformNames) { var solutionConfig = new ConfigurationAndPlatform(configuration, platform); var projectConfig = project.ConfigurationMapping.GetProjectConfiguration(solutionConfig); string key = GuidToString(project.IdGuid) + "." + solutionConfig; string value = projectConfig.Configuration + "|" + MSBuildInternals.FixPlatformNameForSolution(projectConfig.Platform); section.Add(key + ".ActiveCfg", value); if (project.ConfigurationMapping.IsBuildEnabled(solutionConfig)) { section.Add(key + ".Build.0", value); } if (project.ConfigurationMapping.IsDeployEnabled(solutionConfig)) { section.Add(key + ".Deploy.0", value); } } } } return(section); }
public static bool IsValidName(string name) { return(!string.IsNullOrEmpty(name) && MSBuildInternals.Escape(name) == name && name.Trim() == name && FileUtility.IsValidDirectoryEntryName(name) && name.IndexOf('\'') < 0 && name.IndexOf('.') < 0); }
void UpdateMSBuildProperties() { var dict = new Dictionary <string, string>(); MSBuildInternals.AddMSBuildSolutionProperties(this, dict); foreach (var pair in dict) { msBuildProjectCollection.SetGlobalProperty(pair.Key, pair.Value); } }
void WriteAdditionalTargetsToTempFile(Dictionary <string, string> globalProperties) { // Using projects with in-memory modifications doesn't work with parallel build. // As a work-around, we'll write our modifications to a file and force MSBuild to include that file using a custom property. temporaryFileName = Path.GetTempFileName(); using (XmlWriter w = new XmlTextWriter(temporaryFileName, Encoding.UTF8)) { const string xmlNamespace = "http://schemas.microsoft.com/developer/msbuild/2003"; w.WriteStartElement("Project", xmlNamespace); foreach (string import in additionalTargetFiles) { w.WriteStartElement("Import", xmlNamespace); w.WriteAttributeString("Project", MSBuildInternals.Escape(import)); w.WriteEndElement(); } if (globalProperties.ContainsKey("BuildingInsideVisualStudio")) { // When we set BuildingInsideVisualStudio, MSBuild skips its own change detection // because in Visual Studio, the host compiler does the change detection. // We override the target '_ComputeNonExistentFileProperty' which is responsible // for recompiling each time - our _ComputeNonExistentFileProperty does nothing, // which re-enables the MSBuild's usual change detection. w.WriteStartElement("Target", xmlNamespace); w.WriteAttributeString("Name", "_ComputeNonExistentFileProperty"); w.WriteEndElement(); } // 'MsTestToolsTargets' is preferred because it's at the end of the MSBuild 3.5 and 4.0 target file, // but on MSBuild 2.0 we need to fall back to 'CodeAnalysisTargets'. string hijackedProperty = "MsTestToolsTargets"; if (projectMinimumSolutionVersion == SolutionFormatVersion.VS2005) { hijackedProperty = "CodeAnalysisTargets"; } // because we'll replace the hijackedProperty, manually write the corresponding include if (globalProperties.ContainsKey(hijackedProperty)) { // global properties passed to MSBuild are not be evaluated (and are not escaped), // so we need to escape them for writing them into an MSBuild file w.WriteStartElement("Import", xmlNamespace); w.WriteAttributeString("Project", MSBuildInternals.Escape(globalProperties[hijackedProperty])); w.WriteEndElement(); } w.WriteEndElement(); // inject our imports at the end of 'Microsoft.Common.Targets' by replacing the hijackedProperty. globalProperties[hijackedProperty] = temporaryFileName; } #if DEBUG LoggingService.Debug(File.ReadAllText(temporaryFileName)); #endif }
/// <summary> /// Sets the project configuration corresponding to the given solution configuration. /// </summary> public void SetProjectConfiguration(ConfigurationAndPlatform solutionConfiguration, ConfigurationAndPlatform projectConfiguration) { if (string.IsNullOrEmpty(projectConfiguration.Configuration)) { throw new ArgumentException("Invalid project configuration"); } if (string.IsNullOrEmpty(projectConfiguration.Platform)) { throw new ArgumentException("Invalid project platform"); } lock (dict) { GetOrCreateEntry(solutionConfiguration).Config = new ConfigurationAndPlatform( projectConfiguration.Configuration, MSBuildInternals.FixPlatformNameForProject(projectConfiguration.Platform) ); } Changed(this, EventArgs.Empty); }
/// <summary> /// Sets the value of the specified meta data item. The value is escaped before /// setting it to ensure characters like ';' or '$' are not interpreted by MSBuild. /// Setting value to null or an empty string results in removing the metadata item. /// </summary> public void SetEvaluatedMetadata(string metadataName, string value) { if (string.IsNullOrEmpty(value)) { RemoveMetadata(metadataName); } else { lock (SyncRoot) { if (buildItem != null) { buildItem.SetEvaluatedMetadata(metadataName, value); } else { virtualMetadata[metadataName] = MSBuildInternals.Escape(value); } } } }
public string ValidateName(string name) { if (name == null) { return(null); } name = name.Trim(); if (!ConfigurationAndPlatform.IsValidName(name)) { return(null); } if (isPlatform) { return(MSBuildInternals.FixPlatformNameForProject(name)); } else { return(name); } }
internal Engine CreateEngine() { Engine engine = MSBuildInternals.CreateEngine(); foreach (KeyValuePair <string, string> entry in MSBuildProperties) { engine.GlobalProperties.SetProperty(entry.Key, entry.Value); } // re-load these properties from AddInTree every time because "text" might contain // SharpDevelop properties resolved by the StringParser (e.g. ${property:FxCopPath}) AddInTreeNode node = AddInTree.GetTreeNode(AdditionalPropertiesPath, false); if (node != null) { foreach (Codon codon in node.Codons) { object item = codon.BuildItem(null, new System.Collections.ArrayList()); if (item != null) { bool escapeValue = !codon.Properties.Get("text", "").Contains("$("); engine.GlobalProperties.SetProperty(codon.Id, item.ToString(), escapeValue); } } } if (options.AdditionalProperties != null) { foreach (KeyValuePair <string, string> entry in options.AdditionalProperties) { engine.GlobalProperties.SetProperty(entry.Key, entry.Value); } } engine.GlobalProperties.SetProperty("SolutionDir", EnsureBackslash(solution.Directory)); engine.GlobalProperties.SetProperty("SolutionExt", ".sln"); engine.GlobalProperties.SetProperty("SolutionFileName", Path.GetFileName(solution.FileName)); engine.GlobalProperties.SetProperty("SolutionPath", solution.FileName); engine.GlobalProperties.SetProperty("BuildingInsideVisualStudio", "true"); return(engine); }
/// <summary> /// Gets the evaluated value of the metadata item with the specified name. /// Returns an empty string for non-existing meta data items. /// </summary> public string GetEvaluatedMetadata(string metadataName) { lock (SyncRoot) { if (buildItem != null) { return(buildItem.GetEvaluatedMetadata(metadataName) ?? ""); } else { string val; virtualMetadata.TryGetValue(metadataName, out val); if (val == null) { return(""); } else { return(MSBuildInternals.Unescape(val)); } } } }
bool ParseSolution(Project solution) { // get the build target to call Target mainBuildTarget = solution.Targets[options.Target.TargetName]; if (mainBuildTarget == null) { currentResults.Result = BuildResultCode.BuildFileError; currentResults.Add(new BuildError(this.solution.FileName, "Target '" + options.Target + "' not supported by solution.")); return(false); } // example of mainBuildTarget: // <Target Name="Build" Condition="'$(CurrentSolutionConfigurationContents)' != ''"> // <CallTarget Targets="Main\ICSharpCode_SharpDevelop;Main\ICSharpCode_Core;Main\StartUp;Tools" RunEachTargetSeparately="true" /> // </Target> List <BuildTask> mainBuildTargetTasks = Linq.ToList(Linq.CastTo <BuildTask>(mainBuildTarget)); if (mainBuildTargetTasks.Count != 1 || mainBuildTargetTasks[0].Name != "CallTarget") { return(InvalidTarget(mainBuildTarget)); } List <Target> solutionTargets = new List <Target>(); foreach (string solutionTargetName in mainBuildTargetTasks[0].GetParameterValue("Targets").Split(';')) { Target target = solution.Targets[solutionTargetName]; if (target != null) { solutionTargets.Add(target); } } // dictionary for fast lookup of ProjectToBuild elements Dictionary <string, ProjectToBuild> projectsToBuildDict = new Dictionary <string, ProjectToBuild>(); // now look through targets that took like this: // <Target Name="Main\ICSharpCode_Core" Condition="'$(CurrentSolutionConfigurationContents)' != ''"> // <MSBuild Projects="Main\Core\Project\ICSharpCode.Core.csproj" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') " /> // <MSBuild Projects="Main\Core\Project\ICSharpCode.Core.csproj" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " /> // </Target> // and add those targets to the "projectsToBuild" list. foreach (Target target in solutionTargets) { List <BuildTask> tasks = Linq.ToList(Linq.CastTo <BuildTask>(target)); if (tasks.Count == 0) { return(InvalidTarget(target)); } // find task to run when this target is executed BuildTask bestTask = null; foreach (BuildTask task in tasks) { if (task.Name != "MSBuild") { return(InvalidTarget(target)); } if (MSBuildInternals.EvaluateCondition(solution, task.Condition)) { bestTask = task; } } if (bestTask == null) { LoggingService.Warn("No matching condition for solution target " + target.Name); bestTask = tasks[0]; } // create projectToBuild entry and add it to list and dictionary string projectFileName = Path.Combine(this.solution.Directory, bestTask.GetParameterValue("Projects")); ProjectToBuild projectToBuild = new ProjectToBuild(Path.GetFullPath(projectFileName), bestTask.GetParameterValue("Targets")); // get project configuration and platform from properties section string propertiesString = bestTask.GetParameterValue("Properties"); Match match = Regex.Match(propertiesString, @"\bConfiguration=([^;]+);"); if (match.Success) { projectToBuild.configuration = match.Groups[1].Value; } else { projectToBuild.configuration = parentEngine.Configuration; } match = Regex.Match(propertiesString, @"\bPlatform=([^;]+);"); if (match.Success) { projectToBuild.platform = match.Groups[1].Value; } else { projectToBuild.platform = parentEngine.Platform; if (projectToBuild.platform == "Any CPU") { projectToBuild.platform = "AnyCPU"; } } projectsToBuild.Add(projectToBuild); projectsToBuildDict[target.Name] = projectToBuild; } // now create dependencies between projectsToBuild foreach (Target target in solutionTargets) { ProjectToBuild p1; if (!projectsToBuildDict.TryGetValue(target.Name, out p1)) { continue; } foreach (string dependency in target.DependsOnTargets.Split(';')) { ProjectToBuild p2; if (!projectsToBuildDict.TryGetValue(dependency, out p2)) { continue; } p1.dependencies.Add(p2); } } return(true); }
public void SetEvaluatedMetadata(string name, string value) { item.SetMetadataValue(name, MSBuildInternals.Escape(value)); }
public static ProjectBuildOptions CreateProjectBuildOptions(this IBuildable buildable, BuildOptions options, bool isRootBuildable) { IBuildable2 buildable2 = buildable as IBuildable2; if (buildable2 != null) { return(buildable2.CreateProjectBuildOptions(options, isRootBuildable)); } // start of default implementation var configMatchings = buildable.ParentSolution.GetActiveConfigurationsAndPlatformsForProjects(options.SolutionConfiguration, options.SolutionPlatform); ProjectBuildOptions projectOptions = new ProjectBuildOptions(isRootBuildable ? options.ProjectTarget : options.TargetForDependencies); // Find the project configuration, and build an XML string containing all configurations from the solution StringWriter solutionConfigurationXml = new StringWriter(); using (XmlTextWriter solutionConfigurationWriter = new XmlTextWriter(solutionConfigurationXml)) { solutionConfigurationWriter.WriteStartElement("SolutionConfiguration", ""); foreach (var matching in configMatchings) { if (matching.Project == buildable) { projectOptions.Configuration = matching.Configuration; projectOptions.Platform = matching.Platform; } solutionConfigurationWriter.WriteStartElement("ProjectConfiguration"); solutionConfigurationWriter.WriteAttributeString("Project", matching.Project.IdGuid); solutionConfigurationWriter.WriteValue(matching.Configuration + "|" + MSBuildInternals.FixPlatformNameForProject(matching.Platform)); solutionConfigurationWriter.WriteEndElement(); } solutionConfigurationWriter.WriteEndElement(); } // fall back to solution config if we don't find any entries for the project if (string.IsNullOrEmpty(projectOptions.Configuration)) { projectOptions.Configuration = options.SolutionConfiguration; } if (string.IsNullOrEmpty(projectOptions.Platform)) { projectOptions.Platform = options.SolutionPlatform; } // copy properties to project options options.GlobalAdditionalProperties.ForEach(projectOptions.Properties.Add); if (isRootBuildable) { foreach (var pair in options.ProjectAdditionalProperties) { projectOptions.Properties[pair.Key] = pair.Value; } } // Set property for solution configuration. This allows MSBuild to know the correct configuration for project references, // which is necessary to resolve the referenced project's OutputPath. projectOptions.Properties["CurrentSolutionConfigurationContents"] = solutionConfigurationXml.ToString(); return(projectOptions); }
void IConfigurationOrPlatformNameCollection.Add(string newName, string copyFrom) { SD.MainThread.VerifyAccess(); newName = ValidateName(newName); if (newName == null) { throw new ArgumentException(); } lock (project.SyncRoot) { var projectFile = project.MSBuildProjectFile; var userProjectFile = project.MSBuildUserProjectFile; bool copiedGroupInMainFile = false; if (copyFrom != null) { copyFrom = MSBuildInternals.FixPlatformNameForProject(copyFrom); foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.ToList()) { var gConfig = ConfigurationAndPlatform.FromCondition(g.Condition); if (HasName(gConfig, copyFrom)) { CopyProperties(projectFile, g, SetName(gConfig, newName)); copiedGroupInMainFile = true; } } foreach (ProjectPropertyGroupElement g in userProjectFile.PropertyGroups.ToList()) { var gConfig = ConfigurationAndPlatform.FromCondition(g.Condition); if (HasName(gConfig, copyFrom)) { CopyProperties(userProjectFile, g, SetName(gConfig, newName)); } } } if (!copiedGroupInMainFile) { projectFile.AddPropertyGroup().Condition = (isPlatform ? new ConfigurationAndPlatform(null, newName) : new ConfigurationAndPlatform(newName, null)).ToCondition(); } project.LoadConfigurationPlatformNamesFromMSBuild(); // Adjust mapping: // If the new config/platform already exists in the solution and is mapped to some old project config/platform, // re-map it to the new config/platform. var mapping = project.ConfigurationMapping; if (isPlatform) { string newNameForSolution = MSBuildInternals.FixPlatformNameForSolution(newName); if (project.ParentSolution.PlatformNames.Contains(newNameForSolution, ConfigurationAndPlatform.ConfigurationNameComparer)) { foreach (string solutionConfiguration in project.ParentSolution.ConfigurationNames) { var solutionConfig = new ConfigurationAndPlatform(solutionConfiguration, newNameForSolution); var projectConfig = mapping.GetProjectConfiguration(solutionConfig); mapping.SetProjectConfiguration(solutionConfig, SetName(projectConfig, newName)); } } } else { if (project.ParentSolution.ConfigurationNames.Contains(newName, ConfigurationAndPlatform.ConfigurationNameComparer)) { foreach (string solutionPlatform in project.ParentSolution.PlatformNames) { var solutionConfig = new ConfigurationAndPlatform(newName, solutionPlatform); var projectConfig = mapping.GetProjectConfiguration(solutionConfig); mapping.SetProjectConfiguration(solutionConfig, SetName(projectConfig, newName)); } } } project.ActiveConfiguration = mapping.GetProjectConfiguration(project.ParentSolution.ActiveConfiguration); } }
/// <summary> /// Gets the project configuration corresponding to the given solution configuration. /// </summary> public ConfigurationAndPlatform GetProjectConfiguration(ConfigurationAndPlatform solutionConfiguration) { lock (dict) { Entry entry; if (dict.TryGetValue(solutionConfiguration, out entry)) { return(entry.Config); } else { return(new ConfigurationAndPlatform(solutionConfiguration.Configuration, MSBuildInternals.FixPlatformNameForProject(solutionConfiguration.Platform))); } } }
Entry GetOrCreateEntry(ConfigurationAndPlatform solutionConfiguration) { Entry entry; if (!dict.TryGetValue(solutionConfiguration, out entry)) { var config = new ConfigurationAndPlatform(solutionConfiguration.Configuration, MSBuildInternals.FixPlatformNameForProject(solutionConfiguration.Platform)); entry = new Entry(config); dict.Add(solutionConfiguration, entry); } return(entry); }