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));
}
}
}
}