// Generate //------------------------------------------------------------------------------ void Report::Generate( const FBuildStats & stats ) { Timer t; // pre-allocate a large string for output m_Output.SetReserved( MEGABYTE ); m_Output.SetLength( 0 ); // generate some common data used in reporting GetLibraryStats( stats ); // build the report CreateHeader(); CreateTitle(); CreateOverview( stats ); DoCPUTimeByType( stats ); DoCacheStats( stats ); DoCPUTimeByLibrary(); DoCPUTimeByItem( stats ); DoIncludes(); CreateFooter(); // patch in time take const float time = t.GetElapsed(); AStackString<> timeTakenBuffer; stats.FormatTime( time, timeTakenBuffer ); char * placeholder = m_Output.Find( "^^^^ " ); memcpy( placeholder, timeTakenBuffer.Get(), timeTakenBuffer.GetLength() ); }
// CreateOverview //------------------------------------------------------------------------------ void Report::CreateOverview( const FBuildStats & stats ) { DoSectionTitle( "Overview", "overview" ); AStackString<> buffer; DoTableStart(); // Headings Write( "<tr><th width=150>Item</th><th>Details</th></tr>\n" ); // Full command line AStackString<> commandLineBuffer; Env::GetCmdLine( commandLineBuffer ); #if defined( __WINDOWS__ ) const char * exeExtension = strstr( commandLineBuffer.Get(), ".exe\"" ); const char * commandLine = exeExtension ? ( exeExtension + 5 ) : commandLineBuffer.Get(); // skip .exe + closing quote #else const char * commandLine = commandLineBuffer.Get(); #endif Write( "<tr><td width=80>Cmd Line Options</td><td>%s</td></tr>", commandLine ); // Target AStackString<> targets; const Node * rootNode = stats.GetRootNode(); if (rootNode->GetType() != Node::PROXY_NODE) { targets = rootNode->GetName(); } else { const Dependencies & childNodes = rootNode->GetStaticDependencies(); size_t num = childNodes.GetSize(); for ( size_t i=0; i<num; ++i ) { if ( i != 0 ) { targets += ", "; } const Node * child = childNodes[ i ].GetNode(); targets += child->GetName(); } } Write( "<tr><td>Target(s)</td><td>%s</td></tr>\n", targets.Get() ); // Result const bool buildOK = ( stats.GetRootNode()->GetState() == Node::UP_TO_DATE ); Write( "<tr><td>Result</td><td>%s</td></tr>\n", buildOK ? "OK" : "FAILED" ); // Real Time float totalBuildTime = stats.m_TotalBuildTime; stats.FormatTime( totalBuildTime, buffer ); Write( "<tr><td>Time</td><td>%s</td></tr>\n", buffer.Get() ); // Local CPU Time float totalLocalCPUInSeconds = (float)( (double)stats.m_TotalLocalCPUTimeMS / (double)1000 ); stats.FormatTime( totalLocalCPUInSeconds, buffer ); float localRatio = ( totalLocalCPUInSeconds / totalBuildTime ); Write( "<tr><td>CPU Time</td><td>%s (%2.1f:1)</td></tr>\n", buffer.Get(), localRatio ); // version info Write( "<tr><td>Version</td><td>%s %s</td></tr>\n", FBUILD_VERSION_STRING, FBUILD_VERSION_PLATFORM ); // report time char timeBuffer[ 256 ]; #if defined( __WINDOWS__ ) VERIFY( ::GetTimeFormat( LOCALE_NAME_USER_DEFAULT, // LCID Locale TIME_FORCE24HOURFORMAT, // DWORD dwFlags nullptr, // SYSTEMTIME *lpTime nullptr, // LPCTSTR lpFormat, timeBuffer, // LPTSTR lpTimeStr, 256 ) ); // int cchTime #elif defined( __APPLE__ ) timeBuffer[ 0 ] = '\000'; // TODO:MAC Implement GetTimeFormat in Report #elif defined( __LINUX__ ) timeBuffer[ 0 ] = '\000'; // TODO:LINUX Implement GetTimeFormat in Report #else #error Unknown platform #endif char dateBuffer[ 256 ]; #if defined( __WINDOWS__ ) VERIFY( ::GetDateFormat( LOCALE_NAME_USER_DEFAULT, // LCID Locale DATE_LONGDATE, // DWORD dwFlags nullptr, // SYSTEMTIME *lpTime nullptr, // LPCTSTR lpFormat, dateBuffer, // LPTSTR lpTimeStr, 256 ) ); // int cchTime #elif defined( __APPLE__ ) dateBuffer[ 0 ] = '\000'; // TODO:MAC Implement GetDateFormat in Report #elif defined( __LINUX__ ) dateBuffer[ 0 ] = '\000'; // TODO:LINUX Implement GetDateFormat in Report #else #error Unknown platform #endif // NOTE: leave space to patch in time taken later "^^^^ " Write( "<tr><td>Report Generated</td><td>^^^^ - %s %s</td></tr>\n", dateBuffer, timeBuffer ); DoTableStop(); }