def TryGetBuildExecutableInfo( log: Log, generatorConfig: GeneratorConfig, generatorName: str, cmakeConfig: GeneratorCMakeConfig, package: Package, generatorReport: PackageGeneratorReport, variantSettingsDict: Dict[str, str], configVariantOptions: List[str] ) -> Optional[PackageGeneratorBuildExecutableInfo]: if package.Type != PackageType.Executable: return None variableReport = generatorReport.VariableReport executableReport = generatorReport.ExecutableReport if executableReport is None: return None packageBuildPathFormat = GeneratorCMake._GetPackageBuildDir( generatorConfig, cmakeConfig, package) packageBuildPathFormat = IOUtil.Join( packageBuildPathFormat, ".fsl-build/config_${{{0}}}.json".format( LocalMagicBuildVariants.CMakeBuildConfig)) configurationFilePath = ReportVariableFormatter.Format( packageBuildPathFormat, variableReport, variantSettingsDict, executableReport.EnvironmentVariableResolveMethod) configurationFileDict = GeneratorCMake._TryLoadConfigJson( configurationFilePath) buildExePath = IOUtil.NormalizePath(configurationFileDict["EXE_PATH"]) return PackageGeneratorBuildExecutableInfo(buildExePath)
def AddFromBuildReport(rGitIgnoreDict: Dict[str, Set[str]], package: Package, executableReport: GeneratorExecutableReport, variableReport: GeneratorVariableReport) -> None: if executableReport is None or variableReport is None: return allKnownExeFiles = ReportVariableFormatter.GetAllKnownCombinations( executableReport.ExeFormatString, variableReport) for filename in allKnownExeFiles: SafeAddEntry(rGitIgnoreDict, package, filename)
def __RunPackage(self, package: AppInfoPackage, userArgs: List[str], buildVariantsDict: Dict[str, str]) -> None: if package.GeneratorReport is None or package.GeneratorReport.ExecutableReport is None or package.GeneratorReport.VariableReport is None: raise Exception( "Could not run {0}, as we dont have the required information". format(package.Name)) self.Log.LogPrint("Running {0}".format(package.Name)) executableReport = package.GeneratorReport.ExecutableReport variableReport = package.GeneratorReport.VariableReport runCommandList = [] packagePath = package.AbsolutePath exePath = ReportVariableFormatter.Format( executableReport.ExeFormatString, variableReport, buildVariantsDict, executableReport.EnvironmentVariableResolveMethod) if not executableReport.UseAsRelative: exePath = IOUtil.Join(packagePath, exePath) runCommandList.append(exePath) if executableReport.RunScript is not None: runScript = executableReport.RunScript if not executableReport.UseAsRelative: runScript = IOUtil.Join(packagePath, runScript) runCommandList.insert(0, runScript) currentWorkingDirectory = package.AbsolutePath runCommandList = runCommandList + userArgs try: result = subprocess.call(runCommandList, cwd=currentWorkingDirectory) if result != 0: self.Log.LogPrintWarning( "The run command '{0}' failed with '{1}'. It was run with CWD: '{2}'" .format(" ".join(runCommandList), result, currentWorkingDirectory)) sys.exit(result) except FileNotFoundError: self.Log.LogPrintWarning( "The run command '{0}' failed with 'file not found'. It was run with CWD: '{1}'" .format(" ".join(runCommandList), currentWorkingDirectory)) raise
def Evaluate(condition: str, validVariableDict: Dict[str, object], source: str) -> bool: variableReport = GeneratorVariableReport() for variableKey, variableValue in validVariableDict.items(): if isinstance(variableValue, str): variableReport.Add(variableKey, ["'{0}'".format(variableValue)]) elif isinstance(variableValue, bool): variableReport.Add(variableKey, ["{0}".format(variableValue)]) else: raise Exception("Not supported") processedCondition = ReportVariableFormatter.Format( condition, variableReport, {}) # Do some validation on the condition to ensure it only contains the elements we want and support astRootNode = EvaluateConditionInterpreter.__Parse( processedCondition, condition, source) nodeVisitor = EvaluateConditionNodeVisitor(source, processedCondition) nodeVisitor.visit(astRootNode) return EvaluateConditionInterpreter.__DoEvaluate( astRootNode, validVariableDict)
def __TryGenerateRunCommandForExecutable( self, buildContext: LocalBuildContext, package: Package, buildConfig: BuildConfigRecord, runCommands: Optional[List[str]], generatorConfig: GeneratorConfig) -> Optional[List[str]]: if package.Type != PackageType.Executable or runCommands is None or len( runCommands) <= 0: return None if package.ResolvedBuildPath is None or package.AbsolutePath is None: raise Exception("Invalid package") if package not in buildContext.GeneratorReportDict: raise Exception( "ForAllExe not supported by generator for package: {0}".format( package.Name)) generatorReport = buildContext.GeneratorReportDict[package] variableReport = generatorReport.VariableReport executableReport = generatorReport.ExecutableReport if executableReport is None: raise Exception( "ForAllExe not supported by generator for package {0} as it didnt contain a executable record" .format(package.Name)) foundVariantExePath = ReportVariableFormatter.Format( executableReport.ExeFormatString, variableReport, buildConfig.VariantSettingsDict, executableReport.EnvironmentVariableResolveMethod) if buildConfig.Generator is None: raise Exception("Generator is missing") buildExecutableInfo = buildConfig.Generator.TryGetBuildExecutableInfo( self.Log, generatorConfig, package, generatorReport, buildConfig.VariantSettingsDict) if buildExecutableInfo is not None: # Override the "install-type" path with the "development" exe path foundVariantExePath = buildExecutableInfo.BuildExePath packagePath = package.AbsolutePath fullPathExe = IOUtil.Join(packagePath, foundVariantExePath) exeName = IOUtil.GetFileName(foundVariantExePath) exePath = IOUtil.GetDirectoryName(fullPathExe) contentPath = IOUtil.Join(packagePath, ToolSharedValues.CONTENT_FOLDER_NAME) fullBuildDirPath = IOUtil.Join(packagePath, package.ResolvedBuildPath) fullBuildDirPath = buildContext.Config.ToCurrentOSPathDirectConversion( fullBuildDirPath) fullPathExe = buildContext.Config.ToCurrentOSPathDirectConversion( fullPathExe) exeName = buildContext.Config.ToCurrentOSPathDirectConversion(exeName) exePath = buildContext.Config.ToCurrentOSPathDirectConversion(exePath) packagePath = buildContext.Config.ToCurrentOSPathDirectConversion( packagePath) contentPath = buildContext.Config.ToCurrentOSPathDirectConversion( contentPath) commands = [] if executableReport.RunScript is not None: runScript = executableReport.RunScript if not executableReport.UseAsRelative: runScript = IOUtil.Join(packagePath, runScript) commands.append(runScript) for commandToRun in runCommands: command = commandToRun command = command.replace("(EXE)", fullPathExe) command = command.replace("(EXE_NAME)", exeName) command = command.replace("(EXE_PATH)", exePath) command = command.replace("(PACKAGE_NAME)", package.Name) command = command.replace("(PACKAGE_PATH)", packagePath) command = command.replace("(CONTENT_PATH)", contentPath) command = command.replace("(BUILD_PATH)", fullBuildDirPath) commands.append(command) return commands
def __Build(self, buildContext: LocalBuildContext, buildConfig: BuildConfigRecord, buildEnv: Dict[str, str], buildReport: GeneratorBuildReport, variableReport: GeneratorVariableReport, currentWorkingDirectory: Optional[str], strHelpContext: str) -> None: buildCommandReport = buildReport.BuildCommandReport if buildCommandReport is None: if self.Log.Verbosity >= 5: self.Log.LogPrint( "Skipping {0} as its build command was None".format( strHelpContext)) return if buildCommandReport.CurrentWorkingDirectoryFormatString is not None: currentWorkingDirectory = ReportVariableFormatter.Format( buildCommandReport.CurrentWorkingDirectoryFormatString, variableReport, buildConfig.VariantSettingsDict) if currentWorkingDirectory is None: raise Exception("No current working directory supplied") buildCommandStr = ReportVariableFormatter.Format( buildCommandReport.CommandFormatString, variableReport, buildConfig.VariantSettingsDict) if not buildCommandReport.UseAsRelative: buildCommandStr = IOUtil.Join(currentWorkingDirectory, buildCommandStr) buildArgumentList = [] for buildArgument in buildCommandReport.Arguments: buildArgument = ReportVariableFormatter.Format( buildArgument, variableReport, buildConfig.VariantSettingsDict) buildArgumentList.append(buildArgument) nativeBuildArgumentList = [] for buildArgument in buildCommandReport.NativeArguments: buildArgument = ReportVariableFormatter.Format( buildArgument, variableReport, buildConfig.VariantSettingsDict) nativeBuildArgumentList.append(buildArgument) self.__AppendToRightArgumentList( buildArgumentList, nativeBuildArgumentList, buildCommandReport.NativeArgumentSeparator, buildConfig.BuildArgs) self.__AppendToRightArgumentList( buildArgumentList, nativeBuildArgumentList, buildCommandReport.NativeArgumentSeparator, buildContext.Platform.AdditionalBuildArguments) buildCommand = [buildCommandStr] + buildArgumentList if buildCommandReport.NativeArgumentSeparator is not None and len( nativeBuildArgumentList) > 0: buildCommand.append(buildCommandReport.NativeArgumentSeparator) buildCommand += nativeBuildArgumentList try: if self.Log.Verbosity >= 1: self.Log.LogPrint( "Running build command '{0}' in '{1}'".format( self.__SafeJoinCommandArguments(buildCommand), currentWorkingDirectory)) result = subprocess.call(buildCommand, cwd=currentWorkingDirectory, env=buildEnv) if result != 0: self.Log.LogPrintWarning( "The build command '{0}' failed with '{1}'. It was run with CWD: '{2}'" .format(self.__SafeJoinCommandArguments(buildCommand), result, currentWorkingDirectory)) sys.exit(result) except FileNotFoundError: self.Log.DoPrintWarning( "The build command '{0}' failed with 'file not found'. It was run with CWD: '{1}'" .format(self.__SafeJoinCommandArguments(buildCommand), currentWorkingDirectory)) raise
def __ConfigureBuild(self, report: PackageGeneratorConfigReport, buildConfig: BuildConfigRecord) -> None: configReport = report.ConfigReport.ConfigCommandReport variableReport = report.VariableReport buildArgumentList = [] for buildArgument in configReport.Arguments: buildArgument = ReportVariableFormatter.Format( buildArgument, variableReport, buildConfig.VariantSettingsDict) buildArgumentList.append(buildArgument) configCommandStr = ReportVariableFormatter.Format( configReport.CommandFormatString, variableReport, buildConfig.VariantSettingsDict) currentWorkingDirectory = ReportVariableFormatter.Format( configReport.CurrentWorkingDirectoryFormatString, variableReport, buildConfig.VariantSettingsDict) configCommand = [configCommandStr ] + buildArgumentList # + buildConfig.BuildConfigArgs #if len(buildContext.Platform.AdditionalBuildConfigArguments) > 0: # buildCommand += buildContext.Platform.AdditionalBuildConfigArguments try: IOUtil.SafeMakeDirs(currentWorkingDirectory) cacheFilename = IOUtil.Join(currentWorkingDirectory, '.FslConfigureCache.json') dirtyBuildConfigureCache = self.__CheckBuildConfigureModifications( cacheFilename, report.GeneratedFileSet, configCommand) if dirtyBuildConfigureCache is None: self.Log.LogPrint( "Build configuration not modified, skipping configure") return self.Log.LogPrint("Build configuration modifed, running configure") if self.Log.Verbosity >= 1: self.Log.LogPrint( "Running build config command '{0}' in '{1}'".format( self.__SafeJoinCommandArguments(configCommand), currentWorkingDirectory)) result = subprocess.call(configCommand, cwd=currentWorkingDirectory) if result != 0: self.Log.LogPrintWarning( "The build config command '{0}' failed with '{1}'. It was run with CWD: '{2}'" .format(self.__SafeJoinCommandArguments(configCommand), result, currentWorkingDirectory)) sys.exit(result) else: BuildConfigureCache.Save(self.Log, cacheFilename, dirtyBuildConfigureCache) except FileNotFoundError: self.Log.DoPrintWarning( "The build config command '{0}' failed with 'file not found'. It was run with CWD: '{1}'" .format(self.__SafeJoinCommandArguments(configCommand), currentWorkingDirectory)) raise
def __TryGenerateRunCommandForExecutable( self, buildContext: LocalBuildContext, package: Package, userVariantSettingDict: Dict[str, str], runCommands: Optional[List[str]]) -> Optional[List[str]]: if package.Type != PackageType.Executable or runCommands is None or len( runCommands) <= 0: return None if package.ResolvedBuildPath is None or package.AbsolutePath is None: raise Exception("Invalid package") if package not in buildContext.GeneratorReportDict: raise Exception( "ForAllExe not supported by generator for package: {0}".format( package.Name)) generatorReport = buildContext.GeneratorReportDict[package] variableReport = generatorReport.VariableReport executableReport = generatorReport.ExecutableReport if executableReport is None: raise Exception( "ForAllExe not supported by generator for package {0} as it didnt contain a executable record" .format(package.Name)) foundVariantExePath = ReportVariableFormatter.Format( executableReport.ExeFormatString, variableReport, userVariantSettingDict, executableReport.EnvironmentVariableResolveMethod) packagePath = package.AbsolutePath fullPathExe = IOUtil.Join(packagePath, foundVariantExePath) exeName = IOUtil.GetFileName(foundVariantExePath) exePath = IOUtil.GetDirectoryName(fullPathExe) contentPath = IOUtil.Join(packagePath, "Content") fullBuildDirPath = IOUtil.Join(packagePath, package.ResolvedBuildPath) fullBuildDirPath = buildContext.Config.ToCurrentOSPathDirectConversion( fullBuildDirPath) fullPathExe = buildContext.Config.ToCurrentOSPathDirectConversion( fullPathExe) exeName = buildContext.Config.ToCurrentOSPathDirectConversion(exeName) exePath = buildContext.Config.ToCurrentOSPathDirectConversion(exePath) packagePath = buildContext.Config.ToCurrentOSPathDirectConversion( packagePath) contentPath = buildContext.Config.ToCurrentOSPathDirectConversion( contentPath) commands = [] if executableReport.RunScript is not None: runScript = executableReport.RunScript if not executableReport.UseAsRelative: runScript = IOUtil.Join(packagePath, runScript) commands.append(runScript) for commandToRun in runCommands: command = commandToRun command = command.replace("(EXE)", fullPathExe) command = command.replace("(EXE_NAME)", exeName) command = command.replace("(EXE_PATH)", exePath) command = command.replace("(PACKAGE_NAME)", package.Name) command = command.replace("(PACKAGE_PATH)", packagePath) command = command.replace("(CONTENT_PATH)", contentPath) command = command.replace("(BUILD_PATH)", fullBuildDirPath) commands.append(command) return commands
def __BuildPackage(self, buildContext: LocalBuildContext, package: Package, buildConfig: BuildConfigRecord, buildEnv: Dict[str, str], runCommands: Optional[List[str]]) -> None: if package.AbsolutePath is None or package.ResolvedBuildPath is None: raise Exception("Invalid package") if buildContext.GeneratorReportDict is None: raise Exception( "Build not supported by generator '{0}' for package: {1}". format(buildContext.GeneratorName, package.Name)) if package not in buildContext.GeneratorReportDict: raise Exception( "Build not supported by generator '{0}' for package: {1}". format(buildContext.GeneratorName, package.Name)) generatorReport = buildContext.GeneratorReportDict[package] buildReport = generatorReport.BuildReport variableReport = generatorReport.VariableReport if buildReport is None: raise Exception( "Build report not supported by generator '{0}' for package: {1}" .format(buildContext.GeneratorName, package.Name)) buildCommandReport = buildReport.BuildCommandReport if buildCommandReport is None: if self.Log.Verbosity >= 5: self.Log.LogPrint( "Skipping package '{0}' as its build command was None". format(package.Name)) return currentWorkingDirectory = package.AbsolutePath if buildCommandReport.CurrentWorkingDirectoryFormatString is not None: currentWorkingDirectory = ReportVariableFormatter.Format( buildCommandReport.CurrentWorkingDirectoryFormatString, variableReport, buildConfig.VariantSettingsDict) buildCommandStr = ReportVariableFormatter.Format( buildCommandReport.CommandFormatString, variableReport, buildConfig.VariantSettingsDict) if not buildCommandReport.UseAsRelative: buildCommandStr = IOUtil.Join(currentWorkingDirectory, buildCommandStr) buildArgumentList = [] for buildArgument in buildCommandReport.Arguments: buildArgument = ReportVariableFormatter.Format( buildArgument, variableReport, buildConfig.VariantSettingsDict) buildArgumentList.append(buildArgument) buildCommand = [buildCommandStr ] + buildArgumentList + buildConfig.BuildArgs if len(buildContext.Platform.AdditionalBuildArguments) > 0: buildCommand += buildContext.Platform.AdditionalBuildArguments try: result = subprocess.call(buildCommand, cwd=currentWorkingDirectory, env=buildEnv) if result != 0: self.Log.LogPrintWarning( "The build command '{0}' failed with '{1}'. It was run with CWD: '{2}'" .format(" ".join(buildCommand), result, currentWorkingDirectory)) sys.exit(result) except FileNotFoundError: self.Log.DoPrintWarning( "The build command '{0}' failed with 'file not found'. It was run with CWD: '{1}'" .format(" ".join(buildCommand), currentWorkingDirectory)) raise if runCommands: try: # TODO: Allow the working directory for the run command to be changed too. For now use the original choice of absolute path for the package currentWorkingDirectory = package.AbsolutePath result = subprocess.call(runCommands, cwd=currentWorkingDirectory, env=buildEnv) if result != 0: self.Log.LogPrintWarning( "The run command '{0}' failed with '{1}'. It was run with CWD: '{2}'" .format(" ".join(runCommands), result, currentWorkingDirectory)) sys.exit(result) except FileNotFoundError: self.Log.LogPrintWarning( "The run command '{0}' failed with 'file not found'. It was run with CWD: '{1}'" .format(" ".join(runCommands), currentWorkingDirectory)) raise
def GetBuildDir(projectInfo: ToolConfigProjectInfo, buildDir: str) -> str: variableReport = GeneratorVariableReport() BuildUtil.AddCustomVariables(variableReport, projectInfo) return ReportVariableFormatter.Format(buildDir, variableReport, {})