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
Beispiel #4
0
    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
Beispiel #10
0
 def GetBuildDir(projectInfo: ToolConfigProjectInfo, buildDir: str) -> str:
     variableReport = GeneratorVariableReport()
     BuildUtil.AddCustomVariables(variableReport, projectInfo)
     return ReportVariableFormatter.Format(buildDir, variableReport, {})