in Sharpmake/Project.cs [1769:1886]
public virtual void PostResolve()
{
// below checks are very very very costly, may take up to about 20 sec for huge codebase.
if (Builder.Instance.Diagnostics && Util.CountFakeFiles() == 0)
{
// Cache the following File/Directory.Exists, avoiding redundant call for files in multiple configs
var pathExistsCache = new Dictionary<string, bool>(256);
bool PathExists(string path, Func<string, bool> checker)
{
bool result;
if (!pathExistsCache.TryGetValue(path, out result))
pathExistsCache.Add(path, result = checker(path));
return result;
}
bool FileExists(string path) => PathExists(path, File.Exists);
bool DirectoryExists(string path) => PathExists(path, Directory.Exists);
foreach (Configuration conf in Configurations)
{
var includePathsExcludeFromWarningRegex = RegexCache.GetCachedRegexes(IncludePathsExcludeFromWarningRegex).ToArray();
var libraryPathsExcludeFromWarningRegex = RegexCache.GetCachedRegexes(LibraryPathsExcludeFromWarningRegex).ToArray();
// check if the files marked with specific options still exist
foreach (var array in new Dictionary<Strings, string> {
{conf.ResolvedSourceFilesWithCompileAsCLROption, nameof(conf.ResolvedSourceFilesWithCompileAsCLROption)},
{conf.ResolvedSourceFilesWithCompileAsCOption, nameof(conf.ResolvedSourceFilesWithCompileAsCOption)},
{conf.ResolvedSourceFilesWithCompileAsCPPOption, nameof(conf.ResolvedSourceFilesWithCompileAsCPPOption)},
{conf.ResolvedSourceFilesWithCompileAsObjCOption, nameof(conf.ResolvedSourceFilesWithCompileAsObjCOption)},
{conf.ResolvedSourceFilesWithCompileAsObjCPPOption, nameof(conf.ResolvedSourceFilesWithCompileAsObjCPPOption)},
{conf.ResolvedSourceFilesWithCompileAsNonCLROption, nameof(conf.ResolvedSourceFilesWithCompileAsNonCLROption)},
{conf.ResolvedSourceFilesWithCompileAsWinRTOption, nameof(conf.ResolvedSourceFilesWithCompileAsWinRTOption)},
})
{
foreach (string file in array.Key)
{
if (!FileExists(file))
{
ReportError($@"{conf.Project.SharpmakeCsFileName}: Error: File contained in {array.Value} doesn't exist: {file}.");
}
}
}
// check if the files marked as excluded from build still exist
foreach (var array in new Dictionary<Strings, string> {
{conf.ResolvedSourceFilesBuildExclude, nameof(conf.ResolvedSourceFilesBuildExclude)},
{conf.ResolvedSourceFilesBlobExclude, nameof(conf.ResolvedSourceFilesBlobExclude)},
{conf.ResolvedSourceFilesWithExcludeAsWinRTOption, nameof(conf.ResolvedSourceFilesWithExcludeAsWinRTOption)},
{conf.PrecompSourceExclude, nameof(conf.PrecompSourceExclude)}
})
{
foreach (string file in array.Key)
{
if (!FileExists(file))
{
ReportError($@"{conf.Project.SharpmakeCsFileName}: Warning: File contained in {array.Value} doesn't exist: {file}.", onlyWarn: true);
}
}
}
// check if the inclusion paths exist
foreach (var includeArray in new[] { conf.IncludePaths, conf.IncludePrivatePaths })
{
foreach (string folder in includeArray)
{
if (!folder.StartsWith("$", StringComparison.Ordinal) && !includePathsExcludeFromWarningRegex.Any(regex => regex.Match(folder).Success) && !DirectoryExists(folder))
{
ReportError($@"{conf.Project.SharpmakeCsFileName}: Warning: Folder contained in include paths doesn't exist: {folder}.", true);
}
}
}
// check if the library paths exist, and if the libs can be found in them
var allLibraryFiles = new OrderableStrings(conf.LibraryFiles);
var allLibraryPaths = new OrderableStrings(conf.LibraryPaths);
var configTasks = PlatformRegistry.Get<Configuration.IConfigurationTasks>(conf.Platform);
var platformLibraryPaths = configTasks.GetPlatformLibraryPaths(conf);
allLibraryPaths.AddRange(platformLibraryPaths);
// remove all the rooted files
var allRootedFiles = allLibraryFiles.Where(file => Path.IsPathRooted(file)).ToArray();
allLibraryFiles.RemoveRange(allRootedFiles);
string platformLibPrefix = configTasks.GetOutputFileNamePrefix(Configuration.OutputType.Lib);
string platformLibExtension = configTasks.GetDefaultOutputFullExtension(Configuration.OutputType.Lib);
foreach (string folder in allLibraryPaths)
{
if (!folder.StartsWith("$", StringComparison.Ordinal) && !libraryPathsExcludeFromWarningRegex.Any(regex => regex.Match(folder).Success) && !DirectoryExists(folder))
{
ReportError($@"{conf.Project.SharpmakeCsFileName}: Warning: Folder contained in conf.LibraryPaths doesn't exist. Folder: {folder}.", true);
}
else
{
// now check every library files, and remove them from the total array if it exists on disk
var toRemove = new List<string>();
foreach (string file in allLibraryFiles)
{
string path = Path.Combine(folder, file);
if (FileExists(path) || FileExists(path + platformLibExtension) || FileExists(Path.Combine(folder, platformLibPrefix + file + platformLibExtension)))
toRemove.Add(file);
}
allLibraryFiles.RemoveRange(toRemove);
}
}
// Add all rooted files that are missing
allLibraryFiles.Add(allRootedFiles.Where(file => !FileExists(file)).ToArray());
// everything that remains is a missing library file
foreach (string file in allLibraryFiles)
{
ReportError($@"{conf.Project.SharpmakeCsFileName}: Warning: File contained in conf.LibraryFiles doesn't exist. File: {file}. Conf: {conf}", true);
}
}
}
}