private void BlobGenerateFiles()

in Sharpmake/Project.cs [1475:1612]


        private void BlobGenerateFiles(
            string blobPath,
            Strings sourceFiles,
            Strings blobFiles,
            List<Configuration> configurations,
            string WorkBlobFileHeader,
            string WorkBlobFileFooter,
            bool writeBlobsOnDisk
        )
        {
            // Blob per directory, this make blob file more stable so it's change less 
            // when adding new sources files -> will save compile time :)
            List<SourceFile> currentBlobSourceFiles = new List<SourceFile>();
            var allBlobsFiles = new List<List<SourceFile>>();

            List<string> workBlobSourceFiles = null;
            if (BlobWorkEnabled)
                workBlobSourceFiles = new List<string>();

            int blobSize = configurations[0].BlobSize;
            foreach (var config in configurations)
            {
                if (config.BlobSize != blobSize)
                {
                    throw new Error(
                        "Cannot specify 2 different BlobSize, " + blobSize + " and " + config.BlobSize +
                        ", for blob path " + blobPath);
                }
            }
            if (blobSize == 0)
                blobSize = BlobSize;

            uint currentBlobSize = 0;
            uint totalWorkBlobSize = 0;

            string lastDirectoryFullName = "";

            foreach (string sourcefile in sourceFiles)
            {
                FileInfo sourceFileInfo = new FileInfo(sourcefile);
                if (sourceFileInfo.Directory.FullName != lastDirectoryFullName || (currentBlobSize > (blobSize + BlobSizeOverflow)))
                {
                    lastDirectoryFullName = sourceFileInfo.Directory.FullName;

                    if (currentBlobSize > blobSize)
                    {
                        allBlobsFiles.Add(currentBlobSourceFiles);
                        currentBlobSourceFiles = new List<SourceFile>();
                        currentBlobSize = 0;
                    }
                }

                uint currentFileSize = 0;
                if (Util.CountFakeFiles() > 0)
                {
                    currentFileSize = (uint)Util.GetFakeFileLength(sourceFileInfo.FullName);
                    if (currentFileSize == 0)
                        continue;
                }
                else if (sourceFileInfo.Exists)
                {
                    currentFileSize = (uint)sourceFileInfo.Length;
                }

                currentBlobSize += currentFileSize;

                bool isWorkBlobCandidate = (BlobWorkEnabled && !sourceFileInfo.IsReadOnly);
                currentBlobSourceFiles.Add(new SourceFile(sourcefile, isWorkBlobCandidate));
                if (isWorkBlobCandidate)
                {
                    workBlobSourceFiles.Add(sourcefile);
                    totalWorkBlobSize += currentFileSize;
                }
            }

            if (currentBlobSourceFiles.Count != 0)
            {
                allBlobsFiles.Add(currentBlobSourceFiles);
                currentBlobSourceFiles = null;
            }
            // Deactivate work blobs if too much files
            bool isBlobWorkEnabled = BlobWorkEnabled;
            if (isBlobWorkEnabled && totalWorkBlobSize > (BlobWorkFileCount * (blobSize + BlobSizeOverflow)))
            {
                isBlobWorkEnabled = false;
                workBlobSourceFiles.Clear();  //  to flush content of work blobs
            }

            // index of nb of blob created
            int nbBlobCreated = allBlobsFiles.Count;
            BlobCount = nbBlobCreated;

            // make the number of blobs a conf generates available to generators
            if (nbBlobCreated > 0)
            {
                foreach (Configuration conf in configurations)
                    conf.GeneratableBlobCount = nbBlobCreated;
            }

            // Capping the number of blob work to the number of blobs. It makes no sense to have more work blobs than blobs.
            if (BlobWorkFileCount > BlobCount)
                BlobWorkFileCount = BlobCount;

            // Write blobs
            if (writeBlobsOnDisk)
            {
                for (int i = 0; i < allBlobsFiles.Count; ++i)
                {
                    string blobFileName = string.Format(@"{0}_{1:000}", Name.ToLower(), i);
                    var blobbedFiles = (isBlobWorkEnabled) ?
                        from j in allBlobsFiles[i] where !j.IsWorkBlobCandidate select j.Path :
                        from j in allBlobsFiles[i] select j.Path;
                    blobFiles.Add(BlobGenerateFile(blobPath, blobbedFiles, blobFileName, configurations, null, null));
                }

                // write work blob size
                if (BlobWorkEnabled)
                {
                    var workBlobFiles = new List<List<string>>(BlobWorkFileCount);

                    for (int i = 0; i < BlobWorkFileCount; ++i)
                        workBlobFiles.Add(new List<string>());

                    foreach (string workkBlobSourceFile in workBlobSourceFiles)
                    {
                        string relativeWorkkBlobSourceFile = Util.PathGetRelative(SourceRootPath, workkBlobSourceFile);
                        int index = Math.Abs(Util.BuildGuid(relativeWorkkBlobSourceFile).GetHashCode() % workBlobFiles.Count);
                        workBlobFiles[index].Add(workkBlobSourceFile);
                    }

                    for (int i = 0; i < workBlobFiles.Count; ++i)
                    {
                        string blobFileName = string.Format(@"{0}_work_{1:000}", Name.ToLower(), i);
                        blobFiles.Add(BlobGenerateFile(blobPath, workBlobFiles[i], blobFileName, configurations, WorkBlobFileHeader, WorkBlobFileFooter));
                    }
                }
            }
        }