// WriteNestedProjects //------------------------------------------------------------------------------ void SLNGenerator::WriteNestedProjects( const Array< AString > & solutionProjectsToFolder, const Array< AString > & solutionFolderPaths ) { if ( solutionProjectsToFolder.GetSize() == 0 && solutionFolderPaths.GetSize() == 0 ) { return; // skip global section } Write( "\tGlobalSection(NestedProjects) = preSolution\r\n" ); // Write every project to solution folder relationships const AString * const solutionProjectsToFolderEnd = solutionProjectsToFolder.End(); for( const AString * it = solutionProjectsToFolder.Begin() ; it != solutionProjectsToFolderEnd ; ++it ) { Write( it->Get() ); } // Write every intermediate path const AString * const solutionFolderPathsEnd = solutionFolderPaths.End(); for( const AString * it = solutionFolderPaths.Begin() ; it != solutionFolderPathsEnd ; ++it ) { // parse solution folder parent path AStackString<> solutionFolderParentGuid; const char * lastSlash = it->FindLast( NATIVE_SLASH ); if ( lastSlash ) { AStackString<> solutionFolderParentPath( it->Get(), lastSlash ); VSProjectGenerator::FormatDeterministicProjectGUID( solutionFolderParentGuid, solutionFolderParentPath ); } if ( solutionFolderParentGuid.GetLength() > 0 ) { // generate a guid for the solution folder AStackString<> solutionFolderGuid; VSProjectGenerator::FormatDeterministicProjectGUID( solutionFolderGuid, *it ); solutionFolderGuid.ToUpper(); solutionFolderParentGuid.ToUpper(); // write parent solution folder relationship Write( "\t\t%s = %s\r\n", solutionFolderGuid.Get(), solutionFolderParentGuid.Get() ); } } Write( "\tEndGlobalSection\r\n" ); }
// WriteSolutionConfigs //------------------------------------------------------------------------------ void SLNGenerator::WriteSolutionFolderListings( const Array< SLNSolutionFolder > & folders, Array< AString > & solutionFolderPaths ) { // Create every intermediate path const SLNSolutionFolder * const foldersEnd = folders.End(); for( const SLNSolutionFolder * it = folders.Begin() ; it != foldersEnd ; ++it ) { if ( solutionFolderPaths.Find( it->m_Path ) == nullptr ) { solutionFolderPaths.Append( it->m_Path ); } const char * pathEnd = it->m_Path.Find( NATIVE_SLASH ); while ( pathEnd ) { AStackString<> solutionFolderPath( it->m_Path.Get(), pathEnd ); if ( solutionFolderPaths.Find( solutionFolderPath ) == nullptr ) { solutionFolderPaths.Append( solutionFolderPath ); } pathEnd = it->m_Path.Find( NATIVE_SLASH, pathEnd + 1 ); } } solutionFolderPaths.Sort(); // Solution Folders Listings const AString * const solutionFolderPathsEnd = solutionFolderPaths.End(); for( const AString * it = solutionFolderPaths.Begin() ; it != solutionFolderPathsEnd ; ++it ) { // parse solution folder name const char * solutionFolderName = it->FindLast( NATIVE_SLASH ); solutionFolderName = solutionFolderName ? solutionFolderName + 1 : it->Get(); // generate a guid for the solution folder AStackString<> solutionFolderGuid; VSProjectGenerator::FormatDeterministicProjectGUID( solutionFolderGuid, *it ); // Guid must be uppercase (like visual) solutionFolderGuid.ToUpper(); Write( "Project(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"%s\", \"%s\", \"%s\"\r\n", solutionFolderName, solutionFolderName, solutionFolderGuid.Get() ); Write( "EndProject\r\n" ); } }
// WriteProjectListings //------------------------------------------------------------------------------ void SLNGenerator::WriteProjectListings( const AString& solutionBasePath, const AString& solutionBuildProject, const Array< VCXProjectNode * > & projects, const Array< SLNSolutionFolder > & folders, const Array< SLNDependency > & slnDeps, AString & solutionBuildProjectGuid, Array< AString > & projectGuids, Array< AString > & solutionProjectsToFolder ) { // Project Listings VCXProjectNode ** const projectsEnd = projects.End(); for( VCXProjectNode ** it = projects.Begin() ; it != projectsEnd ; ++it ) { // check if this project is the master project const bool projectIsActive = ( solutionBuildProject.CompareI( (*it)->GetName() ) == 0 ); AStackString<> projectPath( (*it)->GetName() ); // get project base name only const char * lastSlash = projectPath.FindLast( NATIVE_SLASH ); const char * lastPeriod = projectPath.FindLast( '.' ); AStackString<> projectName( lastSlash ? lastSlash + 1 : projectPath.Get(), lastPeriod ? lastPeriod : projectPath.GetEnd() ); // retrieve projectGuid AStackString<> projectGuid; if ( (*it)->GetProjectGuid().GetLength() == 0 ) { // For backward compatibility, keep the preceding slash and .vcxproj extension for GUID generation AStackString<> projectNameForGuid( lastSlash ? lastSlash : projectPath.Get() ); VSProjectGenerator::FormatDeterministicProjectGUID( projectGuid, projectNameForGuid ); } else { projectGuid = (*it)->GetProjectGuid(); } // make project path relative projectPath.Replace( solutionBasePath.Get(), "" ); // projectGuid must be uppercase (visual does that, it changes the .sln otherwise) projectGuid.ToUpper(); if ( projectIsActive ) { ASSERT( solutionBuildProjectGuid.GetLength() == 0 ); solutionBuildProjectGuid = projectGuid; } Write( "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"%s\", \"%s\", \"%s\"\r\n", projectName.Get(), projectPath.Get(), projectGuid.Get() ); // Manage dependencies Array< AString > dependencyGUIDs( 64, true ); const AString & fullProjectPath = (*it)->GetName(); for ( const SLNDependency & deps : slnDeps ) { // is the set of deps relevant to this project? if ( deps.m_Projects.Find( fullProjectPath ) ) { // get all the projects this project depends on for ( const AString & dependency : deps.m_Dependencies ) { // For backward compatibility, keep the preceding slash and .vcxproj extension for GUID generation const char * projNameFromSlash = dependency.FindLast( NATIVE_SLASH ); AStackString<> projectNameForGuid( projNameFromSlash ? projNameFromSlash : dependency.Get() ); AStackString<> newGUID; VSProjectGenerator::FormatDeterministicProjectGUID( newGUID, projectNameForGuid ); dependencyGUIDs.Append( newGUID ); } } } if ( !dependencyGUIDs.IsEmpty() ) { Write( "\tProjectSection(ProjectDependencies) = postProject\r\n" ); for ( const AString & guid : dependencyGUIDs ) { Write( "\t\t%s = %s\r\n", guid.Get(), guid.Get() ); } Write( "\tEndProjectSection\r\n" ); } Write( "EndProject\r\n" ); projectGuids.Append( projectGuid ); // check if this project is in a solution folder const SLNSolutionFolder * const foldersEnd = folders.End(); for ( const SLNSolutionFolder * it2 = folders.Begin() ; it2 != foldersEnd ; ++it2 ) { // this has to be done here to have the same order of declaration (like visual) if ( it2->m_ProjectNames.Find( (*it)->GetName() ) ) { // generate a guid for the solution folder AStackString<> solutionFolderGuid; VSProjectGenerator::FormatDeterministicProjectGUID( solutionFolderGuid, it2->m_Path ); solutionFolderGuid.ToUpper(); AStackString<> projectToFolder; projectToFolder.Format( "\t\t%s = %s\r\n", projectGuid.Get(), solutionFolderGuid.Get() ); solutionProjectsToFolder.Append( projectToFolder ); } } } }