Example #1
0
        public void CachePCHUsageForModuleSourceFiles(CPPEnvironment ModuleCompileEnvironment)
        {
            if( ProcessedDependencies == null )
            {
                var PCHCacheTimerStart = DateTime.UtcNow;

                var BuildPlatform = UEBuildPlatform.GetBuildPlatformForCPPTargetPlatform( ModuleCompileEnvironment.Config.Target.Platform );

                bool bFoundAProblemWithPCHs = false;

                FileItem UniquePCH = null;
                foreach( var CPPFile in SourceFilesFound.CPPFiles )	// @todo ubtmake: We're not caching CPPEnvironments for .c/.mm files, etc.  Even though they don't use PCHs, they still have #includes!  This can break dependency checking!
                {
                    // Build a single list of include paths to search.
                    var IncludePathsToSearch = ModuleCompileEnvironment.Config.CPPIncludeInfo.GetIncludesPathsToSearch( CPPFile );

                    // Store the module compile environment along with the .cpp file.  This is so that we can use it later on when looking
                    // for header dependencies
                    CPPFile.CachedCPPIncludeInfo = ModuleCompileEnvironment.Config.CPPIncludeInfo;

                    // Find headers used by the source file.
                    var PCH = UEBuildModuleCPP.CachePCHUsageForCPPFile(Target, CPPFile, BuildPlatform, IncludePathsToSearch, ModuleCompileEnvironment.Config.CPPIncludeInfo.IncludeFileSearchDictionary);
                    if( PCH == null )
                    {
                        throw new BuildException( "Source file \"{0}\" is not including any headers.  We expect all modules to include a header file for precompiled header generation.  Please add an #include statement.", CPPFile.AbsolutePath );
                    }

                    if( UniquePCH == null )
                    {
                        UniquePCH = PCH;
                    }
                    else if( !UniquePCH.Info.Name.Equals( PCH.Info.Name, StringComparison.InvariantCultureIgnoreCase ) )		// @todo ubtmake: We do a string compare on the file name (not path) here, because sometimes the include resolver will pick an Intermediate copy of a PCH header file and throw off our comparisons
                    {
                        // OK, looks like we have multiple source files including a different header file first.  We'll keep track of this and print out
                        // helpful information afterwards.
                        bFoundAProblemWithPCHs = true;
                    }
                }

                ProcessedDependencies = new ProcessedDependenciesClass{ UniquePCHHeaderFile = UniquePCH };

                if( bFoundAProblemWithPCHs )
                {
                    // Map from pch header string to the source files that use that PCH
                    var UsageMapPCH = new Dictionary<string, List<FileItem>>( StringComparer.InvariantCultureIgnoreCase );
                    foreach( var CPPFile in SourceFilesToBuild.CPPFiles )
                    {
                        // Create a new entry if not in the pch usage map
                        UsageMapPCH.GetOrAddNew( CPPFile.PrecompiledHeaderIncludeFilename ).Add( CPPFile );
                    }

                    if( BuildConfiguration.bPrintDebugInfo )
                    {
                        Log.TraceVerbose( "{0} PCH files for module {1}:", UsageMapPCH.Count, Name );
                        int MostFilesIncluded = 0;
                        foreach( var CurPCH in UsageMapPCH )
                        {
                            if( CurPCH.Value.Count > MostFilesIncluded )
                            {
                                MostFilesIncluded = CurPCH.Value.Count;
                            }

                            Log.TraceVerbose("   {0}  ({1} files including it: {2}, ...)", CurPCH.Key, CurPCH.Value.Count, CurPCH.Value[0].AbsolutePath);
                        }
                    }

                    if( UsageMapPCH.Count > 1 )
                    {
                        // Keep track of the PCH file that is most used within this module
                        string MostFilesAreIncludingPCH = string.Empty;
                        int MostFilesIncluded = 0;
                        foreach( var CurPCH in UsageMapPCH.Where( PCH => PCH.Value.Count > MostFilesIncluded ) )
                        {
                            MostFilesAreIncludingPCH = CurPCH.Key;
                            MostFilesIncluded        = CurPCH.Value.Count;
                        }

                        // Find all of the files that are not including our "best" PCH header
                        var FilesNotIncludingBestPCH = new StringBuilder();
                        foreach( var CurPCH in UsageMapPCH.Where( PCH => PCH.Key != MostFilesAreIncludingPCH ) )
                        {
                            foreach( var SourceFile in CurPCH.Value )
                            {
                                FilesNotIncludingBestPCH.AppendFormat( "{0} (including {1})\n", SourceFile.AbsolutePath, CurPCH.Key );
                            }
                        }

                        // Bail out and let the user know which source files may need to be fixed up
                        throw new BuildException(
                            "All source files in module \"{0}\" must include the same precompiled header first.  Currently \"{1}\" is included by most of the source files.  The following source files are not including \"{1}\" as their first include:\n\n{2}",
                            Name,
                            MostFilesAreIncludingPCH,
                            FilesNotIncludingBestPCH );
                    }
                }

                if( BuildConfiguration.bPrintPerformanceInfo )
                {
                    var PCHCacheTime = ( DateTime.UtcNow - PCHCacheTimerStart ).TotalSeconds;
                    TotalPCHCacheTime += PCHCacheTime;
                }
            }
        }
Example #2
0
        static void ScanCompiledFileSet(
            Dictionary<string, Dictionary<string, CompiledPackage>> 
                compilerDictionary,
            Dictionary<string, CompiledLibrary> libraryDictionary,
            Platform platform)
        {
            foreach (
                var file in
                    new DirectoryInfo(Path.Combine(
                        Config.BoostDir, platform.Directory))
                    .GetFiles())
            {
                var split = file.Name.SplitFirst('-');
                var library = split.Before.SplitFirst('_').After;
                var compiler = split.After.SplitFirst('-').Before;

                //
                var compiledLibrary = libraryDictionary.GetOrAddNew(library);
                var compiledPackage =
                    compiledLibrary.PackageDictionary.GetOrAddNew(compiler);
                compiledPackage.AddFile(platform, file.Name);

                // add the compiler and add the library to the compiler.
                compilerDictionary.GetOrAddNew(compiler)[library] =
                    compiledPackage;
            }
        }