private static void GenerateMasterBffGlobalSettingsFile( Builder builder, string masterBffGlobalConfigFile, MasterBffInfo masterBffInfo ) { var fileGenerator = new FileGenerator(); WriteMasterSettingsSection(fileGenerator, masterBffInfo); WriteMasterCompilerSection(fileGenerator, masterBffInfo); // remove all line that contain RemoveLineTag fileGenerator.RemoveTaggedLines(); MemoryStream bffCleanMemoryStream = fileGenerator.ToMemoryStream(); // Write master bff global settings file FileInfo bffFileInfo = new FileInfo(masterBffGlobalConfigFile); if (builder.Context.WriteGeneratedFile(null, bffFileInfo, bffCleanMemoryStream)) { Project.AddFastbuildMasterGeneratedFile(masterBffGlobalConfigFile); } else { Project.IncrementFastBuildUpToDateFileCount(); } }
private static void WriteMasterCompilerSection( FileGenerator masterBffGenerator, MasterBffInfo masterBffInfo, Dictionary <string, CompilerSettings> masterCompilerSettings ) { var sortedMasterCompileSettings = masterCompilerSettings .Where(x => x.Value.DevEnv == masterBffInfo.DevEnv) .Where(x => masterBffInfo.Platforms.TestPlatformFlags(x.Value.PlatformFlags)) .OrderBy(x => x.Value.CompilerName); foreach (var compiler in sortedMasterCompileSettings) { var compilerSettings = compiler.Value; var compilerPlatform = compilerSettings.PlatformFlags; string fastBuildVS2012EnumBugWorkaround = FileGeneratorUtilities.RemoveLineTag; if (FastBuildSettings.EnableVS2012EnumBugWorkaround && compilerSettings.DevEnv == DevEnv.vs2012 && compilerPlatform.HasFlag(Platform.win64)) { fastBuildVS2012EnumBugWorkaround = ".VS2012EnumBugFix = true"; } using (masterBffGenerator.Declare("fastbuildCompilerName", compiler.Key)) using (masterBffGenerator.Declare("fastBuildVisualStudioEnvironment", compilerSettings.RootPath)) using (masterBffGenerator.Declare("fastBuildCompilerExecutable", string.IsNullOrEmpty(compilerSettings.Executable) ? FileGeneratorUtilities.RemoveLineTag : compilerSettings.Executable)) using (masterBffGenerator.Declare("fastBuildExtraFiles", compilerSettings.ExtraFiles.Count > 0 ? UtilityMethods.FBuildCollectionFormat(compilerSettings.ExtraFiles, 20) : FileGeneratorUtilities.RemoveLineTag)) using (masterBffGenerator.Declare("fastBuildVS2012EnumBugWorkaround", fastBuildVS2012EnumBugWorkaround)) { masterBffGenerator.Write(Bff.Template.ConfigurationFile.CompilerSetting); foreach (var compilerConfiguration in compilerSettings.Configurations) { var compConf = compilerConfiguration.Value; if (!masterBffInfo.Platforms.Contains(compConf.Platform)) { continue; } using (masterBffGenerator.Declare("fastBuildConfigurationName", compilerConfiguration.Key)) using (masterBffGenerator.Declare("fastBuildBinPath", compConf.BinPath)) using (masterBffGenerator.Declare("fastBuildLinkerPath", compConf.LinkerPath)) using (masterBffGenerator.Declare("fastBuildResourceCompiler", compConf.ResourceCompiler)) using (masterBffGenerator.Declare("fastBuildCompilerName", compConf.Compiler != FileGeneratorUtilities.RemoveLineTag ? compConf.Compiler : compiler.Key)) using (masterBffGenerator.Declare("fastBuildLibrarian", compConf.Librarian)) using (masterBffGenerator.Declare("fastBuildLinker", compConf.Linker)) using (masterBffGenerator.Declare("fastBuildPlatformLibPaths", string.IsNullOrWhiteSpace(compConf.PlatformLibPaths) ? FileGeneratorUtilities.RemoveLineTag : compConf.PlatformLibPaths)) using (masterBffGenerator.Declare("fastBuildExecutable", compConf.Executable)) using (masterBffGenerator.Declare("fastBuildUsing", compConf.UsingOtherConfiguration)) { masterBffGenerator.Write(Bff.Template.ConfigurationFile.CompilerConfiguration); } } } } }
private static void WriteMasterSettingsSection(FileGenerator masterBffGenerator, MasterBffInfo masterBffInfo) { string tempFolder = Path.GetTempPath(); string cachePath = FileGeneratorUtilities.RemoveLineTag; string cachePluginDLL = FileGeneratorUtilities.RemoveLineTag; string workerConnectionLimit = FileGeneratorUtilities.RemoveLineTag; if (FastBuildSettings.CachePath != null) { cachePath = ".CachePath = '" + FastBuildSettings.CachePath + "'"; if (FastBuildSettings.CachePluginDLLFilePath != null) { cachePluginDLL = ".CachePluginDLL = '" + FastBuildSettings.CachePluginDLLFilePath + "'"; } } if (FastBuildSettings.FastBuildWorkerConnectionLimit >= 0) { workerConnectionLimit = ".WorkerConnectionLimit = " + FastBuildSettings.FastBuildWorkerConnectionLimit.ToString(); } string fastBuildPATH = FileGeneratorUtilities.RemoveLineTag; if (FastBuildSettings.SetPathToResourceCompilerInEnvironment) { // !FIX FOR LINK : fatal error LNK1158: cannot run rc.exe! // // link.exe on win64 executes rc.exe by itself on some occasions // if it doesn't find it, link errors can occur // // link.exe will first search rc.exe next to it, and if it fails // it will look for it in the folders listed by the PATH // environment variable, so we'll try to replicate that process // in sharpmake: // // 1) Get the linker path // 2) Look for rc.exe near it // 3) If found, exit // 4) If not, add a PATH environment variable pointing to the rc.exe folder List <Platform> microsoftPlatforms = PlatformRegistry.GetAvailablePlatforms <IMicrosoftPlatformBff>().ToList(); var resourceCompilerPaths = new Strings(); foreach (CompilerSettings setting in masterBffInfo.CompilerSettings.Values) { if (!microsoftPlatforms.Any(x => setting.PlatformFlags.HasFlag(x))) { continue; } string defaultResourceCompilerPath = Path.GetDirectoryName(setting.DevEnv.GetWindowsResourceCompiler(Platform.win64)); foreach (var configurationPair in setting.Configurations) { var configuration = configurationPair.Value; // check if the configuration has a linker if (configuration.LinkerPath != FileGeneratorUtilities.RemoveLineTag) { // if so, try to find a rc.exe near it if (!File.Exists(Path.Combine(configuration.LinkerPath, "rc.exe"))) { // if not found, get the folder of the custom // rc.exe or the default one to add it to PATH if (configuration.ResourceCompiler != FileGeneratorUtilities.RemoveLineTag) { resourceCompilerPaths.Add(Path.GetDirectoryName(configuration.ResourceCompiler)); } else { resourceCompilerPaths.Add(defaultResourceCompilerPath); } } } } } if (resourceCompilerPaths.Count == 1) { fastBuildPATH = Util.GetCapitalizedPath(resourceCompilerPaths.First()); } else if (resourceCompilerPaths.Count > 1) { throw new Error("Multiple conflicting resource compilers found in PATH! Please verify your ResourceCompiler settings."); } } using (masterBffGenerator.Declare("fastBuildProjectName", "Master")) using (masterBffGenerator.Declare("fastBuildTempFolder", tempFolder)) using (masterBffGenerator.Declare("CachePath", cachePath)) using (masterBffGenerator.Declare("CachePluginDLL", cachePluginDLL)) using (masterBffGenerator.Declare("WorkerConnectionLimit", workerConnectionLimit)) using (masterBffGenerator.Declare("fastBuildSystemRoot", FastBuildSettings.SystemRoot)) using (masterBffGenerator.Declare("fastBuildUserProfile", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile))) using (masterBffGenerator.Declare("fastBuildPATH", fastBuildPATH)) using (masterBffGenerator.Declare("fastBuildAllowDBMigration", FastBuildSettings.FastBuildAllowDBMigration ? "true" : FileGeneratorUtilities.RemoveLineTag)) { masterBffGenerator.Write(Bff.Template.ConfigurationFile.HeaderFile); masterBffGenerator.Write(Bff.Template.ConfigurationFile.GlobalSettings); } }
private static bool GenerateMasterBffFile(Builder builder, ConfigurationsPerBff configurationsPerBff) { string masterBffFilePath = Util.GetCapitalizedPath(configurationsPerBff.BffFilePathWithExtension); string masterBffDirectory = Path.GetDirectoryName(masterBffFilePath); string masterBffFileName = Path.GetFileName(masterBffFilePath); // Global configuration file is in the same directory as the master bff but filename suffix added to its filename. string globalConfigFullPath = GetGlobalBffConfigFileName(masterBffFilePath); string globalConfigFileName = Path.GetFileName(globalConfigFullPath); var solutionProjects = configurationsPerBff.ResolvedProjects; if (solutionProjects.Count == 0 && configurationsPerBff.ProjectsWereFiltered) { // We are running in filter mode for submit assistant and all projects were filtered out. // We need to skip generation and delete any existing master bff file. Util.TryDeleteFile(masterBffFilePath); return(false); } // Start writing Bff var fileGenerator = new FileGenerator(); var masterBffInfo = new MasterBffInfo(); var bffPreBuildSection = new Dictionary <string, string>(); var bffCustomPreBuildSection = new Dictionary <string, string>(); var bffMasterSection = new Dictionary <string, string>(); var masterBffCopySections = new List <string>(); var masterBffCustomSections = new UniqueList <string>(); // section that is not ordered bool mustGenerateFastbuild = false; var platformBffCache = new Dictionary <Platform, IPlatformBff>(); var verificationPostBuildCopies = new Dictionary <string, string>(); foreach (Solution.Configuration solutionConfiguration in configurationsPerBff) { foreach (var solutionProject in solutionProjects) { var project = solutionProject.Project; // Export projects do not have any bff if (project.GetType().IsDefined(typeof(Export), false)) { continue; } // When the project has a source file filter, only keep it if the file list is not empty if (project.SourceFilesFilters != null && (project.SourceFilesFiltersCount == 0 || project.SkipProjectWhenFiltersActive)) { continue; } Solution.Configuration.IncludedProjectInfo includedProject = solutionConfiguration.GetProject(solutionProject.Project.GetType()); bool perfectMatch = includedProject != null && solutionProject.Configurations.Contains(includedProject.Configuration); if (!perfectMatch) { continue; } var conf = includedProject.Configuration; if (!conf.IsFastBuildEnabledProjectConfig()) { continue; } mustGenerateFastbuild = true; IPlatformBff platformBff = platformBffCache.GetValueOrAdd(conf.Platform, PlatformRegistry.Query <IPlatformBff>(conf.Platform)); platformBff.AddCompilerSettings(masterBffInfo.CompilerSettings, conf); if (FastBuildSettings.WriteAllConfigsSection && includedProject.ToBuild == Solution.Configuration.IncludedProjectInfo.Build.Yes) { masterBffInfo.AllConfigsSections.Add(Bff.GetShortProjectName(project, conf)); } using (fileGenerator.Declare("conf", conf)) using (fileGenerator.Declare("target", conf.Target)) using (fileGenerator.Declare("project", conf.Project)) { var preBuildEvents = new Dictionary <string, Project.Configuration.BuildStepBase>(); if (conf.Output == Project.Configuration.OutputType.Exe || conf.ExecuteTargetCopy) { var copies = ProjectOptionsGenerator.ConvertPostBuildCopiesToRelative(conf, masterBffDirectory); foreach (var copy in copies) { var sourceFile = copy.Key; var sourceFileName = Path.GetFileName(sourceFile); var destinationFolder = copy.Value; var destinationFile = Path.Combine(destinationFolder, sourceFileName); // use the global root for alias computation, as the project has not idea in which master bff it has been included var destinationRelativeToGlobal = Util.GetConvertedRelativePath(masterBffDirectory, destinationFolder, conf.Project.RootPath, true, conf.Project.RootPath); { string key = sourceFileName + destinationRelativeToGlobal; string currentSourceFullPath = Util.PathGetAbsolute(masterBffDirectory, sourceFile); string previous; if (verificationPostBuildCopies.TryGetValue(key, out previous)) { if (previous != currentSourceFullPath) { builder.LogErrorLine("A post-build copy to the destination '{0}' already exist but from different sources: '{1}' and '{2}'!", Util.PathGetAbsolute(masterBffDirectory, destinationFolder), previous, currentSourceFullPath); } } else { verificationPostBuildCopies.Add(key, currentSourceFullPath); } } string fastBuildCopyAlias = UtilityMethods.GetFastBuildCopyAlias(sourceFileName, destinationRelativeToGlobal); { using (fileGenerator.Declare("fastBuildCopyAlias", fastBuildCopyAlias)) using (fileGenerator.Declare("fastBuildCopySource", sourceFile)) using (fileGenerator.Declare("fastBuildCopyDest", destinationFile)) { if (!bffMasterSection.ContainsKey(fastBuildCopyAlias)) { bffMasterSection.Add(fastBuildCopyAlias, fileGenerator.Resolver.Resolve(Bff.Template.ConfigurationFile.CopyFileSection)); } } } } foreach (var eventPair in conf.EventPreBuildExecute) { preBuildEvents.Add(eventPair.Key, eventPair.Value); } foreach (var buildEvent in conf.ResolvedEventPreBuildExe) { string eventKey = ProjectOptionsGenerator.MakeBuildStepName(conf, buildEvent, Vcxproj.BuildStep.PreBuild); preBuildEvents.Add(eventKey, buildEvent); } WriteEvents(fileGenerator, preBuildEvents, bffPreBuildSection, masterBffDirectory); } var customPreBuildEvents = new Dictionary <string, Project.Configuration.BuildStepBase>(); foreach (var eventPair in conf.EventCustomPrebuildExecute) { customPreBuildEvents.Add(eventPair.Key, eventPair.Value); } foreach (var buildEvent in conf.ResolvedEventCustomPreBuildExe) { string eventKey = ProjectOptionsGenerator.MakeBuildStepName(conf, buildEvent, Vcxproj.BuildStep.PreBuildCustomAction); customPreBuildEvents.Add(eventKey, buildEvent); } WriteEvents(fileGenerator, customPreBuildEvents, bffCustomPreBuildSection, masterBffDirectory); if (includedProject.ToBuild == Solution.Configuration.IncludedProjectInfo.Build.Yes) { MergeBffIncludeTreeRecursive(conf, ref masterBffInfo.BffIncludeToDependencyIncludes); } } } } if (!mustGenerateFastbuild) { throw new Error("Sharpmake-FastBuild : Trying to generate a MasterBff with none of its projects having a FastBuild configuration, or having a platform supporting it, or all of them having conf.DoNotGenerateFastBuild = true"); } masterBffCopySections.AddRange(bffMasterSection.Values); masterBffCopySections.AddRange(bffPreBuildSection.Values); masterBffCustomSections.AddRange(bffCustomPreBuildSection.Values); var result = new StringBuilder(); foreach (var projectBffFullPath in GetMasterIncludeList(masterBffInfo.BffIncludeToDependencyIncludes)) { string projectFullPath = Path.GetDirectoryName(projectBffFullPath); var projectPathRelativeFromMasterBff = Util.PathGetRelative(masterBffDirectory, projectFullPath, true); string bffKeyRelative = Path.Combine(Bff.CurrentBffPathKey, Path.GetFileName(projectBffFullPath)); string include = string.Join( Environment.NewLine, "{", $" {Bff.CurrentBffPathVariable} = \"{projectPathRelativeFromMasterBff}\"", $" #include \"{bffKeyRelative}\"", "}" ); result.AppendLine(include); } string fastBuildMasterBffDependencies = result.Length == 0 ? FileGeneratorUtilities.RemoveLineTag : result.ToString(); GenerateMasterBffGlobalSettingsFile(builder, globalConfigFullPath, masterBffInfo); using (fileGenerator.Declare("fastBuildProjectName", masterBffFileName)) using (fileGenerator.Declare("fastBuildGlobalConfigurationInclude", $"#include \"{globalConfigFileName}\"")) { fileGenerator.Write(Bff.Template.ConfigurationFile.HeaderFile); foreach (Platform platform in platformBffCache.Keys) // kind of cheating to use that cache instead of the masterBffInfo.CompilerSettings, but it works :) { using (fileGenerator.Declare("fastBuildDefine", Bff.GetPlatformSpecificDefine(platform))) fileGenerator.Write(Bff.Template.ConfigurationFile.Define); } fileGenerator.Write(Bff.Template.ConfigurationFile.GlobalConfigurationInclude); } WriteMasterCopySection(fileGenerator, masterBffCopySections); WriteMasterCustomSection(fileGenerator, masterBffCustomSections); using (fileGenerator.Declare("fastBuildProjectName", masterBffFileName)) using (fileGenerator.Declare("fastBuildOrderedBffDependencies", fastBuildMasterBffDependencies)) { fileGenerator.Write(Bff.Template.ConfigurationFile.Includes); } if (masterBffInfo.AllConfigsSections.Count != 0) { using (fileGenerator.Declare("fastBuildConfigs", UtilityMethods.FBuildFormatList(masterBffInfo.AllConfigsSections, 4))) { fileGenerator.Write(Bff.Template.ConfigurationFile.AllConfigsSection); } } // remove all line that contain RemoveLineTag fileGenerator.RemoveTaggedLines(); MemoryStream bffCleanMemoryStream = fileGenerator.ToMemoryStream(); // Write master .bff file FileInfo bffFileInfo = new FileInfo(masterBffFilePath); bool updated = builder.Context.WriteGeneratedFile(null, bffFileInfo, bffCleanMemoryStream); foreach (var confsPerSolution in configurationsPerBff) { confsPerSolution.Solution.PostGenerationCallback?.Invoke(masterBffDirectory, Path.GetFileNameWithoutExtension(masterBffFileName), FastBuildSettings.FastBuildConfigFileExtension); } return(updated); }
private static void WriteMasterCompilerSection(FileGenerator masterBffGenerator, MasterBffInfo masterBffInfo) { var sortedMasterCompileSettings = masterBffInfo.CompilerSettings.OrderBy(x => x.Value.CompilerName); foreach (var compiler in sortedMasterCompileSettings) { var compilerSettings = compiler.Value; var compilerPlatform = compilerSettings.PlatformFlags; string fastBuildCompilerFamily = UtilityMethods.GetFBuildCompilerFamily(compilerSettings.FastBuildCompilerFamily); string fastBuildCompilerUseRelativePaths = FileGeneratorUtilities.RemoveLineTag; if (FastBuildSettings.CompilersUsingRelativePaths.Contains(compiler.Key)) { fastBuildCompilerUseRelativePaths = "true"; } string fastBuildVS2012EnumBugWorkaround = FileGeneratorUtilities.RemoveLineTag; if (FastBuildSettings.EnableVS2012EnumBugWorkaround && compilerSettings.DevEnv == DevEnv.vs2012 && compilerPlatform.HasFlag(Platform.win64)) { fastBuildVS2012EnumBugWorkaround = ".VS2012EnumBugFix = true"; } string fastBuildCompilerAdditionalSettings = FileGeneratorUtilities.RemoveLineTag; if (FastBuildSettings.AdditionalCompilerSettings.TryGetValue(compiler.Key, out IList <string> extraOptions) && extraOptions.Any()) { fastBuildCompilerAdditionalSettings = string.Join(Environment.NewLine, extraOptions.Select(option => " " + option)); } using (masterBffGenerator.Declare("fastbuildCompilerName", compiler.Key)) using (masterBffGenerator.Declare("fastBuildCompilerRootPath", compilerSettings.RootPath)) using (masterBffGenerator.Declare("fastBuildCompilerExecutable", string.IsNullOrEmpty(compilerSettings.Executable) ? FileGeneratorUtilities.RemoveLineTag : compilerSettings.Executable)) using (masterBffGenerator.Declare("fastBuildExtraFiles", compilerSettings.ExtraFiles.Count > 0 ? UtilityMethods.FBuildCollectionFormat(compilerSettings.ExtraFiles, 28) : FileGeneratorUtilities.RemoveLineTag)) using (masterBffGenerator.Declare("fastBuildCompilerFamily", string.IsNullOrEmpty(fastBuildCompilerFamily) ? FileGeneratorUtilities.RemoveLineTag : fastBuildCompilerFamily)) using (masterBffGenerator.Declare("fastBuildCompilerUseRelativePaths", fastBuildCompilerUseRelativePaths)) using (masterBffGenerator.Declare("fastBuildVS2012EnumBugWorkaround", fastBuildVS2012EnumBugWorkaround)) using (masterBffGenerator.Declare("fastBuildCompilerAdditionalSettings", fastBuildCompilerAdditionalSettings)) { masterBffGenerator.Write(Bff.Template.ConfigurationFile.CompilerSetting); foreach (var compilerConfiguration in compilerSettings.Configurations.OrderBy(x => x.Key)) { var compConf = compilerConfiguration.Value; string fastBuildLinkerType = UtilityMethods.GetFBuildLinkerType(compConf.FastBuildLinkerType); using (masterBffGenerator.Declare("fastBuildConfigurationName", compilerConfiguration.Key)) using (masterBffGenerator.Declare("fastBuildBinPath", compConf.BinPath)) using (masterBffGenerator.Declare("fastBuildLinkerPath", compConf.LinkerPath)) using (masterBffGenerator.Declare("fastBuildResourceCompiler", compConf.ResourceCompiler)) using (masterBffGenerator.Declare("fastBuildCompilerName", compConf.Compiler != FileGeneratorUtilities.RemoveLineTag ? compConf.Compiler : compiler.Key)) using (masterBffGenerator.Declare("fastBuildLibrarian", compConf.Librarian)) using (masterBffGenerator.Declare("fastBuildLinker", compConf.Linker)) using (masterBffGenerator.Declare("fastBuildLinkerType", string.IsNullOrEmpty(fastBuildLinkerType) ? FileGeneratorUtilities.RemoveLineTag : fastBuildLinkerType)) using (masterBffGenerator.Declare("fastBuildPlatformLibPaths", string.IsNullOrWhiteSpace(compConf.PlatformLibPaths) ? FileGeneratorUtilities.RemoveLineTag : compConf.PlatformLibPaths)) using (masterBffGenerator.Declare("fastBuildExecutable", compConf.Executable)) using (masterBffGenerator.Declare("fastBuildUsing", compConf.UsingOtherConfiguration)) { masterBffGenerator.Write(Bff.Template.ConfigurationFile.CompilerConfiguration); } } } } }