internal virtual void ResolveSourceFiles()

in Sharpmake/Project.cs [871:1347]


        internal virtual void ResolveSourceFiles(Builder builder)
        {
            var sourceFilesIncludeRegex = RegexCache.GetCachedRegexes(SourceFilesIncludeRegex);
            var sourceFilesFiltersRegex = RegexCache.GetCachedRegexes(SourceFilesFiltersRegex);
            var sourceFilesExcludeRegex = RegexCache.GetCachedRegexes(SourceFilesExcludeRegex);
            var sourceFilesBuildExcludeRegex = RegexCache.GetCachedRegexes(SourceFilesBuildExcludeRegex);
            var sourceFilesBuildFiltersRegex = RegexCache.GetCachedRegexes(SourceFilesBuildFiltersRegex);
            var sourceFilesCompileAsCRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsCRegex);
            var sourceFilesCompileAsCPPRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsCPPRegex);
            var sourceFilesCompileAsObjCRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsObjCRegex);
            var sourceFilesCompileAsObjCPPRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsObjCPPRegex);
            var sourceFilesCompileAsCLRRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsCLRRegex);
            var sourceFilesCompileAsCLRExcludeRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsCLRExcludeRegex);
            var sourceFilesCompileAsNonCLRRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsNonCLRRegex);
            var sourceFilesCompileAsWinRTRegex = RegexCache.GetCachedRegexes(SourceFilesCompileAsWinRTRegex);
            var sourceFilesExcludeAsWinRTRegex = RegexCache.GetCachedRegexes(SourceFilesExcludeAsWinRTRegex);
            var sourceFilesBlobExcludeRegex = RegexCache.GetCachedRegexes(SourceFilesBlobExcludeRegex);

            if (!Util.DirectoryExists(SourceRootPath))
            {
                ResolveNonExistingSourcePath();
            }

            if (DebugBreaks.ShouldBreakOnSourcePath(DebugBreaks.Context.Resolving, SourceFilesBuildExclude))
                Debugger.Break();
            ResolvedSourceFilesBuildExclude.AddRange(SourceFilesBuildExclude);

            if (NoneExtensionsCopyIfNewer.Count != 0)
            {
                NoneExtensions.RemoveAll(s => NoneExtensionsCopyIfNewer.Contains(s));
            }

            // Only scan directory for files if needed
            if (SourceFilesExtensions.Count != 0 || ResourceFilesExtensions.Count != 0 || PRIFilesExtensions.Count != 0 || NoneExtensions.Count != 0 || NoneExtensionsCopyIfNewer.Count != 0)
            {
                string capitalizedSourceRootPath = Util.GetCapitalizedPath(SourceRootPath);

                // Query all files in source directory
                DirectoryInfo sourceRootPathInfo = new DirectoryInfo(capitalizedSourceRootPath);
                Strings files = new Strings(GetDirectoryFiles(sourceRootPathInfo));

                AddMatchExtensionFiles(files, SourceFiles, SourceFilesExtensions);

                if (SourceFilesIncludeRegex.Count != 0)
                {
                    if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, files), files, SourceFiles, sourceFilesIncludeRegex))
                        Debugger.Break();
                }

                // Additional source directories if any
                foreach (var additionalSourceRootPath in AdditionalSourceRootPaths)
                {
                    string capitalizedAdditionalSourceRootPath = Util.GetCapitalizedPath(additionalSourceRootPath);
                    DirectoryInfo additionalSourceRootPathInfo = new DirectoryInfo(capitalizedAdditionalSourceRootPath);
                    Strings additionalFiles = new Strings(GetDirectoryFiles(additionalSourceRootPathInfo));
                    AddMatchExtensionFiles(additionalFiles, SourceFiles, SourceFilesExtensions);

                    if (SourceFilesIncludeRegex.Count != 0)
                    {
                        if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, additionalFiles), additionalFiles, SourceFiles, sourceFilesIncludeRegex))
                            Debugger.Break();
                    }

                    AddMatchExtensionFiles(additionalFiles, PRIFiles, PRIFilesExtensions);
                    AddMatchExtensionFiles(additionalFiles, ResourceFiles, ResourceFilesExtensions);
                    AddMatchExtensionFiles(additionalFiles, NatvisFiles, NatvisFilesExtensions);
                    AddMatchExtensionFiles(additionalFiles, NoneFiles, NoneExtensions);
                    AddMatchExtensionFiles(additionalFiles, NoneFilesCopyIfNewer, NoneExtensionsCopyIfNewer);
                    AddMatchExtensionFiles(additionalFiles, ProtoFiles, ProtoExtensions);
                }

                // Apply Filters 
                if (SourceFilesFiltersRegex.Count != 0)
                {
                    Strings allSourceFile = SourceFiles;
                    SourceFiles = new Strings();

                    if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, allSourceFile), allSourceFile, SourceFiles, sourceFilesFiltersRegex))
                        Debugger.Break();
                }

                Util.ResolvePath(SourceRootPath, ref SourceFiles);

                if (SourceFilesBuildFiltersRegex.Count != 0)
                {
                    AddNoMatchFiles(RootPath, Util.PathGetRelative(RootPath, SourceFiles), SourceFiles, ResolvedSourceFilesBuildExclude, sourceFilesBuildFiltersRegex);
                }

                AddMatchExtensionFiles(files, PRIFiles, PRIFilesExtensions);
                Util.ResolvePath(SourceRootPath, ref PRIFiles);

                AddMatchExtensionFiles(files, ResourceFiles, ResourceFilesExtensions);
                Util.ResolvePath(SourceRootPath, ref ResourceFiles);

                AddMatchExtensionFiles(files, NatvisFiles, NatvisFilesExtensions);
                Util.ResolvePath(SourceRootPath, ref NatvisFiles);

                AddMatchExtensionFiles(files, NoneFiles, NoneExtensions);
                Util.ResolvePath(SourceRootPath, ref NoneFiles);

                AddMatchExtensionFiles(files, NoneFilesCopyIfNewer, NoneExtensionsCopyIfNewer);
                Util.ResolvePath(SourceRootPath, ref NoneFilesCopyIfNewer);

                AddMatchExtensionFiles(files, ProtoFiles, ProtoExtensions);
                Util.ResolvePath(SourceRootPath, ref ProtoFiles);
            }

            _preFilterSourceFiles.AddRange(SourceFiles);

            if (SourceFilesFilters != null)
            {
                // keep precomp
                Strings keepFiles = new Strings();
                Strings confPrecomps = new Strings();
                foreach (Configuration conf in Configurations)
                    if (conf.PrecompSource != null)
                        confPrecomps.Add(conf.PrecompSource);
                foreach (string sourceFile in SourceFiles)
                    foreach (string confPrecomp in confPrecomps)
                        if (sourceFile.EndsWith(confPrecomp, StringComparison.OrdinalIgnoreCase))
                            keepFiles.Add(sourceFile);

                SourceFiles.IntersectWith(SourceFilesFilters);
                SourceFiles.RemoveRange(SourceFilesExclude);
                SourceFilesFiltersCount = SourceFiles.Count(f => SourceFilesCompileExtensions.Contains(Path.GetExtension(f)));
                SourceFiles.AddRange(keepFiles);
                ResourceFiles.IntersectWith(SourceFilesFilters);
                NatvisFiles.IntersectWith(SourceFilesFilters);
                NoneFiles.IntersectWith(SourceFilesFilters);
                NoneFilesCopyIfNewer.IntersectWith(SourceFilesFilters);
                ProtoFiles.IntersectWith(SourceFilesFilters);
            }

            using (builder.CreateProfilingScope("Project.ResolveSourceFiles:AdditionalFiltering"))
                AdditionalFiltering(SourceFiles, ref SourceFilesExclude);

            // Add source files
            ResolvedSourceFiles.AddRange(SourceFiles);

            //Exclude files in IntermediatePath and OutputPath
            ExcludeOutputFiles();

            // Remove file that match SourceFilesExcludeRegex
            if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, SourceFiles), SourceFiles, SourceFilesExclude, sourceFilesExcludeRegex))
                Debugger.Break();
            if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, ResourceFiles), ResourceFiles, SourceFilesExclude, sourceFilesExcludeRegex))
                Debugger.Break();
            if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, NatvisFiles), NatvisFiles, SourceFilesExclude, sourceFilesExcludeRegex))
                Debugger.Break();
            if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, NoneFiles), NoneFiles, SourceFilesExclude, sourceFilesExcludeRegex))
                Debugger.Break();
            if (AddMatchFiles(RootPath, Util.PathGetRelative(RootPath, ProtoFiles), ProtoFiles, SourceFilesExclude, sourceFilesExcludeRegex))
                Debugger.Break();

            // Remove exclude file
            foreach (string excludeSourceFile in SourceFilesExclude)
            {
                ResolvedSourceFiles.Remove(excludeSourceFile);
                ResourceFiles.Remove(excludeSourceFile);
                NatvisFiles.Remove(excludeSourceFile);
                NoneFiles.Remove(excludeSourceFile);
                ProtoFiles.Remove(excludeSourceFile);
            }
            var resolvedSourceFilesRelative = Util.PathGetRelative(RootPath, ResolvedSourceFiles);

            // check if we need to blob the project
            bool oneBlobbed = false;
            bool fastBuildBlobs = false;

            var resolvedSourceFilesBuildExclude = new Strings();
            var resolvedSourceFilesWithCompileAsCOption = new Strings();
            var resolvedSourceFilesWithCompileAsCPPOption = new Strings();
            var resolvedSourceFilesWithCompileAsObjCOption = new Strings();
            var resolvedSourceFilesWithCompileAsObjCPPOption = new Strings();
            var resolvedSourceFilesWithCompileAsCLROption = new Strings();
            var compileAsClrFilesExclude = new Strings();
            var resolvedSourceFilesWithCompileAsNonCLROption = new Strings();
            var resolvedSourceFilesWithCompileAsWinRTOption = new Strings();
            var resolvedSourceFilesWithExcludeAsWinRTOption = new Strings();
            using (builder.CreateProfilingScope("Project.ResolveSourceFiles:ApplyProjectRegexes"))
            {
                // Do first part that is specific to project to not repeat for each config
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesBuildExclude, sourceFilesBuildExcludeRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithCompileAsCOption, sourceFilesCompileAsCRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithCompileAsCPPOption, sourceFilesCompileAsCPPRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithCompileAsObjCOption, sourceFilesCompileAsObjCRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithCompileAsObjCPPOption, sourceFilesCompileAsObjCPPRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithCompileAsCLROption, sourceFilesCompileAsCLRRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, compileAsClrFilesExclude, sourceFilesCompileAsCLRExcludeRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithCompileAsNonCLROption, sourceFilesCompileAsNonCLRRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithCompileAsWinRTOption, sourceFilesCompileAsWinRTRegex);
                AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, resolvedSourceFilesWithExcludeAsWinRTOption, sourceFilesExcludeAsWinRTRegex);
            }

            // Optimization: with projects with huge number of configurations, regexes are the exact same in multiple confs.
            // Here we group confs with exact same md5 of regexes to do a lot of matching a single time.
            var md5Hasher = System.Security.Cryptography.MD5.Create();
            var confRegexesHashToAnyConf = new Dictionary<string, Configuration>();
            var confToRegexesHash = new Dictionary<Configuration, string>();
            using (builder.CreateProfilingScope("Project.ResolveSourceFiles:GroupCommonRegexes", Configurations.Count))
            {
                foreach (Configuration conf in Configurations)
                {
                    var stream = new MemoryStream(2000);
                    var writer = new BinaryWriter(stream);
                    writer.Write(conf.SourceFilesBuildExcludeRegex.Count);
                    foreach (string val in conf.SourceFilesBuildExcludeRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsCRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsCRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsCPPRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsCPPRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsObjCRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsObjCRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsObjCPPRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsObjCPPRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsCLRRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsCLRRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsCLRExcludeRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsCLRExcludeRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsNonCLRRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsNonCLRRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesCompileAsWinRTRegex.Count);
                    foreach (string val in conf.SourceFilesCompileAsWinRTRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesExcludeAsWinRTRegex.Count);
                    foreach (string val in conf.SourceFilesExcludeAsWinRTRegex)
                        writer.Write(val);
                    writer.Write(conf.SourceFilesFiltersRegex.Count);
                    foreach (string val in conf.SourceFilesFiltersRegex)
                        writer.Write(val);

                    byte[] data = md5Hasher.ComputeHash(stream.GetBuffer());
                    string md5 = BitConverter.ToString(data);
                    confToRegexesHash[conf] = md5;
                    confRegexesHashToAnyConf[md5] = conf;
                }
            }

            using (builder.CreateProfilingScope("Project.ResolveSourceFiles:ApplyCommonRegexes", confRegexesHashToAnyConf.Count))
            {
                foreach (var conf in confRegexesHashToAnyConf.Values)
                {
                    conf.ResolvedSourceFilesBuildExclude.AddRange(resolvedSourceFilesBuildExclude);
                    var configSourceFilesBuildExcludeRegex = RegexCache.GetCachedRegexes(conf.SourceFilesBuildExcludeRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesBuildExclude, configSourceFilesBuildExcludeRegex);

                    // Resolve files that will be built as C Files 
                    conf.ResolvedSourceFilesWithCompileAsCOption.AddRange(resolvedSourceFilesWithCompileAsCOption);
                    var configSourceFilesCompileAsCRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsCRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithCompileAsCOption, configSourceFilesCompileAsCRegex);

                    // Resolve files that will be built as CPP Files 
                    conf.ResolvedSourceFilesWithCompileAsCPPOption.AddRange(resolvedSourceFilesWithCompileAsCPPOption);
                    var configSourceFilesCompileAsCPPRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsCPPRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithCompileAsCPPOption, configSourceFilesCompileAsCPPRegex);

                    // Resolve files that will be built as ObjC Files 
                    conf.ResolvedSourceFilesWithCompileAsObjCOption.AddRange(resolvedSourceFilesWithCompileAsObjCOption);
                    var configSourceFilesCompileAsObjCRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsObjCRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithCompileAsObjCOption, configSourceFilesCompileAsObjCRegex);

                    // Resolve files that will be built as ObjCPP Files 
                    conf.ResolvedSourceFilesWithCompileAsObjCPPOption.AddRange(resolvedSourceFilesWithCompileAsObjCPPOption);
                    var configSourceFilesCompileAsObjCPPRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsObjCPPRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithCompileAsObjCPPOption, configSourceFilesCompileAsObjCPPRegex);

                    // Resolve files that will be built as CLR Files 
                    conf.ResolvedSourceFilesWithCompileAsCLROption.AddRange(resolvedSourceFilesWithCompileAsCLROption);
                    var configSourceFilesCompileAsCLRRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsCLRRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithCompileAsCLROption, configSourceFilesCompileAsCLRRegex);

                    // Remove file that match SourceFilesCompileAsCLRExcludeRegex
                    var configCompileAsClrFilesExclude = new Strings();
                    configCompileAsClrFilesExclude.AddRange(compileAsClrFilesExclude);
                    var configSourceFilesCompileAsCLRExcludeRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsCLRExcludeRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, configCompileAsClrFilesExclude, configSourceFilesCompileAsCLRExcludeRegex);
                    conf.ResolvedSourceFilesWithCompileAsCLROption.RemoveRange(configCompileAsClrFilesExclude);

                    // Resolve non-CLR files.
                    conf.ResolvedSourceFilesWithCompileAsNonCLROption.AddRange(resolvedSourceFilesWithCompileAsNonCLROption);
                    var configSourceFilesCompileAsNonCLRRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsNonCLRRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithCompileAsNonCLROption, configSourceFilesCompileAsNonCLRRegex);

                    // Resolve files that will be built as WinRT Files 
                    conf.ResolvedSourceFilesWithCompileAsWinRTOption.AddRange(resolvedSourceFilesWithCompileAsWinRTOption);
                    var configSourceFilesCompileAsWinRTRegex = RegexCache.GetCachedRegexes(conf.SourceFilesCompileAsWinRTRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithCompileAsWinRTOption, configSourceFilesCompileAsWinRTRegex);

                    // Resolve files that will not be built as WinRT Files 
                    conf.ResolvedSourceFilesWithExcludeAsWinRTOption.AddRange(resolvedSourceFilesWithExcludeAsWinRTOption);
                    var configSourceFilesExcludeAsWinRTRegex = RegexCache.GetCachedRegexes(conf.SourceFilesExcludeAsWinRTRegex);
                    AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, conf.ResolvedSourceFilesWithExcludeAsWinRTOption, configSourceFilesExcludeAsWinRTRegex);

                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithCompileAsCOption);
                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithCompileAsCPPOption);
                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithCompileAsObjCOption);
                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithCompileAsObjCPPOption);
                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithCompileAsNonCLROption);
                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithCompileAsCLROption);
                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithCompileAsWinRTOption);
                    conf.ResolvedSourceFilesBlobExclude.AddRange(conf.ResolvedSourceFilesWithExcludeAsWinRTOption);

                    var configSourceFilesFiltersRegex = RegexCache.GetCachedRegexes(conf.SourceFilesFiltersRegex).ToArray();
                    if (conf.SourceFilesFiltersRegex.Count != 0)
                    {
                        foreach (var sourceFile in SourceFiles)
                        {
                            if (!configSourceFilesFiltersRegex.Any(regex => regex.Match(sourceFile).Success))
                                conf.ResolvedSourceFilesBuildExclude.Add(sourceFile);
                        }
                        Util.ResolvePath(SourceRootPath, ref conf.ResolvedSourceFilesBuildExclude);
                    }

                    // To allow sharing with other configs
                    conf.ResolvedSourceFilesWithCompileAsCOption.SetReadOnly(true);
                    conf.ResolvedSourceFilesWithCompileAsCPPOption.SetReadOnly(true);
                    conf.ResolvedSourceFilesWithCompileAsObjCOption.SetReadOnly(true);
                    conf.ResolvedSourceFilesWithCompileAsObjCPPOption.SetReadOnly(true);
                    conf.ResolvedSourceFilesWithCompileAsCLROption.SetReadOnly(true);
                    conf.ResolvedSourceFilesWithCompileAsNonCLROption.SetReadOnly(true);
                    conf.ResolvedSourceFilesWithCompileAsWinRTOption.SetReadOnly(true);
                    conf.ResolvedSourceFilesWithExcludeAsWinRTOption.SetReadOnly(true);
                }
            }

            using (builder.CreateProfilingScope("Project.ResolveSourceFiles:ApplyRegexesToConfigs", Configurations.Count))
            {
                foreach (Configuration conf in Configurations)
                {
                    if (conf.IsBlobbed)
                        oneBlobbed = true;

                    if (conf.IsFastBuild && conf.FastBuildBlobbed)
                        fastBuildBlobs = true;

                    conf.ResolvedSourceFilesBuildExclude.AddRange(SourceFilesExclude);

                    // add SourceFilesBuildExclude from the project
                    if (DebugBreaks.ShouldBreakOnSourcePath(DebugBreaks.Context.Resolving, ResolvedSourceFilesBuildExclude))
                        Debugger.Break();
                    conf.ResolvedSourceFilesBuildExclude.AddRange(ResolvedSourceFilesBuildExclude);
                    if (DebugBreaks.ShouldBreakOnSourcePath(DebugBreaks.Context.Resolving, conf.SourceFilesBuildExclude))
                        Debugger.Break();
                    conf.ResolvedSourceFilesBuildExclude.AddRange(conf.SourceFilesBuildExclude);

                    var doneConfWithSameRegexes = confRegexesHashToAnyConf[confToRegexesHash[conf]];

                    if (!Object.ReferenceEquals(doneConfWithSameRegexes, conf))
                    {
                        conf.ResolvedSourceFilesBuildExclude.AddRange(doneConfWithSameRegexes.ResolvedSourceFilesBuildExclude);

                        // Copy references here to be faster, these must not be modified from now on
                        conf.ResolvedSourceFilesWithCompileAsCOption = doneConfWithSameRegexes.ResolvedSourceFilesWithCompileAsCOption;
                        conf.ResolvedSourceFilesWithCompileAsCPPOption = doneConfWithSameRegexes.ResolvedSourceFilesWithCompileAsCPPOption;
                        conf.ResolvedSourceFilesWithCompileAsObjCOption = doneConfWithSameRegexes.ResolvedSourceFilesWithCompileAsObjCOption;
                        conf.ResolvedSourceFilesWithCompileAsObjCPPOption = doneConfWithSameRegexes.ResolvedSourceFilesWithCompileAsObjCPPOption;
                        conf.ResolvedSourceFilesWithCompileAsCLROption = doneConfWithSameRegexes.ResolvedSourceFilesWithCompileAsCLROption;
                        conf.ResolvedSourceFilesWithCompileAsNonCLROption = doneConfWithSameRegexes.ResolvedSourceFilesWithCompileAsNonCLROption;
                        conf.ResolvedSourceFilesWithCompileAsWinRTOption = doneConfWithSameRegexes.ResolvedSourceFilesWithCompileAsWinRTOption;
                        conf.ResolvedSourceFilesWithExcludeAsWinRTOption = doneConfWithSameRegexes.ResolvedSourceFilesWithExcludeAsWinRTOption;
                    }
                }
            }

            foreach (string sourceFile in ResolvedSourceFiles)
            {
                if (sourceFile.EndsWith(".asm", StringComparison.OrdinalIgnoreCase))
                {
                    ContainsASM = true;
                }
                if (sourceFile.EndsWith(".nasm", StringComparison.OrdinalIgnoreCase))
                {
                    ContainsNASM = true;
                }
            }

            if (oneBlobbed || fastBuildBlobs)
            {
                // Generator will use ResolvedSourceFiles and Configuration.ResolvedSourceFilesExclude, 
                // allow us to handle the blob here instead than in each generator

                // Don't blob precomp source file
                Strings configurationsNoBlobbedSourceFiles = GetConfigurationsNoBlobSourceFiles(ResolvedSourceFiles);

                // Exclude from blob all files that match any SourceFilesBlobExcludeRegex.
                if (AddMatchFiles(RootPath, resolvedSourceFilesRelative, ResolvedSourceFiles, SourceFilesBlobExclude, sourceFilesBlobExcludeRegex))
                    Debugger.Break();

                foreach (var conf in Configurations)
                    conf.ResolvedSourceFilesBlobExclude.AddRange(SourceFilesBlobExclude);

                // Use ResolvedSourceFiles sorted by relative paths
                var sortedResolvedSourceFiles = ResolvedSourceFiles.Zip(resolvedSourceFilesRelative, (file, relFile) => new Tuple<string, string>(file, relFile))
                                                                   .OrderBy(t => t.Item2, StringComparer.OrdinalIgnoreCase)
                                                                   .Select(t => t.Item1);

                foreach (string sourceFile in sortedResolvedSourceFiles)
                {
                    if (DebugBreaks.ShouldBreakOnSourcePath(DebugBreaks.Context.BlobbingResolving, sourceFile))
                        Debugger.Break();
                    string sourceFileExtension = Path.GetExtension(sourceFile);

                    if (SourceFilesCompileExtensions.Contains(sourceFileExtension))
                    {
                        if (SourceFilesBlobExtensions.Contains(sourceFileExtension) &&
                            !configurationsNoBlobbedSourceFiles.Contains(sourceFile) &&
                            !SourceFilesBlobExclude.Contains(sourceFile))
                        {
                            foreach (var entry in _blobPathContents)
                            {
                                if (!entry.Value.AlwaysExclusions.Contains(sourceFile) &&
                                    !entry.Value.PartialExclusions.Contains(sourceFile))
                                    entry.Value.ResolvedBlobbedSourceFiles.Add(sourceFile);
                            }
                        }
                        else
                        {
                            ResolvedNoBlobbedSourceFiles.Add(sourceFile);
                        }
                    }
                }

                foreach (var entry in _blobPathContents)
                {
                    BlobGenerateFiles(
                        entry.Key,
                        entry.Value.ResolvedBlobbedSourceFiles,
                        entry.Value.ResolvedBlobSourceFiles,
                        entry.Value.Configurations,
                        entry.Value.WorkBlobFileHeader,
                        entry.Value.WorkBlobFileFooter,
                        oneBlobbed
                    );
                    ResolvedSourceFiles.AddRange(entry.Value.ResolvedBlobSourceFiles);
                }

                // Set blob files from other blob paths
                foreach (var entry in _blobPathContents)
                {
                    foreach (var entry2 in _blobPathContents)
                    {
                        if (entry2.Key != entry.Key)
                        {
                            entry.Value.ResolvedBlobSourceFilesFromOtherContents.AddRange(entry2.Value.ResolvedBlobSourceFiles);
                        }
                    }
                }

                // Exclude blob files in other blob paths
                foreach (var config in Configurations)
                {
                    config.ResolvedSourceFilesBuildExclude.AddRange(_blobPathContents[config.BlobPath].ResolvedBlobSourceFilesFromOtherContents);
                }
            }

            foreach (Configuration conf in Configurations)
            {
                BlobPathContent blobContent = null;
                if (!_blobPathContents.TryGetValue(conf.BlobPath, out blobContent))
                {
                    continue;
                }

                if (conf.IsBlobbed)
                    conf.ResolvedSourceFilesBuildExclude.AddRange(blobContent.ResolvedBlobbedSourceFiles);
                else
                    conf.ResolvedSourceFilesBuildExclude.AddRange(blobContent.ResolvedBlobSourceFiles);
            }
        }