/// <summary> /// Constructor /// </summary> internal ProjectConfigurationInSolution(string configurationName, string platformName, bool includeInBuild) { ConfigurationName = configurationName; PlatformName = RemoveSpaceFromAnyCpuPlatform(platformName); IncludeInBuild = includeInBuild; FullName = SolutionConfigurationInSolution.ComputeFullName(ConfigurationName, PlatformName); }
/// <summary> /// Figure out what solution configuration we are going to build, whether or not it actually exists in the solution /// file. /// </summary> private static string DetermineLikelyActiveSolutionConfiguration(SolutionFile solutionFile, IDictionary<string, string> globalProperties) { string activeSolutionConfiguration = null; string activeSolutionPlatform = null; globalProperties.TryGetValue("Configuration", out activeSolutionConfiguration); globalProperties.TryGetValue("Platform", out activeSolutionPlatform); if (String.IsNullOrEmpty(activeSolutionConfiguration)) { activeSolutionConfiguration = solutionFile.GetDefaultConfigurationName(); } if (String.IsNullOrEmpty(activeSolutionPlatform)) { activeSolutionPlatform = solutionFile.GetDefaultPlatformName(); } SolutionConfigurationInSolution configurationInSolution = new SolutionConfigurationInSolution(activeSolutionConfiguration, activeSolutionPlatform); return configurationInSolution.FullName; }
/// <summary> /// A helper method for constructing conditions for a solution configuration /// </summary> /// <remarks> /// Sample configuration condition: /// '$(Configuration)' == 'Release' and '$(Platform)' == 'Any CPU' /// </remarks> private static string GetConditionStringForConfiguration(SolutionConfigurationInSolution configuration) { return string.Format ( CultureInfo.InvariantCulture, " ('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}') ", EscapingUtilities.Escape(configuration.ConfigurationName), EscapingUtilities.Escape(configuration.PlatformName) ); }
/// <summary> /// Adds a new property group with contents of the given solution configuration to the project. /// </summary> private void AddPropertyGroupForSolutionConfiguration(ProjectRootElement traversalProject, SolutionConfigurationInSolution solutionConfiguration) { AddPropertyGroupForSolutionConfiguration(traversalProject, _solutionFile, solutionConfiguration); }
/// <summary> /// Adds a new property group with contents of the given solution configuration to the project /// Internal for unit-testing. /// </summary> internal static void AddPropertyGroupForSolutionConfiguration(ProjectRootElement msbuildProject, SolutionFile solutionFile, SolutionConfigurationInSolution solutionConfiguration) { ProjectPropertyGroupElement solutionConfigurationProperties = msbuildProject.CreatePropertyGroupElement(); msbuildProject.AppendChild(solutionConfigurationProperties); solutionConfigurationProperties.Condition = GetConditionStringForConfiguration(solutionConfiguration); StringBuilder solutionConfigurationContents = new StringBuilder(1024); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.OmitXmlDeclaration = true; using (XmlWriter xw = XmlWriter.Create(solutionConfigurationContents, settings)) { xw.WriteStartElement("SolutionConfiguration"); // add a project configuration entry for each project in the solution foreach (ProjectInSolution project in solutionFile.ProjectsInOrder) { ProjectConfigurationInSolution projectConfiguration = null; if (project.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out projectConfiguration)) { xw.WriteStartElement("ProjectConfiguration"); xw.WriteAttributeString("Project", project.ProjectGuid); xw.WriteAttributeString("AbsolutePath", project.AbsolutePath); xw.WriteAttributeString("BuildProjectInSolution", projectConfiguration.IncludeInBuild.ToString()); xw.WriteString(projectConfiguration.FullName); foreach (string dependencyProjectGuid in project.Dependencies) { // This is a project that the current project depends *ON* (ie., it must build first) ProjectInSolution dependencyProject; if (!solutionFile.ProjectsByGuid.TryGetValue(dependencyProjectGuid, out dependencyProject)) { // If it's not itself part of the solution, that's an invalid solution ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(dependencyProject != null, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solutionFile.FullPath), "SolutionParseProjectDepNotFoundError", project.ProjectGuid, dependencyProjectGuid); } // Add it to the list of dependencies, but only if it should build in this solution configuration // (If a project is not selected for build in the solution configuration, it won't build even if it's depended on by something that IS selected for build) // .. and only if it's known to be MSBuild format, as projects can't use the information otherwise if (dependencyProject.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) { ProjectConfigurationInSolution dependencyProjectConfiguration = null; if (dependencyProject.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out dependencyProjectConfiguration) && WouldProjectBuild(solutionFile, solutionConfiguration.FullName, dependencyProject, dependencyProjectConfiguration)) { xw.WriteStartElement("ProjectDependency"); xw.WriteAttributeString("Project", dependencyProjectGuid); xw.WriteEndElement(); } } } xw.WriteEndElement(); // </ProjectConfiguration> } } xw.WriteEndElement(); // </SolutionConfiguration> } var escapedSolutionConfigurationContents = EscapingUtilities.Escape(solutionConfigurationContents.ToString()); solutionConfigurationProperties.AddProperty("CurrentSolutionConfigurationContents", escapedSolutionConfigurationContents); msbuildProject.AddItem( "SolutionConfiguration", solutionConfiguration.FullName, new Dictionary<string, string> { { "Configuration", solutionConfiguration.ConfigurationName }, { "Platform", solutionConfiguration.PlatformName }, { "Content", escapedSolutionConfigurationContents }, }); }
/// <summary> /// Adds MSBuild tasks to a project target to pre-resolve its project references /// </summary> private void AddResolveProjectReferenceTasks ( ProjectInstance traversalProject, ProjectTargetInstance target, ProjectInSolution project, SolutionConfigurationInSolution solutionConfiguration, string outputReferenceItemName, string outputImportLibraryItemName, out string addedReferenceGuids ) { StringBuilder referenceGuids = new StringBuilder(); string message = null; // Suffix for the reference item name. Since we need to attach additional (different) metadata to every // reference item, we need to have helper item lists each with only one item int outputReferenceItemNameSuffix = 0; // Pre-resolve the MSBuild project references foreach (string projectReferenceGuid in project.ProjectReferences) { ProjectInSolution referencedProject = (ProjectInSolution)_solutionFile.ProjectsByGuid[projectReferenceGuid]; ProjectConfigurationInSolution referencedProjectConfiguration = null; if ((referencedProject != null) && (referencedProject.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out referencedProjectConfiguration)) && (referencedProjectConfiguration != null)) { string outputReferenceItemNameWithSuffix = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", outputReferenceItemName, outputReferenceItemNameSuffix); if ((referencedProject.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) || ((referencedProject.ProjectType == SolutionProjectType.Unknown) && (referencedProject.CanBeMSBuildProjectFile(out message)))) { string condition = GetConditionStringForConfiguration(solutionConfiguration); if (traversalProject.EvaluateCondition(condition)) { bool specifyProjectToolsVersion = String.Equals(traversalProject.ToolsVersion, "2.0", StringComparison.OrdinalIgnoreCase) ? false : true; ProjectTaskInstance msbuildTask = AddMSBuildTaskInstance ( target, referencedProject.RelativePath, "GetTargetPath", referencedProjectConfiguration.ConfigurationName, referencedProjectConfiguration.PlatformName, specifyProjectToolsVersion ); msbuildTask.AddOutputItem("TargetOutputs", outputReferenceItemNameWithSuffix, null); } if (referenceGuids.Length > 0) { referenceGuids.Append(';'); } referenceGuids.Append(projectReferenceGuid); // This merges the one-item item list into the main list, adding the appropriate guid metadata ProjectTaskInstance createItemTask = target.AddTask("CreateItem", null, null); createItemTask.SetParameter("Include", "@(" + outputReferenceItemNameWithSuffix + ")"); createItemTask.SetParameter("AdditionalMetadata", "Guid=" + projectReferenceGuid); createItemTask.AddOutputItem("Include", outputReferenceItemName, null); } outputReferenceItemNameSuffix++; } } addedReferenceGuids = referenceGuids.ToString(); }