def __DiscoverMissingPackages( self, config: Config, activePlatform: GeneratorPluginBase, packageDict: Dict[str, List[XmlGenFile]], genFiles: List[XmlGenFile]) -> Dict[str, XmlGenFile]: """ Create a dict where the key is the name of the missing package and the value is the xmlGenFile that first requested it """ missingPackages = {} # type: Dict[str, XmlGenFile] for entry in genFiles: for dep in entry.DirectDependencies: if not dep.Name in packageDict: if not dep.Name in missingPackages: missingPackages[dep.Name] = entry if config.Verbosity > 1: config.LogPrint(".. {0} missing {1}".format( entry.Name, dep.Name)) for platform in list(entry.Platforms.values()): if activePlatform.Id == PluginSharedValues.PLATFORM_ID_ALL or platform.Name == activePlatform.Name: for dep in platform.DirectDependencies: if not dep.Name in packageDict: if not dep.Name in missingPackages: missingPackages[dep.Name] = entry if config.Verbosity >= 2 and config.Verbosity < 4: config.LogPrint( ".. Platform {0} package {1} missing {2}" .format(platform.Name, entry.Name, dep.Name)) if config.Verbosity >= 4: config.LogPrint( ".. Platform {0} package {1} missing {2}". format(platform.Name, entry.Name, dep.Name)) return missingPackages
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: # Check if a environment variable has been set to disable this tool # This is for example done by FslBuild to prevent multiple executions of content building. toolEnabled = IOUtil.TryGetEnvironmentVariable(CONFIG_FSLBUILDCONTENT_ENABLED) featureList = localToolConfig.BuildPackageFilters.FeatureNameList config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) # Get the platform and see if its supported buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig(localToolConfig.BuildVariantsDict) generator = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById(localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, False, config.ToolConfig.CMakeConfiguration, localToolConfig.GetUserCMakeConfig()) PlatformUtil.CheckBuildPlatform(generator.PlatformName) generatorContext = GeneratorContext(config, self.ErrorHelpManager, localToolConfig.BuildPackageFilters.RecipeFilterManager, config.ToolConfig.Experimental, generator) config.LogPrint("Active platform: {0}".format(generator.PlatformName)) discoverFeatureList = '*' in featureList topLevelPackage = None if discoverFeatureList or localToolConfig.Project is None: if discoverFeatureList: config.LogPrint("No features specified, so using package to determine them") topLevelPackage = self.__ResolveAndGetTopLevelPackage(generatorContext, config, currentDirPath, toolConfig.GetMinimalConfig(), localToolConfig.Recursive) if discoverFeatureList: featureList = [entry.Name for entry in topLevelPackage.ResolvedAllUsedFeatures] #if localToolConfig.Project is None: # executeablePackage = PackageListUtil.FindFirstExecutablePackage(packages) # localToolConfig.Project = executeablePackage.ShortName if localToolConfig.Validate: Validate.ValidatePlatform(config, localToolConfig.PlatformName, featureList) if topLevelPackage is None: topLevelPackage = self.__ResolveAndGetTopLevelPackage(generatorContext, config, currentDirPath, toolConfig.GetMinimalConfig(), localToolConfig.Recursive) RecipeBuilder.ValidateInstallationForPackages(config, generatorContext, topLevelPackage.ResolvedBuildOrder) if toolEnabled is not None and not ParseUtil.ParseBool(toolEnabled): if self.Log.Verbosity > 0: print("FslBuildContent has been disabled by environment variable {0} set to {1}".format(CONFIG_FSLBUILDCONTENT_ENABLED, toolEnabled)) return locations = toolConfig.PackageConfiguration[localToolConfig.PackageConfigurationType].Locations if not localToolConfig.Recursive or topLevelPackage is None: location = self.__TryFindLocation(locations, currentDirPath) if location is None: raise Exception("Could not locate location for {0}".format(currentDirPath)) packagePath = PackagePath(currentDirPath, location) ContentBuilder.Build(config, packagePath, featureList, localToolConfig.Output) else: # Location not found, but its ok since '-r' was specified and we have a top level package for foundPackage in topLevelPackage.ResolvedBuildOrder: if foundPackage.Type == PackageType.Executable: foundFeatureList = [entry.Name for entry in foundPackage.ResolvedAllUsedFeatures] if foundPackage.Path is None: raise Exception("Invalid package") ContentBuilder.Build(config, foundPackage.Path, foundFeatureList)
def DoGenerate(self, platformContext: PlatformContext, config: Config, packages: List[Package]) -> List[Package]: generator = None # type: Optional[GeneratorBase] topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) androidABIList = self.OptionAndroidABI_all if GEN_MAGIC_VARIANT_ANDROID_ABI in config.VariantsDict: androidABI = config.VariantsDict[GEN_MAGIC_VARIANT_ANDROID_ABI] if androidABI != 'all': if not androidABI in self.VariantAndroidABI.Options: raise Exception( "'{0}' is not a valid option expected one of these {1}" .format(androidABI, self.VariantAndroidABI.Options)) androidABIList = [androidABI] # remove unsupported ABI's if there are others available to build if self.__ContainsFeature(topLevelPackage.ResolvedAllUsedFeatures, "vulkan"): if len( androidABIList ) > 1 and AndroidABIOption.DeprecatedArmeAbi in androidABIList: config.LogPrint( "INFO: Vulkan does not support ANDROID_ABI '{0}' removing the ABI and building the rest" .format(AndroidABIOption.DeprecatedArmeAbi)) androidABIList.remove(AndroidABIOption.DeprecatedArmeAbi) generator = GeneratorAndroidGradleCMake(config, packages, self.Name, androidABIList) return self.GenerateDone(config, packages, self.Name, generator)
def ExtractArguments(toolAppContext: ToolAppContext, config: Config, exePackages: List[Package], extractArguments: str, currentDir: str) -> Dict[Package, JsonDictType]: config.LogPrint("Building all executable packages to extract their command line arguments") filterDir = None if extractArguments == '*' else currentDir res = {} # type: Dict[Package, JsonDictType] for package in exePackages: if filterDir is None or package.AbsolutePath == filterDir: config.LogPrint("- Building and running {0}".format(package.Name)) arguments = TryBuildAndRun(toolAppContext, config, package) if arguments is not None: res[package] = arguments # quick exit #return res return res
def __patchABIList(self, config: Config, package: Package, androidABIList: List[str]) -> List[str]: if not AndroidABIOption.DeprecatedArmeAbi in androidABIList and not AndroidABIOption.DeprecatedMips in androidABIList and not AndroidABIOption.DeprecatedMips64 in androidABIList: return androidABIList removed = [] result = list(androidABIList) for depPackage in package.ResolvedBuildOrder: if depPackage.Name.lower() == "assimp": if AndroidABIOption.DeprecatedArmeAbi in androidABIList: result.remove(AndroidABIOption.DeprecatedArmeAbi) removed.append(AndroidABIOption.DeprecatedArmeAbi) if AndroidABIOption.DeprecatedMips in androidABIList: result.remove(AndroidABIOption.DeprecatedMips) removed.append(AndroidABIOption.DeprecatedMips) if AndroidABIOption.DeprecatedMips64 in androidABIList: result.remove(AndroidABIOption.DeprecatedMips64) removed.append(AndroidABIOption.DeprecatedMips64) # If all would be removed by this patch, dont remove anything and let the checker catch incompatibility issue so its reported if len(result) <= 0: return androidABIList if len(removed) > 0: config.LogPrint("Removed incompatible assimp ABI's: %s" % (removed)) return result
def TryBuildAndRun(toolAppContext: ToolAppContext, config: Config, package: Package) -> Optional[JsonDictType]: if package.ResolvedPlatformNotSupported: return None if package.AbsolutePath is None: raise Exception("Invalid package") workDir = package.AbsolutePath tmpOutputFilename = IOUtil.Join(workDir, 'FslBuildDoc_AppArguments.json') try: # FslBuild.py --ForAllExe "(EXE) --System.Arguments.Save <filename>" toolFlowConfig = ToolFlowBuild.GetDefaultLocalConfig() toolFlowConfig.SetToolAppConfigValues(toolAppContext.ToolAppConfig) toolFlowConfig.ForAllExe = '(EXE) --System.Arguments.Save {0} -h'.format( tmpOutputFilename) buildFlow = ToolFlowBuild.ToolFlowBuild(toolAppContext) buildFlow.Process(workDir, config.ToolConfig, toolFlowConfig) return ReadJsonFile(tmpOutputFilename) except (Exception) as ex: if toolAppContext.LowLevelToolConfig.DebugEnabled: raise config.LogPrint( "Failed to build and run '{0}' due to exception {1}".format( package.Name, ex)) return None finally: IOUtil.RemoveFile(tmpOutputFilename)
def DoGenerateBuildFiles( pluginConfigContext: PluginConfigContext, config: Config, errorHelpManager: ErrorHelpManager, files: List[str], platformGeneratorPlugin: GeneratorPlugin, packageFilters: PackageFilters ) -> Union[List[Package], MultiPlatformPackageResultType]: config.LogPrint("- Generating build files") isSDKBuild = len(files) <= 0 packageLoader = PackageLoader(config, files, platformGeneratorPlugin) res = [] # type: Union[List[Package], MultiPlatformPackageResultType] if platformGeneratorPlugin.PlatformId == PluginSharedValues.PLATFORM_ID_ALL: resDict = {} # type: MultiPlatformPackageResultType for entry in pluginConfigContext.GetGeneratorPlugins(): if not config.IsTestMode or not entry.InDevelopment: packages = __ResolveAndGenerate(config, errorHelpManager, entry, copy.deepcopy(packageLoader), packageFilters, isSDKBuild) resDict[entry.PlatformName] = (packages, entry) res = resDict else: res = __ResolveAndGenerate(config, errorHelpManager, platformGeneratorPlugin, packageLoader, packageFilters, isSDKBuild) return res
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: config = Config(self.Log, toolConfig, 'sdk', localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) if localToolConfig.DryRun: config.ForceDisableAllWrite() if localToolConfig.ToCDepth < 1: localToolConfig.ToCDepth = 1 elif localToolConfig.ToCDepth > 4: localToolConfig.ToCDepth = 4 config.PrintTitle() # Get the platform and see if its supported platform = PluginConfig.GetGeneratorPluginById( localToolConfig.PlatformName, False) PlatformUtil.CheckBuildPlatform(platform.Name) config.LogPrint("Active platform: {0}".format(platform.Name)) packageFilters = localToolConfig.BuildPackageFilters theFiles = MainFlow.DoGetFiles(config, toolConfig.GetMinimalConfig(), currentDirPath, localToolConfig.Recursive) generatorContext = GeneratorContext(config, config.ToolConfig.Experimental, platform) packages = MainFlow.DoGetPackages(generatorContext, config, theFiles, packageFilters) #topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) #featureList = [entry.Name for entry in topLevelPackage.ResolvedAllUsedFeatures] for rootDir in config.ToolConfig.RootDirectories: readmePath = IOUtil.Join(rootDir.ResolvedPath, "README.md") packageReadMeLines = TryLoadReadMe(config, readmePath) result = ProcessPackages(self.ToolAppContext, config, packages, rootDir, localToolConfig.ExtractArguments, toolConfig.BuildDocConfiguration) if packageReadMeLines is not None: packageReadMeLinesNew = TryReplaceSection( config, packageReadMeLines, "AG_DEMOAPPS", result, readmePath) if packageReadMeLinesNew is not None: packageReadMeLines = packageReadMeLinesNew packageReadMeLinesNew = TryInsertTableOfContents( config, packageReadMeLines, localToolConfig.ToCDepth, readmePath) if packageReadMeLinesNew is not None: packageReadMeLines = packageReadMeLinesNew SaveReadMe(config, readmePath, packageReadMeLines) elif config.Verbosity > 2: config.LogPrintWarning("No README.md found in {0}".format( rootDir.ResolvedPath))
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) #if localToolConfig.DryRun: # config.ForceDisableAllWrite() if localToolConfig.IgnoreNotSupported: config.IgnoreNotSupported = True self.Log.PrintTitle() packageFilters = localToolConfig.BuildPackageFilters buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig(localToolConfig.BuildVariantsDict) generator = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById(localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, config.ToolConfig.DefaultPackageLanguage, config.ToolConfig.CMakeConfiguration, localToolConfig.GetUserCMakeConfig(), False) theFiles = MainFlow.DoGetFiles(config, toolConfig.GetMinimalConfig(generator.CMakeConfig), currentDirPath, localToolConfig.Recursive) generatorContext = GeneratorContext(config, self.ErrorHelpManager, packageFilters.RecipeFilterManager, config.ToolConfig.Experimental, generator) packages = MainFlow.DoGetPackages(generatorContext, config, theFiles, packageFilters, autoAddRecipeExternals=False) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) requestedFiles = None if config.IsSDKBuild else theFiles if localToolConfig.SaveJson is not None: if localToolConfig.BuildPackageFilters.ExtensionNameList is None: raise Exception("Invalid config missing ExtensionNameList filters") config.LogPrint("Saving to json file '{0}'".format(localToolConfig.SaveJson)) generatorConfig = GeneratorConfig(generator.PlatformName, config.SDKConfigTemplatePath, config.ToolConfig, 1, CommandType.Build) InfoSaver.SavePackageMetaDataToJson(generatorContext, generatorConfig, localToolConfig.SaveJson, config, topLevelPackage, localToolConfig.PackageTypeList, localToolConfig.IncludeGeneratorReport) if localToolConfig.ListFeatures: Builder.ShowFeatureList(self.Log, topLevelPackage, requestedFiles) if localToolConfig.ListVariants: requestedFiles = None if config.IsSDKBuild else theFiles Builder.ShowVariantList(self.Log, topLevelPackage, requestedFiles, generator) if localToolConfig.ListBuildVariants: Builder.ShowBuildVariantList(self.Log, generator) if localToolConfig.ListExtensions: Builder.ShowExtensionList(self.Log, topLevelPackage, requestedFiles) if localToolConfig.ListRequirements: Builder.ShowRequirementList(self.Log, topLevelPackage, requestedFiles) if localToolConfig.ListRecipes: RecipeInfo.ShowRecipeList(self.Log, topLevelPackage, requestedFiles) if localToolConfig.Stats: self.__ShowStats(topLevelPackage)
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: config = Config(self.Log, toolConfig, 'sdk', localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) if localToolConfig.DryRun: config.ForceDisableAllWrite() if localToolConfig.ToCDepth < 1: localToolConfig.ToCDepth = 1 elif localToolConfig.ToCDepth > 4: localToolConfig.ToCDepth = 4 config.PrintTitle() # Get the generator and see if its supported buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig(localToolConfig.BuildVariantsDict) generator = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById(localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, False, config.ToolConfig.CMakeConfiguration, localToolConfig.GetUserCMakeConfig()) PlatformUtil.CheckBuildPlatform(generator.PlatformName) config.LogPrint("Active platform: {0}".format(generator.PlatformName)) packageFilters = localToolConfig.BuildPackageFilters theFiles = MainFlow.DoGetFiles(config, toolConfig.GetMinimalConfig(), currentDirPath, localToolConfig.Recursive) generatorContext = GeneratorContext(config, self.ErrorHelpManager, packageFilters.RecipeFilterManager, config.ToolConfig.Experimental, generator) packages = MainFlow.DoGetPackages(generatorContext, config, theFiles, packageFilters) #topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) #featureList = [entry.Name for entry in topLevelPackage.ResolvedAllUsedFeatures] for projectContext in config.ToolConfig.ProjectInfo.Contexts: rootDir = self.__TryLocateRootDirectory(config.ToolConfig.RootDirectories, projectContext.Location) if rootDir is None: raise Exception("Root directory not found for location {0}".format(projectContext.Location)) readmePath = IOUtil.Join(rootDir.ResolvedPath, "README.md") packageReadMeLines = TryLoadReadMe(config, readmePath) result = ProcessPackages(self.ToolAppContext, config, packages, rootDir, localToolConfig.ExtractArguments, toolConfig.BuildDocConfiguration, currentDirPath) if packageReadMeLines is not None: projectCaption = "# {0} {1}".format(projectContext.ProjectName, projectContext.ProjectVersion) packageReadMeLinesNew = TryReplaceSection(config, packageReadMeLines, "AG_PROJECT_CAPTION", [projectCaption], readmePath) if packageReadMeLinesNew is not None: packageReadMeLines = packageReadMeLinesNew packageReadMeLinesNew = TryReplaceSection(config, packageReadMeLines, "AG_DEMOAPPS", result, readmePath) if packageReadMeLinesNew is not None: packageReadMeLines = packageReadMeLinesNew packageReadMeLinesNew = TryInsertTableOfContents(config, packageReadMeLines, localToolConfig.ToCDepth, readmePath) if packageReadMeLinesNew is not None: packageReadMeLines = packageReadMeLinesNew SaveReadMe(config, readmePath, packageReadMeLines) elif config.Verbosity > 2: config.LogPrintWarning("No README.md found in {0}".format(rootDir.ResolvedPath))
def DoGenerateBuildFilesNoAll(config: Config, errorHelpManager: ErrorHelpManager, files: List[str], platformGeneratorPlugin: GeneratorPlugin, packageFilters: PackageFilters) -> List[Package]: config.LogPrint("- Generating build files") isSDKBuild = len(files) <= 0 packageLoader = PackageLoader(config, files, platformGeneratorPlugin) return __ResolveAndGenerate(config, errorHelpManager, platformGeneratorPlugin, packageLoader, packageFilters, isSDKBuild, False)
def ForceCheckBuildTools(configToolCheck: Config, generatorContext: GeneratorContext, toolPackageNames: List[str]) -> PackageRecipeResultManager: configToolCheck.LogPrint("BuildTools check"); plugin = generatorContext.Platform filePathList = [] # type: List[str] packageFilters = PackageFilters() packages = MainFlow.DoGetPackages(generatorContext, configToolCheck, filePathList, packageFilters, forceImportPackageNames=toolPackageNames) packageRecipeResultManager = PackageRecipeResultManager(configToolCheck); builderConfig = BuilderConfig() builderConfig.Settings.CheckBuildCommands = True RecipeBuilder.BuildPackages(configToolCheck, generatorContext, builderConfig, packages, packageRecipeResultManager) return packageRecipeResultManager
def DoGenerateBuildFilesNoAll(config: Config, files: List[str], platformGeneratorPlugin: GeneratorPlugin, packageFilters: PackageFilters) -> List[Package]: config.LogPrint("- Generating build files") if platformGeneratorPlugin.Id == PluginSharedValues.PLATFORM_ID_ALL: raise Exception("Can not use PLATFORM_ID_ALL") isSDKBuild = len(files) <= 0 packageLoader = PackageLoader(config, files, platformGeneratorPlugin) return __ResolveAndGenerate(config, platformGeneratorPlugin, packageLoader, packageFilters, isSDKBuild)
def __init__(self, config: Config, packageBuildPath: str, contentBuildPath: str, contentOutputPath: str, features: Features, toolFinder: ToolFinder) -> None: super(Builder, self).__init__() configPathVariables = PathVariables(config, packageBuildPath, contentBuildPath, contentOutputPath) commandFilename = IOUtil.Join(contentBuildPath, "Content.json") commandFile = ContentBuildCommandFile(config, commandFilename, configPathVariables) # We don't include the files at 'Content' (contentOutputPath) sourceContent = SourceContent(config, contentOutputPath, contentBuildPath, commandFile, False, commandFilename) contentProcessors = [] # type: List[BasicContentProcessor] # contentProcessors = [VulkanContentProcessor()] contentProcessors += self.__AddBasicContentProcessors( config, toolFinder, config.ToolConfig.ContentBuilderConfiguration) contentProcessors = self.__FilterProcessorsBasedOnFeatures( contentProcessors, features) absoluteCacheFileName = IOUtil.Join(packageBuildPath, "_ContentBuildCache.fsl") absoluteOutputCacheFileName = IOUtil.Join( packageBuildPath, "_ContentBuildCacheOutput.fsl") srcsSyncState = BuildState.GenerateSyncState( config, absoluteCacheFileName, sourceContent.AllContentSource, True) outputSyncState = BuildState.GenerateOutputSyncState( config, absoluteOutputCacheFileName, contentOutputPath, True) if sourceContent.IsEmpty: config.LogPrint("No files found") return if not config.DisableWrite: IOUtil.SafeMakeDirs(contentOutputPath) self.__ProcessSyncFiles(config, contentBuildPath, contentOutputPath, sourceContent.ContentSource, srcsSyncState, outputSyncState) self.__ProcessContentFiles(config, contentBuildPath, contentOutputPath, toolFinder, contentProcessors, sourceContent.ContentBuildSource, srcsSyncState, outputSyncState) srcsSyncState.Save() outputSyncState.Save()
def DoGenerateBuildFiles3(config: Config, files: List[str], platformGeneratorPlugin: GeneratorPlugin, packageFilters: PackageFilters) -> MultiPlatformPackageResultType: config.LogPrint("- Generating build files") isSDKBuild = len(files) <= 0 packageLoader = PackageLoader(config, files, platformGeneratorPlugin) if platformGeneratorPlugin.Id != PluginSharedValues.PLATFORM_ID_ALL: raise Exception("This requires: PLATFORM_ID_ALL") resDict = {} # type: MultiPlatformPackageResultType for entry in PluginConfig.GetGeneratorPlugins(config.AllowDevelopmentPlugins): if not config.IsTestMode or not entry.InDevelopment: packages = __ResolveAndGenerate(config, entry, copy.deepcopy(packageLoader), packageFilters, isSDKBuild) resDict[entry.Name] = (packages, entry) return resDict
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) if localToolConfig.DryRun: config.ForceDisableAllWrite() if localToolConfig.IgnoreNotSupported: config.IgnoreNotSupported = True # Get the platform and see if its supported platformGeneratorPlugin = PluginConfig.GetGeneratorPluginById(localToolConfig.PlatformName, localToolConfig.Generator, False, config.ToolConfig.CMakeConfiguration, localToolConfig.GetUserCMakeConfig()) PlatformUtil.CheckBuildPlatform(platformGeneratorPlugin.PlatformName) config.LogPrint("Active platform: {0}".format(platformGeneratorPlugin.PlatformName)) theFiles = MainFlow.DoGetFiles(config, toolConfig.GetMinimalConfig(), currentDirPath, localToolConfig.Recursive) generatorContext = GeneratorContext(config, localToolConfig.BuildPackageFilters.RecipeFilterManager, config.ToolConfig.Experimental, platformGeneratorPlugin) PluginConfig.SetLegacyGeneratorType(localToolConfig.GenType) packageFilters = localToolConfig.BuildPackageFilters packages = MainFlow.DoGenerateBuildFilesNoAll(config, theFiles, platformGeneratorPlugin, packageFilters) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) requestedFiles = None if config.IsSDKBuild else theFiles # We need the generator to be able to examine its support if localToolConfig.ListFeatures or localToolConfig.ListVariants or localToolConfig.ListExtensions or localToolConfig.ListRequirements: if localToolConfig.ListFeatures: Builder.ShowFeatureList(self.Log, config, topLevelPackage, requestedFiles) if localToolConfig.ListVariants: Builder.ShowVariantList(self.Log, topLevelPackage, requestedFiles, platformGeneratorPlugin) if localToolConfig.ListExtensions: Builder.ShowExtensionList(self.Log, topLevelPackage, requestedFiles) if localToolConfig.ListRequirements: Builder.ShowRequirementList(self.Log, config, topLevelPackage, requestedFiles) else: if localToolConfig.BuildPackageFilters is None or localToolConfig.BuildPackageFilters.ExtensionNameList is None: raise Exception("localToolConfig.BuildPackageFilters.ExtensionNameList not set") Builder.BuildPackages(generatorContext, config, packages, localToolConfig.BuildVariantsDict, localToolConfig.RemainingArgs, localToolConfig.ForAllExe, platformGeneratorPlugin, localToolConfig.EnableContentBuilder, localToolConfig.ForceClaimInstallArea, localToolConfig.BuildThreads, localToolConfig.Command)
def GenerateGUID(config: Config, packages: List[Package], guid: str) -> str: if guid != g_defaultVCID: return guid used = set() for package in packages: winPlatform = package.GetPlatform(PlatformNameString.WINDOWS) if winPlatform: used.add(winPlatform.ProjectId) count = 0 newGuid = ("%s" % (uuid.uuid4())).upper() while newGuid in used: if count > 100000: config.LogPrint("Failed to generate unique GUID in allocated time using default, please add a unique GUID manually") return guid newGuid = ("%s" % (uuid.uuid4())).upper() count = count + 1 return newGuid
def __init__(self, config: Config, packageBuildPath: str, contentBuildPath: str, contentOutputPath: str, contentProcessorManager: ContentProcessorManager) -> None: super().__init__() configPathVariables = PathVariables(config, packageBuildPath, contentBuildPath, contentOutputPath) commandFilename = IOUtil.Join(contentBuildPath, ToolSharedValues.CONTENT_BUILD_FILE_NAME) commandFile = ContentBuildCommandFile(config, commandFilename, configPathVariables) # We don't include the files at "Content" (contentOutputPath) sourceContent = SourceContent(config, contentOutputPath, contentBuildPath, commandFile, False, commandFilename) absoluteCacheFileName = IOUtil.Join(packageBuildPath, "_ContentBuildCache.fsl") absoluteOutputCacheFileName = IOUtil.Join( packageBuildPath, "_ContentBuildCacheOutput.fsl") srcsSyncState = BuildState.GenerateSyncState( config, absoluteCacheFileName, sourceContent.AllContentSource, True) outputSyncState = BuildState.GenerateOutputSyncState( config, absoluteOutputCacheFileName, contentOutputPath, True) if sourceContent.IsEmpty: config.LogPrint("No files found") return if not config.DisableWrite: IOUtil.SafeMakeDirs(contentOutputPath) self.__ProcessSyncFiles(config, contentBuildPath, contentOutputPath, sourceContent.ContentSource, srcsSyncState, outputSyncState) self.__ProcessContentFiles(config, contentBuildPath, contentOutputPath, contentProcessorManager, sourceContent.ContentBuildSource, srcsSyncState, outputSyncState) srcsSyncState.Save() outputSyncState.Save()
def __LoadFiles( self, config: Config, files: List[PackageFile], rPackageDict: Dict[str, List[XmlGenFile]], rGenFiles: List[XmlGenFile], defaultPackageLanguage: int, factoryFunction: Callable[[Config, int], XmlGenFile]) -> None: for file in files: config.LogPrint("'{0}'".format(file.AbsoluteFilePath)) xml = factoryFunction(config, defaultPackageLanguage) xml.Load(config, self.PackageTemplateLoader, file) self.__ValidatePackage(config, file, xml) rGenFiles.insert(0, xml) if not xml.Name in rPackageDict: rPackageDict[xml.Name] = [xml] else: rPackageDict[xml.Name].append(xml) for packageList in list(rPackageDict.values()): if len(packageList) > 1: raise PackageHasMultipleDefinitions2Exception(packageList)
def DoGenerateBuildFilesNow( pluginConfigContext: PluginConfigContext, config: Config, errorHelpManager: ErrorHelpManager, files: List[str], platformGeneratorPlugin: GeneratorPlugin, packageFilters: PackageFilters ) -> Optional[Tuple[List[Package], GeneratorPlugin]]: config.LogPrint("- Generating build files") isSDKBuild = len(files) <= 0 packageLoader = PackageLoader(config, files, platformGeneratorPlugin) res = None # type: Optional[Tuple[List[Package], GeneratorPlugin]] for entry in pluginConfigContext.GetGeneratorPlugins(): if entry.PlatformName.lower( ) == platformGeneratorPlugin.OriginalPlatformId and ( not entry.InDevelopment): packages = __ResolveAndGenerate(config, errorHelpManager, entry, copy.deepcopy(packageLoader), packageFilters, isSDKBuild, False) res = (packages, entry) return res
def BuildPackages(generatorContext: GeneratorContext, config: Config, packages: List[Package], variantSettingsDict: Dict[str, str], buildArgs: List[str], buildForAllExe: Optional[str], generator: GeneratorPluginBase2, enableContentBuilder: bool, forceClaimInstallArea: bool, buildThreads: int, buildCommand: CommandType, printPathIfCMake: bool = False) -> None: PlatformUtil.CheckBuildPlatform(generatorContext.PlatformName) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) BuildVariantUtil.ValidateUserVariantSettings(config, topLevelPackage, variantSettingsDict) BuildVariantUtil.LogVariantSettings(config, variantSettingsDict) buildConfig = BuildConfigRecord(config.ToolConfig.ToolVersion, generatorContext.PlatformName, variantSettingsDict, buildCommand, buildArgs, buildForAllExe, generator, buildThreads) builder = Builder(generatorContext, config, topLevelPackage, buildConfig, enableContentBuilder, forceClaimInstallArea) # Print executable paths if enabled and its a cmake type build if printPathIfCMake and generatorContext.Generator.IsCMake and buildCommand == CommandType.Build and topLevelPackage is not None: for depPackage in topLevelPackage.ResolvedAllDependencies: package = depPackage.Package if package.Type == PackageType.Executable and builder.UsedBuildContext is not None and builder.UsedGeneratorConfig is not None: if not package.ResolvedPlatformNotSupported: runCommand = builder.TryGenerateRunCommandForExecutable( builder.UsedBuildContext, package, buildConfig, ["(EXE)"], builder.UsedGeneratorConfig) if runCommand is not None: config.DoPrint("Executable at: '{0}'".format( runCommand[0])) else: config.LogPrint( "Package '{0}' was not supported on this platform". format(package.Name))
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: # Check if a environment variable has been set to disable this tool # This is for example done by FslBuild to prevent multiple executions of content building. toolEnabled = IOUtil.TryGetEnvironmentVariable( CONFIG_FSLBUILDCONTENT_ENABLED) featureList = localToolConfig.BuildPackageFilters.FeatureNameList config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) # Get the platform and see if its supported platform = PluginConfig.GetGeneratorPluginById( localToolConfig.PlatformName, False) PlatformUtil.CheckBuildPlatform(platform.Name) generatorContext = GeneratorContext(config, config.ToolConfig.Experimental, platform) config.LogPrint("Active platform: {0}".format(platform.Name)) discoverFeatureList = '*' in featureList topLevelPackage = None if discoverFeatureList or localToolConfig.Project is None: if discoverFeatureList: config.LogPrint( "No features specified, so using package to determine them" ) topLevelPackage = self.__ResolveAndGetTopLevelPackage( generatorContext, config, currentDirPath, toolConfig.GetMinimalConfig(), localToolConfig.Recursive) if discoverFeatureList: featureList = [ entry.Name for entry in topLevelPackage.ResolvedAllUsedFeatures ] #if localToolConfig.Project is None: # executeablePackage = PackageListUtil.FindFirstExecutablePackage(packages) # localToolConfig.Project = executeablePackage.ShortName if localToolConfig.Validate: Validate.ValidatePlatform(config, localToolConfig.PlatformName, featureList) if topLevelPackage is None: topLevelPackage = self.__ResolveAndGetTopLevelPackage( generatorContext, config, currentDirPath, toolConfig.GetMinimalConfig(), localToolConfig.Recursive) RecipeBuilder.ValidateInstallationForPackages( config, generatorContext, topLevelPackage.ResolvedBuildOrder) if toolEnabled is not None and not ParseUtil.ParseBool(toolEnabled): if self.Log.Verbosity > 0: print( "FslBuildContent has been disabled by environment variable %s set to %s" % (CONFIG_FSLBUILDCONTENT_ENABLED, toolEnabled)) return ContentBuilder.Build(config, currentDirPath, featureList)
def __init__(self, config: Config, files: List[str], platform: GeneratorPluginBase, forceImportPackageNames: Optional[List[str]] = None) -> None: super(PackageLoader, self).__init__() self.BasicConfig = config genFilename = config.GenFileName # type: str packageConfigDict = config.ToolConfig.PackageConfiguration # type: Dict[str, ToolConfigPackageConfiguration] packageLocations = [] if not config.Type in packageConfigDict else packageConfigDict[ config.Type].Locations # type: List[ToolConfigPackageLocation] factoryFunction = _CreateXmlGenFile templateLocationCache = self.__CacheTemplateLocations(config) self.PackageTemplateLoader = PackageTemplateLoader( config, templateLocationCache) self.PackageFinder = PackageFinder(config, platform, config.Type, packageConfigDict, genFilename, config.IsTestMode) inputFiles = self.PackageFinder.LocateInputFiles( files) # type: List[PackageFile] config.LogPrint("- Parsing") try: config.PushIndent() # Preload all known package files from the cache if the package configuration requested it. if config.Type in packageConfigDict and packageConfigDict[ config.Type].Preload: inputFiles = self.PackageFinder.GetKnownPackageFiles( inputFiles) internalNinjaToolPackageName = "Recipe.BuildTool.ninja" if platform.Name == PlatformNameString.ANDROID and not self.__ContainsPackage( inputFiles, internalNinjaToolPackageName): packageFile = self.PackageFinder.TryLocateMissingPackagesByName( internalNinjaToolPackageName) if packageFile is None: raise ToolDependencyNotFoundException( internalNinjaToolPackageName) if packageFile not in inputFiles: # prevent file duplicatin (FIX: this is a workaround due to 'initial' packages not being in the lookup cache) if not self.__ContainsName(inputFiles, internalNinjaToolPackageName): inputFiles.append(packageFile) #files.append(packageFile.AbsoluteFilePath) if forceImportPackageNames is not None: for packageName in forceImportPackageNames: packageFile = self.PackageFinder.TryLocateMissingPackagesByName( packageName) if packageFile is None: raise ToolDependencyNotFoundException(packageName) if packageFile not in inputFiles: # prevent file duplicatin (FIX: this is a workaround due to 'initial' packages not being in the lookup cache) if not self.__ContainsName(inputFiles, packageName): inputFiles.append(packageFile) #files.append(packageFile.AbsoluteFilePath) # sort the input files to ensure a predictable 'initial' order inputFiles.sort(key=lambda s: s.AbsoluteDirPath.lower()) packageDict = {} # type: Dict[str, List[XmlGenFile]] genFiles = [] # type: List[XmlGenFile] # Load the initial package files self.__LoadFiles(config, inputFiles, packageDict, genFiles, config.ToolConfig.DefaultPackageLanguage, factoryFunction) searchForPackages = True newGenFiles = genFiles while searchForPackages: missingPackages = self.__DiscoverMissingPackages( config, platform, packageDict, newGenFiles) if len(missingPackages) > 0: newFiles = self.PackageFinder.LocateMissingPackages( missingPackages) newGenFiles = [] self.__LoadFiles(config, newFiles, packageDict, newGenFiles, config.ToolConfig.DefaultPackageLanguage, factoryFunction) genFiles += newGenFiles else: searchForPackages = False self.FoundInputFiles = inputFiles self.SourceFiles = files self.GenFiles = genFiles finally: config.PopIndent()
def __init__(self, generatorContext: GeneratorContext, config: Config, topLevelPackage: Package, buildConfig: BuildConfigRecord, enableContentBuilder: bool, forceClaimInstallArea: bool) -> None: super(Builder, self).__init__() self.Log = config localPlatformBuildContext = LocalPlatformBuildContext( config, generatorContext.Generator.OriginalName, buildConfig.BuildCommand, buildConfig.BuildThreads) # Do a final filter that removes all unsupported packages resolvedBuildOrder = topLevelPackage.ResolvedBuildOrder resolvedBuildOrder = PackageFilter.FilterNotSupported( self.Log, topLevelPackage, resolvedBuildOrder) if not PackageFilter.WasThisAExecutableBuildAndAreThereAnyLeft( topLevelPackage.ResolvedBuildOrder, resolvedBuildOrder): self.Log.DoPrint("No executables left, skipping all") return # Run the recipe builder on the packages we have left # We run the recipe builder on the resolvedBuildOrder since it all required packages, not just the ones we need to build as libs and executables builderSettings = BuilderSettings() builderSettings.ForceClaimInstallArea = forceClaimInstallArea builderSettings.BuildThreads = buildConfig.BuildThreads RecipeBuilder.BuildPackagesInOrder(config, generatorContext, resolvedBuildOrder, builderSettings) resolvedBuildOrderBuildable = PackageFilter.FilterBuildablePackages( resolvedBuildOrder) if len(resolvedBuildOrderBuildable) == 0: config.DoPrint("Nothing to build!") return generatorConfig = GeneratorConfig(config.SDKConfigTemplatePath, config.ToolConfig) generatorReportDict = generatorContext.Generator.GenerateReport( self.Log, generatorConfig, resolvedBuildOrderBuildable) packageCount = len(resolvedBuildOrderBuildable) resolvedBuildOrderBuildable = self.__ApplyPlatformOrderChanges( resolvedBuildOrderBuildable, buildConfig.PlatformName) originalBuildArgs = buildConfig.BuildArgs # Default content building for all platform (for those generators that don't add it to the build file) if enableContentBuilder: for package in resolvedBuildOrderBuildable: if package.Type == PackageType.Executable: featureList = [ entry.Name for entry in package.ResolvedAllUsedFeatures ] if package.AbsolutePath is None: raise Exception("Invalid package") ContentBuilder.Build(config, package.AbsolutePath, featureList) # Windows runs its validation checks slightly differently runValidationChecks = (buildConfig.PlatformName != PlatformNameString.WINDOWS) buildContext = LocalBuildContext(config, localPlatformBuildContext, generatorReportDict, generatorContext.GeneratorName) for package in resolvedBuildOrderBuildable: config.LogPrint("Building package: {0}".format(package.Name)) config.LogPrint("Package location: {0}".format( package.AbsolutePath)) if not config.IsDryRun: buildEnv = os.environ.copy() # type: Dict[str, str] buildEnv[CONFIG_FSLBUILDCONTENT_ENABLED] = "false" BuildVariantUtil.ExtendEnvironmentDictWithVariants( config, buildEnv, package, buildConfig.VariantSettingsDict) buildConfig.BuildArgs = list(originalBuildArgs) if config.Verbosity > 4: config.DoPrint("Package build arguments1: {0}".format( buildConfig.BuildArgs)) config.DoPrint("General build arguments2: {0}".format( originalBuildArgs)) strRunCommands = buildConfig.RunCommand runCommands = None # type: Optional[List[str]] if strRunCommands is not None: userRunCommands = shlex.split(strRunCommands) runCommands = self.__TryGenerateRunCommandForExecutable( buildContext, package, buildConfig.VariantSettingsDict, userRunCommands) if runValidationChecks: featureList = [ entry.Name for entry in package.ResolvedAllUsedFeatures ] Validate.ValidatePlatform(config, buildConfig.PlatformName, featureList, 4) self.__BuildPackage(buildContext, package, buildConfig, buildEnv, runCommands) if packageCount > 0: config.LogPrint("Build {0} packages".format(packageCount)) else: config.DoPrint("Nothing build!")
def __ToolMainEx(self, currentDir: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig, templateDict: Dict[str, List[XmlNewTemplateFile]], performSanityCheck: bool = False) -> None: config = Config(self.Log, toolConfig, 'sdk', localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) #config.ForceDisableAllWrite() config.PrintTitle() packageFilters = localToolConfig.BuildPackageFilters reservedProjectNames = set() # type: Set[str] packages = None # type: Optional[List[Package]] if not localToolConfig.NoParse: # Get the generator and see if its supported on this platform buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig( localToolConfig.BuildVariantsDict) generator = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById( localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, config.ToolConfig.DefaultPackageLanguage, config.ToolConfig.CMakeConfiguration, localToolConfig.GetUserCMakeConfig(), False) PlatformUtil.CheckBuildPlatform(generator.PlatformName) config.LogPrint("Active platform: {0}".format( generator.PlatformName)) generatorContext = GeneratorContext( config, self.ErrorHelpManager, packageFilters.RecipeFilterManager, config.ToolConfig.Experimental, generator) packages = ParsePackages( generatorContext, config, toolConfig.GetMinimalConfig(generator.CMakeConfig), currentDir, packageFilters) # Reserve the name of all packages if not packages is None: for package in packages: reservedProjectNames.add(package.Name) currentDir, projectName = DetermineDirAndProjectName( currentDir, localToolConfig.ProjectName) localConfig = LocalConfig(config, currentDir, projectName, localToolConfig.Template, localToolConfig.Force, templateDict, reservedProjectNames, localToolConfig.Language) configVariant = localConfig.ConfigVariant if not localToolConfig.AllowOverwrite: if os.path.isdir(configVariant.ProjectPath): raise EnvironmentError( "The project directory already exist: '{0}', you can use '{1}' to overwrite it." .format(configVariant.ProjectPath, g_allowOverwriteOption)) elif os.path.exists(configVariant.ProjectPath): raise EnvironmentError( "A file named '{0}' already exist, you can use '{1}' to overwrite it." .format(configVariant.ProjectPath, g_allowOverwriteOption)) visualStudioGUID = localToolConfig.VisualStudioGUID if packages: visualStudioGUID = GeneratorVCUtil.GenerateGUID( config, packages, visualStudioGUID) GenerateProject(config, localConfig, configVariant, visualStudioGUID, localToolConfig.GenFileOnly) if not localToolConfig.NoBuildGen: config.DoPrint("Generating build files") projectConfig = Config(self.Log, toolConfig, PluginSharedValues.TYPE_DEFAULT, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) theFiles = MainFlow.DoGetFiles( projectConfig, toolConfig.GetMinimalConfig(generator.CMakeConfig), configVariant.ProjectPath) buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig( localToolConfig.BuildVariantsDict) platformGeneratorPlugin = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById( localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, config.ToolConfig.DefaultPackageLanguage, config.ToolConfig.CMakeConfiguration, localToolConfig.GetUserCMakeConfig(), False) MainFlow.DoGenerateBuildFiles( self.ToolAppContext.PluginConfigContext, projectConfig, self.ErrorHelpManager, theFiles, platformGeneratorPlugin, packageFilters) if performSanityCheck: self.__PerformSanityCheck(config, currentDir, localConfig.ProjectName, localConfig.Template)
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: #self.Log.LogPrintVerbose(2, "*** Forcing the legacy clang tidy mode ***") #localToolConfig.Legacy = True config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) # create a config we control and that can be used to just build the tool recipe's configToolCheck = Config(self.Log, toolConfig, PluginSharedValues.TYPE_DEFAULT, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) if localToolConfig.DryRun: config.ForceDisableAllWrite() configToolCheck.ForceDisableAllWrite() self.__CheckUserArgs(localToolConfig.ClangFormatArgs, "formatArgs") self.__CheckUserArgs(localToolConfig.ClangTidyArgs, "tidyArgs") self.__CheckUserArgs(localToolConfig.ClangTidyPostfixArgs, "tidyPostfixArgs") applyClangFormat = toolConfig.ClangFormatConfiguration is not None and localToolConfig.ClangFormat applyClangTidy = toolConfig.ClangTidyConfiguration is not None and localToolConfig.ClangTidy if localToolConfig.IgnoreNotSupported or ( (localToolConfig.ScanSource or applyClangFormat) and not applyClangTidy): config.IgnoreNotSupported = True configToolCheck.IgnoreNotSupported = True packageFilters = localToolConfig.BuildPackageFilters # Get the platform and see if its supported buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig( localToolConfig.BuildVariantsDict) if localToolConfig.Legacy and applyClangTidy and config.ToolConfig.CMakeConfiguration is not None: # For the LEGACY clangTidy implementation we disable allow find package for the build checks for now as we dont use cmake for those # We basically have to update the tidy pass to utilize ninja+cmake for the tidy pass so that find_package will work self.Log.LogPrintVerbose(2, "Force disabling 'AllowFindPackage'") config.ToolConfig.CMakeConfiguration.SetAllowFindPackage(False) cmakeUserConfig = localToolConfig.GetUserCMakeConfig() if not localToolConfig.Legacy and applyClangTidy: config.LogPrintVerbose( 2, "Forcing the ninja generator for clang tidy") cmakeUserConfig.GeneratorName = "Ninja" generator = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById( localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, config.ToolConfig.DefaultPackageLanguage, config.ToolConfig.CMakeConfiguration, cmakeUserConfig, True) PlatformUtil.CheckBuildPlatform(generator.PlatformName) generatorContext = GeneratorContext(config, self.ErrorHelpManager, packageFilters.RecipeFilterManager, config.ToolConfig.Experimental, generator) self.Log.LogPrint("Active platform: {0}".format( generator.PlatformName)) packageRecipeResultManager = None # type: Optional[PackageRecipeResultManager] toolPackageNamesSet = set() toolPackageNames = [] if applyClangFormat or applyClangTidy: if applyClangFormat: if toolConfig.ClangFormatConfiguration is None: raise Exception("internal error") toolPackageNamesSet.add( toolConfig.ClangFormatConfiguration.RecipePackageName) toolPackageNamesSet.add( toolConfig.ClangFormatConfiguration.NinjaRecipePackageName) if applyClangTidy: if toolConfig.ClangTidyConfiguration is None: raise Exception("internal error") toolPackageNamesSet.add( toolConfig.ClangTidyConfiguration.ClangRecipePackageName) toolPackageNamesSet.add(toolConfig.ClangTidyConfiguration. ClangTidyRecipePackageName) toolPackageNamesSet.add( toolConfig.ClangTidyConfiguration.NinjaRecipePackageName) toolPackageNames = list(toolPackageNamesSet) packageRecipeResultManager = ForceCheckBuildTools( configToolCheck, generatorContext, toolPackageNames) searchDir = currentDirPath if localToolConfig.File is not None: localToolConfig.File = IOUtil.NormalizePath(localToolConfig.File) if IOUtil.IsAbsolutePath(localToolConfig.File): searchDir = IOUtil.GetDirectoryName(localToolConfig.File) closestGenFilePath = FileFinder.TryFindClosestFileInRoot( config, toolConfig, searchDir, config.GenFileName) if closestGenFilePath is None: closestGenFilePath = searchDir if self.Log.Verbosity >= 4: self.Log.LogPrint("Closest '{0}' file path: '{1}'".format( toolConfig.GenFileName, closestGenFilePath)) packageProcess = None # type: Optional[MainFlow.PackageLoadAndResolveProcess] packages = None discoverFeatureList = '*' in packageFilters.FeatureNameList if discoverFeatureList or localToolConfig.Project is None or localToolConfig.ScanSource or applyClangFormat or applyClangTidy: if discoverFeatureList: config.LogPrint( "No features specified, so using package to determine them" ) if localToolConfig.ScanSource or applyClangFormat or applyClangTidy or discoverFeatureList: packageProcess = self.__CreatePackageProcess( config, toolConfig.GetMinimalConfig(generator.CMakeConfig), closestGenFilePath, localToolConfig.Recursive, generatorContext.Platform, toolPackageNames) packageProcess.Resolve(generatorContext, packageFilters, applyClangTidy, False) packages = packageProcess.Packages topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) if discoverFeatureList: packageFilters.FeatureNameList = [ entry.Name for entry in topLevelPackage.ResolvedAllUsedFeatures ] customPackageFileFilter = None # type: Optional[CustomPackageFileFilter] if not localToolConfig.ScanSource and not applyClangFormat and not applyClangTidy: Validate.ValidatePlatform(config, localToolConfig.PlatformName, packageFilters.FeatureNameList) if packageProcess is None: packageProcess = self.__CreatePackageProcess( config, toolConfig.GetMinimalConfig(generator.CMakeConfig), closestGenFilePath, localToolConfig.Recursive, generatorContext.Platform, toolPackageNames) if not packageProcess.IsFullResolve or packages is None: # For now this requires a full resolve (but basically it only requires basic + files) packages = packageProcess.Resolve(generatorContext, packageFilters, applyClangTidy, True) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) RecipeBuilder.ValidateInstallationForPackages( config, config.SDKPath, generatorContext, topLevelPackage.ResolvedBuildOrder) else: if localToolConfig.File is not None: # Delay extension validation customPackageFileFilter = CustomPackageFileFilter( localToolConfig.File) theTopLevelPackage = None # type: Optional[Package] filteredPackageList = [] # type: List[Package] if applyClangTidy or applyClangFormat or localToolConfig.ScanSource: addExternals = applyClangTidy filteredPackageList, theTopLevelPackage = self.__PreparePackages( self.Log, localToolConfig, packageProcess, generatorContext, packageFilters, addExternals, packages, config.IsSDKBuild, applyClangTidy, config) if len(filteredPackageList) <= 0: self.Log.DoPrint("No supported packages left to process") return if applyClangTidy: self.__ApplyClangTidy(self.Log, toolConfig, localToolConfig, packageRecipeResultManager, theTopLevelPackage, filteredPackageList, generator, config, generatorContext, customPackageFileFilter) if applyClangFormat: self.__ApplyClangFormat(self.Log, toolConfig, localToolConfig, packageRecipeResultManager, filteredPackageList, customPackageFileFilter, generatorContext.CMakeConfig) # Scan source after 'format' to ensure we dont warn about stuff that has been fixed if localToolConfig.ScanSource: self.__ApplyScanSource(self.Log, localToolConfig, config.IsSDKBuild, config.DisableWrite, filteredPackageList, customPackageFileFilter)
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) # create a config we control and that can be used to just build the tool recipe's configToolCheck = Config(self.Log, toolConfig, PluginSharedValues.TYPE_DEFAULT, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) if localToolConfig.DryRun: config.ForceDisableAllWrite() configToolCheck.ForceDisableAllWrite() self.__CheckUserArgs(localToolConfig.ClangFormatArgs, "formatArgs") self.__CheckUserArgs(localToolConfig.ClangTidyArgs, "tidyArgs") self.__CheckUserArgs(localToolConfig.ClangTidyPostfixArgs, "tidyPostfixArgs") applyClangFormat = toolConfig.ClangFormatConfiguration is not None and localToolConfig.ClangFormat applyClangTidy = toolConfig.ClangTidyConfiguration is not None and localToolConfig.ClangTidy if localToolConfig.IgnoreNotSupported or ( (localToolConfig.ScanSource or applyClangFormat) and not applyClangTidy): config.IgnoreNotSupported = True configToolCheck.IgnoreNotSupported = True packageFilters = localToolConfig.BuildPackageFilters # Get the platform and see if its supported platform = PluginConfig.GetGeneratorPluginById( localToolConfig.PlatformName, False) PlatformUtil.CheckBuildPlatform(platform.Name) generatorContext = GeneratorContext(config, config.ToolConfig.Experimental, platform) config.LogPrint("Active platform: {0}".format(platform.Name)) packageRecipeResultManager = None # type: Optional[PackageRecipeResultManager] toolPackageNames = [] if applyClangFormat or applyClangTidy: if applyClangFormat: if toolConfig.ClangFormatConfiguration is None: raise Exception("internal error") toolPackageNames.append( toolConfig.ClangFormatConfiguration.RecipePackageName) if applyClangTidy: if toolConfig.ClangTidyConfiguration is None: raise Exception("internal error") toolPackageNames.append( toolConfig.ClangTidyConfiguration.RecipePackageName) packageRecipeResultManager = ForceCheckBuildTools( configToolCheck, generatorContext, toolPackageNames) searchDir = currentDirPath if localToolConfig.File is not None and IOUtil.IsAbsolutePath( localToolConfig.File): searchDir = IOUtil.GetDirectoryName(localToolConfig.File) closestGenFilePath = FileFinder.TryFindClosestFileInRoot( config, toolConfig, searchDir, config.GenFileName) if closestGenFilePath is None: closestGenFilePath = searchDir if (self.Log.Verbosity >= 4): self.Log.LogPrint("Closest '{0}' file path: '{1}'".format( toolConfig.GenFileName, closestGenFilePath)) packageProcess = None # type: Optional[MainFlow.PackageLoadAndResolveProcess] packages = None discoverFeatureList = '*' in packageFilters.FeatureNameList if discoverFeatureList or localToolConfig.Project is None or localToolConfig.ScanSource or applyClangFormat or applyClangTidy: if discoverFeatureList: config.LogPrint( "No features specified, so using package to determine them" ) if localToolConfig.ScanSource or applyClangFormat or applyClangTidy or discoverFeatureList: packageProcess = self.__CreatePackageProcess( config, toolConfig.GetMinimalConfig(), closestGenFilePath, localToolConfig.Recursive, generatorContext.Platform, toolPackageNames) packageProcess.Resolve(generatorContext, packageFilters, applyClangTidy, False) packages = packageProcess.Packages topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) if discoverFeatureList: packageFilters.FeatureNameList = [ entry.Name for entry in topLevelPackage.ResolvedAllUsedFeatures ] customPackageFileFilter = None # type: Optional[CustomPackageFileFilter] if not localToolConfig.ScanSource and not applyClangFormat and not applyClangTidy: Validate.ValidatePlatform(config, localToolConfig.PlatformName, packageFilters.FeatureNameList) if packageProcess is None: packageProcess = self.__CreatePackageProcess( config, toolConfig.GetMinimalConfig(), closestGenFilePath, localToolConfig.Recursive, generatorContext.Platform, toolPackageNames) if not packageProcess.IsFullResolve or packages is None: # For now this requires a full resolve (but basically it only requires basic + files) packages = packageProcess.Resolve(generatorContext, packageFilters, applyClangTidy, True) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) RecipeBuilder.ValidateInstallationForPackages( config, generatorContext, topLevelPackage.ResolvedBuildOrder) else: if localToolConfig.File is not None: # Delay extension validation customPackageFileFilter = CustomPackageFileFilter( localToolConfig.File) theTopLevelPackage = None # type: Optional[Package] filteredPackageList = [] # type: List[Package] if applyClangTidy or applyClangFormat or localToolConfig.ScanSource: addExternals = applyClangTidy filteredPackageList, theTopLevelPackage = self.__PreparePackages( self.Log, localToolConfig, packageProcess, generatorContext, packageFilters, addExternals, packages, config.IsSDKBuild, applyClangTidy, config) if len(filteredPackageList) <= 0: self.Log.DoPrint("No supported packages left to process") return if applyClangTidy: self.__ApplyClangTidy(self.Log, toolConfig, localToolConfig, packageRecipeResultManager, theTopLevelPackage, filteredPackageList, platform, config, generatorContext, customPackageFileFilter) if applyClangFormat: self.__ApplyClangFormat(self.Log, toolConfig, localToolConfig, packageRecipeResultManager, filteredPackageList, customPackageFileFilter) # Scan source after 'format' to ensure we dont warn about stuff that has been fixed if localToolConfig.ScanSource: self.__ApplyScanSource(self.Log, localToolConfig, config.IsSDKBuild, config.DisableWrite, filteredPackageList, customPackageFileFilter)
def __init__(self, config: Config, files: List[str], generator: GeneratorPluginBase, forceImportPackageNames: Optional[List[str]] = None) -> None: super().__init__() self.BasicConfig = config genFilename = config.GenFileName # type: str packageConfigDict = config.ToolConfig.PackageConfiguration # type: Dict[str, ToolConfigPackageConfiguration] packageLocations = [] if not config.Type in packageConfigDict else packageConfigDict[config.Type].Locations # type: List[ToolConfigPackageLocation] factoryFunction = _CreateXmlGenFile templateLocationCache = self.__CacheTemplateLocations(config) self.PackageTemplateLoader = PackageTemplateLoader(config, templateLocationCache) self.PackageFinder = PackageFinder(config, generator, config.Type, packageConfigDict, genFilename, config.IsTestMode) inputFiles = self.PackageFinder.LocateInputFiles(files) # type: List[PackageFile] config.LogPrint("- Parsing") try: config.PushIndent() # Preload all known package files from the cache if the package configuration requested it. if config.Type in packageConfigDict and packageConfigDict[config.Type].Preload: inputFiles = self.PackageFinder.GetKnownPackageFiles(inputFiles) if (generator.PlatformName == PlatformNameString.ANDROID or generator.PlatformId == PlatformNameString.ALL.lower()): internalNinjaToolPackageName = "Recipe.BuildTool.ninja" config.LogPrintVerbose(4, "Adding package {0}".format(internalNinjaToolPackageName)) self.__AddPackageToList(inputFiles, internalNinjaToolPackageName, _ThrowToolDependencyNotFoundException) #if generator.IsCMake: # internalCMakeToolPackageName = "Recipe.BuildTool.CMake" # config.LogPrintVerbose(4, "Adding package {0}".format(internalCMakeToolPackageName)) # self.__AddPackageToList(inputFiles, internalCMakeToolPackageName, _ThrowToolDependencyNotFoundException) if forceImportPackageNames is not None: for packageName in forceImportPackageNames: self.__AddPackageToList(inputFiles, packageName, _ThrowToolDependencyNotFoundException) # Ensure we load the project base package dependencies specified in the project.gen file inputFiles = self.__AddBasePackages(inputFiles, config.ToolConfig.ProjectInfo.Contexts) # sort the input files to ensure a predictable 'initial' order inputFiles.sort(key=lambda s: s.AbsoluteDirPath.lower()) packageDict = {} # type: Dict[str, List[XmlGenFile]] genFiles = [] # type: List[XmlGenFile] # Load the initial package files self.__LoadFiles(config, inputFiles, packageDict, genFiles, config.ToolConfig.DefaultPackageLanguage, factoryFunction) searchForPackages = True newGenFiles = genFiles while searchForPackages: missingPackages = self.__DiscoverMissingPackages(config, generator, packageDict, newGenFiles) if len(missingPackages) > 0: newFiles = self.PackageFinder.LocateMissingPackages(missingPackages) newGenFiles = [] self.__LoadFiles(config, newFiles, packageDict, newGenFiles, config.ToolConfig.DefaultPackageLanguage, factoryFunction) genFiles += newGenFiles else: searchForPackages = False self.FoundInputFiles = inputFiles self.SourceFiles = files self.GenFiles = genFiles finally: config.PopIndent()
def __init__(self, generatorContext: GeneratorContext, config: Config, topLevelPackage: Package, buildConfig: BuildConfigRecord, enableContentBuilder: bool, forceClaimInstallArea: bool) -> None: super().__init__() self.Log = config localPlatformBuildContext = LocalPlatformBuildContext( config, generatorContext.Generator.OriginalPlatformName, generatorContext.Generator.IsCMake, buildConfig.BuildThreads) # Do a final filter that removes all unsupported packages resolvedBuildOrder = topLevelPackage.ResolvedBuildOrder resolvedBuildOrder = PackageFilter.FilterNotSupported( self.Log, topLevelPackage, resolvedBuildOrder) if not PackageFilter.WasThisAExecutableBuildAndAreThereAnyLeft( topLevelPackage.ResolvedBuildOrder, resolvedBuildOrder): self.Log.DoPrint("No executables left, skipping all") return # Run the recipe builder on the packages we have left # We run the recipe builder on the resolvedBuildOrder since it all required packages, not just the ones we need to build as libs and executables builderSettings = BuilderSettings() builderSettings.ForceClaimInstallArea = forceClaimInstallArea builderSettings.BuildThreads = buildConfig.BuildThreads RecipeBuilder.BuildPackagesInOrder(config, generatorContext, resolvedBuildOrder, builderSettings) resolvedBuildOrderBuildable = PackageFilter.FilterBuildablePackages( resolvedBuildOrder) if len(resolvedBuildOrderBuildable) == 0: config.DoPrint("Nothing to build!") return generatorConfig = GeneratorConfig( generatorContext.PlatformName, config.SDKConfigTemplatePath, config.ToolConfig, localPlatformBuildContext.NumBuildThreads, buildConfig.BuildCommand) generatorConfigReport = generatorContext.Generator.TryGenerateConfigReport( self.Log, generatorConfig, topLevelPackage) packageCount = len(resolvedBuildOrderBuildable) resolvedBuildOrderBuildable = self.__ApplyPlatformOrderChanges( resolvedBuildOrderBuildable, buildConfig.PlatformName) originalBuildArgs = buildConfig.BuildArgs # Handle the configure step masterBuildReport = None # type: Optional[GeneratorBuildReport] masterBuildVariableReport = None # type: Optional[GeneratorVariableReport] if generatorConfigReport is not None: # Setup some extra variables for configure self.__AddCustomVariables(generatorConfigReport.VariableReport, config.ToolConfig.ProjectInfo) self.__ConfigureBuild(generatorConfigReport, buildConfig) masterBuildReport = generatorConfigReport.MasterBuildReport masterBuildVariableReport = generatorConfigReport.MasterBuildVariableReport if masterBuildVariableReport is not None: self.__AddCustomVariables(masterBuildVariableReport, config.ToolConfig.ProjectInfo) # Acquire information about the build step generatorReport = generatorContext.Generator.GenerateReport( self.Log, generatorConfig, resolvedBuildOrderBuildable) generatorReportDict = generatorReport.PackageReportDict for generatorEntry in generatorReportDict.values(): if generatorEntry.VariableReport is not None: self.__AddCustomVariables(generatorEntry.VariableReport, config.ToolConfig.ProjectInfo) # Default content building for all platform (for those generators that don't add it to the build file) builderCanBuildContent = (generatorConfigReport is not None and generatorConfigReport.CanBuildContent) if enableContentBuilder and not builderCanBuildContent: for package in resolvedBuildOrderBuildable: if package.Type == PackageType.Executable: featureList = [ entry.Name for entry in package.ResolvedAllUsedFeatures ] if package.Path is None: raise Exception("Invalid package") ContentBuilder.Build(config, package.Path, featureList) # Windows runs its validation checks slightly differently runValidationChecks = (buildConfig.PlatformName != PlatformNameString.WINDOWS) buildContext = LocalBuildContext(config, localPlatformBuildContext, generatorReportDict, generatorContext.GeneratorName) if masterBuildReport is not None: if masterBuildVariableReport is None: raise Exception("master-build must have a variable report") self.__BuildMaster(buildConfig, buildContext, masterBuildReport, masterBuildVariableReport, topLevelPackage, originalBuildArgs, builderCanBuildContent, runValidationChecks, config.IsDryRun) # Build and run all the packages in the resolvedBuildOrderBuildable self.__BuildAndRunPackages(config, buildConfig, buildContext, resolvedBuildOrderBuildable, originalBuildArgs, builderCanBuildContent, runValidationChecks, masterBuildReport is None, config.IsDryRun, generatorConfig) if packageCount > 0: config.LogPrint("Build {0} packages".format(packageCount)) else: config.DoPrint("Nothing build!") if generatorContext.Generator.IsCMake and buildConfig.BuildCommand == CommandType.Clean: self.Log.DoPrint( "*** To do a full cmake clean build delete the out of source build folder ***" ) if not generatorContext.Generator.SupportCommandClean and buildConfig.BuildCommand == CommandType.Clean: self.Log.DoPrint("*** clean not supported by this builder ***") if not generatorContext.Generator.SupportCommandInstall and buildConfig.BuildCommand == CommandType.Install: self.Log.DoPrint("*** install not supported by this builder ***")