示例#1
0
    def __FiltersPackagesByExtensions(
        log: Log, packages: Union[List[Package], List[AppInfoPackage]],
        extensionNameList: ExtensionListManager, featureNameList: List[str],
        requirementTree: Union[RequirementTree, AppInfoGlobalRequirementTree]
    ) -> List[T]:
        """  Filter packages by extensions.
             If '*' is in the extensionNameList a clone of 'packages' will be returned
             Else we return a list containing only the packages that can be build with the available extensions
        """
        if extensionNameList.AllowAllExtensions:
            log.LogPrint("Filtering by extensions: All")
            return cast(List[T], list(packages))
        else:
            log.LogPrint("Filtering by extensions: {0}".format(", ".join([
                str(qualifiedName)
                for qualifiedName in extensionNameList.Content
            ])))

        filteredPackageList = []
        for package in packages:
            if PackageFilter.__IsAllPackageExtensionAvailable(
                    package, requirementTree):
                filteredPackageList.append(package)
            elif package.Type == PackageType.Library or package.Type == PackageType.Executable or package.ResolvedDirectExperimentalRecipe != None:
                missingNames = PackageFilter.__GetCompleteMissingExtensionNames(
                    package, requirementTree)
                log.LogPrint(
                    "Could not build package '{0}' due to missing extension '{1}'"
                    .format(package.Name, ", ".join(missingNames)))
        return cast(List[T], filteredPackageList)
示例#2
0
    def __FiltersPackagesByFeatures(log: Log,
                                    packages: Union[List[Package],
                                                    List[AppInfoPackage]],
                                    featureNameList: List[str]) -> List[T]:
        """  Filter packages by features.
             If '*' is in the featureNameList a clone of 'packages' will be returned
             Else we return a list containing only the packages that can be build with the available features
        """

        if '*' in featureNameList:
            log.LogPrint("Filtering by features: All")
            return cast(List[T], list(packages))
        else:
            log.LogPrint("Filtering by features: {0}".format(
                ", ".join(featureNameList)))

        filteredPackageList = []
        for package in packages:
            if PackageFilter.__FeaturesAvailable(package, featureNameList):
                filteredPackageList.append(package)
            elif package.Type == PackageType.Library or package.Type == PackageType.Executable or package.ResolvedDirectExperimentalRecipe is not None:
                missingFeatures = PackageFilter.__GetCompleteMissingFeatureNames(
                    package, featureNameList)
                log.LogPrint(
                    "Could not build package '{0}' due to missing features '{1}'"
                    .format(package.Name, ", ".join(missingFeatures)))
        return cast(List[T], filteredPackageList)
示例#3
0
    def __init__(self, log: Log, packageName: str, xmlExperimentalRecipe: XmlExperimentalRecipe, forceDisable: bool) -> None:
        """
        forceDisable will not disable 'the external' recipe type used for build tools
        """
        self._Log = log
        self.SysXmlSource = xmlExperimentalRecipe
        self.Version = xmlExperimentalRecipe.Version    # type: Optional[Version]
        self.ShortName = xmlExperimentalRecipe.ShortName
        self.FullName = xmlExperimentalRecipe.FullName
        self.AllowFind = xmlExperimentalRecipe.Find

        determinedType = self.__DetermineRecipeType(xmlExperimentalRecipe)
        self.Type = determinedType if not forceDisable or determinedType == RecipeType.External else RecipeType.Disabled
        self.Pipeline = xmlExperimentalRecipe.Pipeline if self.Type == RecipeType.Build else None
        self.ValidateInstallation = xmlExperimentalRecipe.ValidateInstallation if self.Type != RecipeType.Disabled else None
        self.IsLocalSourceBuild = False
        if (self.Pipeline is not None and len(self.Pipeline.CommandList) > 0 and
                self.Pipeline.CommandList[0].CommandType == BuildRecipePipelineCommand.Source):
            self.IsLocalSourceBuild = True

        # The installation path of the package
        self.ResolvedInstallLocation = None  # type: Optional[ResolvedPath]

        if self.Type == RecipeType.Undefined:
            log.DoPrintWarning("No installation or validation available for package '{0}' recipe '{1}'".format(packageName, self.FullName))
        if self.ValidateInstallation is None and self.Type != RecipeType.Disabled:
            log.DoPrintWarning("No installation validation available for package '{0}' recipe '{1}'".format(packageName, self.FullName))
        if forceDisable and log.Verbosity >= 4:
            if self.Type == RecipeType.Disabled:
                log.LogPrint("  - Force disabling recipe for package {0}".format(packageName))
            else:
                log.LogPrint("  - Force disabling recipe for package {0} ignored due to type".format(packageName))
示例#4
0
    def __init__(self, log: Log, rootDirs: List[ToolConfigRootDirectory],
                 basedUponXML: XmlExperimental, configFileName: str,
                 projectRootDirectory: str) -> None:
        super(ToolConfigExperimental, self).__init__()
        self.BasedOn = basedUponXML

        self.DefaultThirdPartyInstallReadonlyCacheDirectory = None  # type: Optional[ToolConfigExperimentalDefaultThirdPartyInstallDirectory]

        self.AllowDownloads = basedUponXML.AllowDownloads
        self.DisableDownloadEnv = basedUponXML.DisableDownloadEnv
        self.DefaultThirdPartyInstallDirectory = ToolConfigExperimentalDefaultThirdPartyInstallDirectory(
            log, basedUponXML.DefaultThirdPartyInstallDirectory,
            "DefaultThirdPartyInstallDirectory", False)
        self.DefaultThirdPartyInstallReadonlyCacheDirectory = self.__TryCreateReadonlyCache(
            log, basedUponXML.DefaultThirdPartyInstallReadonlyCacheDirectory)

        if log.Verbosity > 1:
            log.LogPrint(
                "DefaultThirdPartyInstallDirectory: {0} which resolves to '{1}'"
                .format(self.DefaultThirdPartyInstallDirectory.Name,
                        self.DefaultThirdPartyInstallDirectory.ResolvedPath))
            if not self.DefaultThirdPartyInstallReadonlyCacheDirectory is None:
                log.LogPrint(
                    "DefaultThirdPartyInstallReadonlyCacheDirectory: {0} which resolves to '{1}'"
                    .format(
                        self.DefaultThirdPartyInstallReadonlyCacheDirectory.
                        Name,
                        self.DefaultThirdPartyInstallReadonlyCacheDirectory.
                        ResolvedPath))
示例#5
0
def CheckWindowsGLES(log: Log) -> None:
    log.LogPrint("- OpenGL ES environment")
    try:
        emulator = os.environ.get("FSL_GLES_NAME")
        if not emulator:
            raise EnvironmentError(
                "OpenGLES emulation 'FSL_GLES_NAME' environment variable is not set."
            )

        emulator = emulator.lower()
        if (emulator == 'arm' or emulator == 'default'):
            CheckWindowsGLESArm(log)
        elif (emulator == 'mesa'):
            CheckWindowsGLESPowerVR(log)
        elif (emulator == 'powervr'):
            CheckWindowsGLESMesa(log)
        elif (emulator == 'qualcomm'):
            CheckWindowsGLESQualcomm(log)
        elif (emulator == 'vivante'):
            CheckWindowsGLESVivante(log)
        else:
            log.LogPrint("WARNING: Unknown emulator '{0}'".format(emulator))
    except:
        print(
            "ERROR: CheckWindowsGLES failed.\nThis indicates that the OpenGLES emulation environment was not correctly setup and the code wont be able to locate the necessary OpenGLES header files. Possible causes:\n- Are you using the right emulator type: x64 or x86 see documentation.\n- Did you run the required setup scripts?\n- If building from visual studio did you launch the project via .StartProject.bat\n"
        )
        raise
示例#6
0
 def __AddParentFeatures(log: Log, featureNameList: List[str],
                         requirementTree: Union[RequirementTree, AppInfoGlobalRequirementTree],
                         useStrictFeatureWarning: bool) -> List[str]:
     if '*' in featureNameList:
         return featureNameList
     featureNameList.sort()
     if log.Verbosity > 1:
         log.LogPrint("Automatically adding features to supplied feature list {0}".format(featureNameList))
     featureNameSet = set(featureNameList)
     for featureName in featureNameList:
         if featureName in requirementTree.FeatureToNodeDict:
             requirementNode = requirementTree.FeatureToNodeDict[featureName]
             currentNode = requirementNode  # type: Optional[Union[RequirementTreeNode, AppInfoGlobalRequirementTreeNode]]
             while currentNode is not None:
                 if currentNode.Content is not None:
                     if not currentNode.Content.Name in featureNameSet:
                         featureNameSet.add(currentNode.Content.Name)
                         if log.Verbosity > 1 and requirementNode.Content is not None:
                             log.LogPrint("- '{0}' because '{1}' depends on it".format(currentNode.Content.Name, requirementNode.Content.Name))
                 currentNode = currentNode.Parent
         else:
             featureNameSet.remove(featureName)
             if useStrictFeatureWarning:
                 log.DoPrintWarning("Unknown feature name '{0}' in filterNameList {1}".format(featureName, featureNameList))
             else:
                 # For now just log a warning
                 log.LogPrintVerbose(5, "Unknown feature name '{0}' in filterNameList {1}".format(featureName, featureNameList))
     resultList = list(featureNameSet)
     resultList.sort()
     return resultList
示例#7
0
    def Run(log: Log, toolConfig: ToolConfig, formatPackageList: List[Package],
            customPackageFileFilter: Optional[CustomPackageFileFilter],
            packageRecipeResultManager: PackageRecipeResultManager,
            clangFormatConfiguration: ClangFormatConfiguration,
            cmakeConfig: GeneratorCMakeConfig, repairEnabled: bool,
            buildThreads: int, useLegacyTidyMethod: bool) -> None:
        """ RunClangFormat on a package at a time """

        # Lookup the recommended build threads using the standard build algorithm
        numBuildThreads = PlatformBuildUtil.GetRecommendedBuildThreads(
            buildThreads)

        clangExeInfo = PerformClangUtil.LookupRecipeResults(
            packageRecipeResultManager,
            clangFormatConfiguration.RecipePackageName,
            MagicValues.ClangFormatCommand)
        ninjaExeInfo = PerformClangUtil.LookupRecipeResults(
            packageRecipeResultManager,
            clangFormatConfiguration.NinjaRecipePackageName,
            MagicValues.NinjaCommand)

        log.LogPrint("ClangFormat version: {0}".format(clangExeInfo.Version))
        log.LogPrint("Ninja version: {0}".format(ninjaExeInfo.Version))

        log.LogPrint("Running clang-format")

        # Filter the package list so it only contains things we can process
        finalPackageList = [
            package for package in formatPackageList
            if PerformClangUtil.CanProcessPackage(package)
        ]

        sortedPackages = list(finalPackageList)
        sortedPackages.sort(key=lambda s: s.Name.lower())

        #test = set()
        #for entry in sortedPackages:
        #    if entry.Name in test:
        #        raise Exception("duplicated package")
        #    else:
        #       test.add(entry.Name)

        if useLegacyTidyMethod:
            count = PerformClangFormatHelper.Process(
                log, toolConfig, customPackageFileFilter,
                clangFormatConfiguration, clangExeInfo, sortedPackages,
                repairEnabled, numBuildThreads)
        else:
            count = PerformClangFormatHelper2.Process(
                log, toolConfig, customPackageFileFilter,
                clangFormatConfiguration, cmakeConfig, clangExeInfo,
                ninjaExeInfo, sortedPackages, repairEnabled, numBuildThreads)

        if count == 0:
            if customPackageFileFilter is None:
                log.DoPrintWarning("No files processed")
            else:
                log.DoPrintWarning(
                    "No files processed, could not find a package that matches {0}"
                    .format(customPackageFileFilter))
示例#8
0
    def Process(log: Log, toolConfig: ToolConfig, customPackageFileFilter: Optional[CustomPackageFileFilter],
                clangFormatConfiguration: ClangFormatConfiguration, cmakeConfig: GeneratorCMakeConfig,
                clangFormatExeInfo: ClangExeInfo, ninjaExeInfo: ClangExeInfo, sortedPackageList: List[Package],
                repairEnabled: bool, numBuildThreads: int) -> int:
        totalProcessedCount = 0

        logOutput = False
        currentWorkingDirectory = BuildUtil.GetBuildDir(log, toolConfig, cmakeConfig.CheckDir)
        currentWorkingDirectory = IOUtil.Join(currentWorkingDirectory, "format")
        ninjaOutputFile =  IOUtil.Join(currentWorkingDirectory, "build.ninja")
        toolVersionOutputFile =  IOUtil.Join(currentWorkingDirectory, "ToolVersions.txt")
        IOUtil.SafeMakeDirs(currentWorkingDirectory)

        log.LogPrint("Using path: '{0}'".format(currentWorkingDirectory))

        log.LogPrint("Storing tool versions.")
        PerformClangFormatHelper2.WriteToolVersionFile(log, toolVersionOutputFile, clangFormatExeInfo, ninjaExeInfo)

        log.LogPrint("Generating ninja format file.")
        #foundFixes = PerformClangTidyHelper2.FindFixes(log, clangTidyFixOutputFolder)
        #if len(foundFixes) > 0:
        #    PerformClangTidyHelper2.DeleteFixes(log, clangTidyFixOutputFolder, foundFixes)

        totalProcessedCount = PerformClangFormatHelper2.GenerateNinjaTidyFile(log, toolConfig, ninjaOutputFile, currentWorkingDirectory,
                                                                              toolVersionOutputFile, clangFormatExeInfo, customPackageFileFilter,
                                                                              clangFormatConfiguration, sortedPackageList, repairEnabled)
        log.LogPrint("Executing ninja format file.")

        RunHelper.RunNinja(log, ninjaExeInfo, ninjaOutputFile, currentWorkingDirectory, numBuildThreads, logOutput)

        return totalProcessedCount
示例#9
0
def _RunClangFormat(log: Log, toolConfig: ToolConfig,
                    clangFormatConfiguration: ClangFormatConfiguration,
                    clangExeInfo: ClangExeInfo, package: Package,
                    filteredFiles: Optional[List[str]],
                    repairEnabled: bool) -> None:
    if package.ResolvedBuildAllIncludeFiles is None or len(
            package.ResolvedBuildAllIncludeFiles
    ) <= 0 or not package.AllowCheck or package.IsVirtual:
        return

    if package.AbsolutePath is None or package.ResolvedBuildSourceFiles is None:
        raise Exception("Invalid package")

    formatPackageConfig = FormatPackageConfig(log, package,
                                              clangFormatConfiguration,
                                              filteredFiles)

    cmd = clangExeInfo.Command
    buildCommand = [cmd, '-style=file']
    if repairEnabled:
        buildCommand.append('-i')
    if len(clangFormatConfiguration.AdditionalUserArguments) > 0:
        log.LogPrint("Adding user supplied arguments before '--' {0}".format(
            clangFormatConfiguration.AdditionalUserArguments))
        buildCommand += clangFormatConfiguration.AdditionalUserArguments

    buildCommand += [
        entry.ResolvedPath for entry in formatPackageConfig.AllFiles
    ]

    currentWorkingDirectory = package.AbsolutePath
    FileFinder.FindClosestFileInRoot(log, toolConfig, currentWorkingDirectory,
                                     clangFormatConfiguration.CustomFormatFile)

    try:
        # if verbose enabled we log the clang-format version
        if log.Verbosity >= 4:
            log.LogPrint("Running command '{0}' in cwd: {1}".format(
                buildCommand, currentWorkingDirectory))

        result = subprocess.call(buildCommand, cwd=currentWorkingDirectory)
        if result != 0:
            log.LogPrintWarning(
                "The command '{0}' failed with '{1}'. It was run with CWD: '{2}'"
                .format(" ".join(buildCommand), result,
                        currentWorkingDirectory))
            raise ExitException(result)
    except FileNotFoundError:
        log.DoPrintWarning(
            "The command '{0}' failed with 'file not found'. It was run with CWD: '{1}'"
            .format(" ".join(buildCommand), currentWorkingDirectory))
        raise
    def RunInAnotherThread(packageQueue: Any,
                           cancellationToken: SimpleCancellationToken,
                           mainLog: Log, toolConfig: ToolConfig, customPackageFileFilter: Optional[CustomPackageFileFilter],
                           clangFormatConfiguration: ClangFormatConfiguration, clangExeInfo: ClangExeInfo, repairEnabled: bool) -> Tuple[int,int]:
        threadId = threading.get_ident()
        mainLog.LogPrintVerbose(4, "Starting thread {0}".format(threadId))
        examinedCount = 0
        processedCount = 0
        keepWorking = True
        package = None # type: Optional[Package]

        try:
            while keepWorking and not cancellationToken.IsCancelled():
                try:
                    # Since the queue is preloaded this is ok
                    package = packageQueue.get_nowait()
                except:
                    package = None
                if package is None:
                    keepWorking = False
                else:
                    if mainLog.Verbosity >= 4:
                        mainLog.LogPrint("- clang-format on package '{0}' on thread {1}".format(package.Name, threadId))
                    else:
                        mainLog.LogPrint("- clang-format on package '{0}'".format(package.Name))

                    captureLog = CaptureLog(mainLog.Title, mainLog.Verbosity)
                    try:
                        filteredFiles = None
                        if customPackageFileFilter is not None:
                            filteredFiles = customPackageFileFilter.TryLocateFilePatternInPackage(captureLog, package, clangFormatConfiguration.FileExtensions)
                        if customPackageFileFilter is None or filteredFiles is not None:
                            processedCount += 1
                            _RunClangFormat(captureLog, toolConfig, clangFormatConfiguration, clangExeInfo, package, filteredFiles, repairEnabled)
                        examinedCount += 1
                    finally:
                        try:
                            if len(captureLog.Captured) > 0:
                                capturedLog = "Package: '{0}' result:\n{1}".format(package.Name, "\n".join(captureLog.Captured))
                                mainLog.DoPrint(capturedLog)
                        except:
                            pass
        except Exception as ex:
            cancellationToken.Cancel()
            mainLog.DoPrintError("Cancelling tasks due to exception: {0}")
            raise
        finally:
            mainLog.LogPrintVerbose(4, "Ending thread {0}".format(threadId))

        return (examinedCount, processedCount)
示例#11
0
    def __init__(self, log: Log, errorHelpManager: ErrorHelpManager,
                 recipeFilterManager: RecipeFilterManager,
                 experimental: Optional[ToolConfigExperimental],
                 generator: GeneratorPlugin) -> None:
        if generator.CMakeConfig is None:
            raise Exception("Invalid generator")

        recipeBuilderSetup = None
        allowDownloads = False
        if experimental is not None:
            targetLocation = ResolvedPath(
                experimental.DefaultThirdPartyInstallDirectory.DynamicName,
                experimental.DefaultThirdPartyInstallDirectory.ResolvedPath)
            installReadonlySource = experimental.DefaultThirdPartyInstallReadonlyCacheDirectory
            readonlyCachePath = None if installReadonlySource is None else installReadonlySource.ResolvedPath  # type: Optional[str]
            recipeBuilderSetup = RecipeBuilderSetup(targetLocation,
                                                    readonlyCachePath)
            if IOUtil.TryGetEnvironmentVariable(
                    experimental.DisableDownloadEnv) is not None:
                allowDownloads = False
                log.LogPrint(
                    "Downloads disabled since the environment variable {0} was defined"
                    .format(experimental.DisableDownloadEnv))
            elif experimental.AllowDownloads:
                allowDownloads = True
            else:
                log.LogPrint(
                    "Downloads disabled since the project has it disabled by default"
                )

        validVariableDict = {}  # type: Dict[str, object]
        validVariableDict['PlatformName'] = generator.PlatformName
        validVariableDict['IsCMakeBuild'] = generator.IsCMake

        generatorInfo = GeneratorInfo(generator.IsCMake,
                                      generator.CMakeConfig.AllowFindPackage,
                                      validVariableDict)
        super().__init__(log, errorHelpManager, generator.PlatformName,
                         generator.PlatformName, generatorInfo,
                         generator.CMakeConfig, recipeBuilderSetup)

        #allowDownload=True, disableDownloadEnv=None

        self.Log = log
        self.Generator = generator
        # for now the generator is also the platform and the existing code use that name so maintain compatibility for now
        self.Platform = generator
        self.AllowDownloads = allowDownloads
        self.RecipeFilterManager = recipeFilterManager
示例#12
0
 def __TryGetValidateInstallation(self, log: Log, xmlElement: ET.Element) -> Optional[XmlRecipeInstallation]:
     child = self._TryGetElement(xmlElement, 'Installation')
     if child is None:
         if log.Verbosity >= 2:
             log.LogPrint("The Installation element is missing for recipe {0}".format(self.Name))
         return None
     return XmlRecipeInstallation(log, child)
示例#13
0
    def ProcessInstallDirClaim(log: Log,
                               targetPath: str,
                               sdkPath: str,
                               forceClaimInstallArea: bool, 
                               installAreaInfoPath: str) -> None:
        filePath = IOUtil.Join(targetPath, installAreaInfoPath)

        # Beware that this method to claim a area is in no way secure
        # It will basically only be useful after the claim file has been created
        # So we start with a possible race condition, but any future attempts to use the directory
        # will catch that multiple repos are trying to reuse the same install area
        fileContent = IOUtil.TryReadFile(filePath)
        if fileContent is None:
            log.LogPrint("Install area '{0}' is unclaimed, claiming it".format(targetPath))
            BuildAreaInfoFileUtil.ClaimInstallDirNow(log, targetPath, filePath, sdkPath, forceClaimInstallArea)
            return

        jsonBuildInfoDict = json.loads(fileContent)
        if not BuildAreaInfoFile.IsDictValid(jsonBuildInfoDict):
            if not forceClaimInstallArea:
                raise Exception("Install area '{0}' contained an invalid file '{1}', did you try to run concurrent builds using the same install directory or did it get corrupted? Delete the file to allow the build to continue or use --ForceClaimInstallArea to do so automatically. You could also set up a readonly cache area to reuse between repos see the documentation for more info.".format(targetPath, filePath))
            log.DoPrintWarning("Install area '{0}' contained an invalid file '{1}', as --ForceClaimInstallArea was specified it was overwritten and '{2}' now controls it".format(targetPath, filePath, sdkPath))
            jsonBuildInfoDict = BuildAreaInfoFileUtil.ClaimInstallDirNow(log, targetPath, filePath, sdkPath, forceClaimInstallArea, logWarning=False)

        buildAreaInfoFile = BuildAreaInfoFile(jsonBuildInfoDict)
        if buildAreaInfoFile.SDKPath != sdkPath:
            if not forceClaimInstallArea:
                raise Exception("The Install area at '{0}' is already claimed by the sdk at '{1}' so the sdk at '{2}' can not reuse it as it could give concurrency issues if multiple builds execute at the same time. If you are sure that you are not doing concurrent builds and you just want to use the area for a new SDK you can force claim it with --ForceClaimInstallArea. You could also set up a readonly cache area to reuse between repos see the documentation for more info.".format(targetPath, buildAreaInfoFile.SDKPath, sdkPath))
            log.DoPrintWarning("The Install area at '{0}' was already claimed by the sdk at '{1}' but '{2}' took control of it as --ForceClaimInstallArea was specified.".format(targetPath, buildAreaInfoFile.SDKPath, sdkPath))
            jsonBuildInfoDict = BuildAreaInfoFileUtil.ClaimInstallDirNow(log, targetPath, filePath, sdkPath, forceClaimInstallArea, logWarning=False)
    def Run(log: Log, toolConfig: ToolConfig, formatPackageList: List[Package],
            customPackageFileFilter: Optional[CustomPackageFileFilter],
            packageRecipeResultManager: PackageRecipeResultManager,
            clangFormatConfiguration: ClangFormatConfiguration,
            repairEnabled: bool) -> None:
        """ RunClangFormat on a package at a time """

        clangExeInfo = PerformClangUtil.LookupRecipeResults(
            packageRecipeResultManager,
            clangFormatConfiguration.RecipePackageName,
            MagicValues.ClangFormatCommand)

        if log.Verbosity >= 1:
            PerformClangUtil.ShowVersion(log, clangExeInfo)

        log.LogPrint("Running clang-format")

        # Filter the package list so it only contains things we can process
        finalPackageList = [
            package for package in formatPackageList
            if PerformClangUtil.CanProcessPackage(package)
        ]

        sortedPackages = list(finalPackageList)
        sortedPackages.sort(key=lambda s: s.Name.lower())
        for package in sortedPackages:
            filteredFiles = None if customPackageFileFilter is None else customPackageFileFilter.TryLocateFilePatternInPackage(
                log, package, clangFormatConfiguration.FileExtensions)
            if customPackageFileFilter is None or filteredFiles is not None:
                _RunClangFormat(log, toolConfig, clangFormatConfiguration,
                                clangExeInfo, package, filteredFiles,
                                repairEnabled)
示例#15
0
    def __BuildInstanceGraph(
            log: Log, queue: PackageResolveQueue) -> ResolvedPackageGraph:
        graph = ResolvedPackageGraph()
        instanceDict = dict(
        )  # type: Dict[PackageName, ResolvedPackageInstance]

        resolver = PackageResolver(log)

        while len(queue) > 0:
            currentPackage = queue.Dequeue()
            if currentPackage.Type != PackageType.TopLevel:
                if log.Verbosity >= LocalVerbosityLevel.Info:
                    log.LogPrint(
                        "Resolving package: {0}".format(currentPackage))

                resolvedPackageTemplate = resolver.Resolve(currentPackage)
                PackageGraphBuilder.__AddTemplateNodeAndEdges(
                    graph, resolvedPackageTemplate)

                if len(resolvedPackageTemplate.InstanceConfigs) <= 0:
                    raise Exception(
                        "ERROR: no instance configs provided by template")

                isFlavorSingleton = len(
                    resolvedPackageTemplate.InstanceConfigs) <= 1
                for instanceConfig in resolvedPackageTemplate.InstanceConfigs:
                    packageInstance = PackageGraphBuilder.__CreateResolvedPackageInstance(
                        log, instanceDict, resolvedPackageTemplate,
                        instanceConfig,
                        isFlavorSingleton)  # type: ResolvedPackageInstance
                    PackageGraphBuilder.__AddInstanceNodeAndEdges(
                        graph, packageInstance)
            elif len(queue) != 0:
                raise Exception("internal error")
        return graph
    def Run(log: Log, toolConfig: ToolConfig, formatPackageList: List[Package],
            customPackageFileFilter: Optional[CustomPackageFileFilter],
            packageRecipeResultManager: PackageRecipeResultManager,
            clangFormatConfiguration: ClangFormatConfiguration, repairEnabled: bool, buildThreads: int) -> None:
        """ RunClangFormat on a package at a time """

        # Lookup the recommended build threads using the standard build algorithm
        buildThreads = PlatformBuildUtil.GetRecommendedBuildThreads(buildThreads)

        clangExeInfo = PerformClangUtil.LookupRecipeResults(packageRecipeResultManager, clangFormatConfiguration.RecipePackageName,
                                                            MagicValues.ClangFormatCommand)

        if log.Verbosity >= 1:
            PerformClangUtil.ShowVersion(log, clangExeInfo)

        log.LogPrint("Running clang-format")

        # Filter the package list so it only contains things we can process
        finalPackageList = [package for package in formatPackageList if PerformClangUtil.CanProcessPackage(package)]

        sortedPackages = list(finalPackageList)
        sortedPackages.sort(key=lambda s: s.Name.lower())

        count = PerformClangFormatHelper.Process(log, toolConfig, customPackageFileFilter, clangFormatConfiguration, clangExeInfo, sortedPackages,
                                                 repairEnabled, buildThreads)
        if count == 0:
            if customPackageFileFilter is None:
                log.DoPrintWarning("No files processed")
            else:
                log.DoPrintWarning("No files processed, could not find a package that matches {0}".format(customPackageFileFilter))
示例#17
0
    def __ApplyClangTidy(self, log: Log, toolConfig: ToolConfig, localToolConfig: LocalToolConfig,
                         packageRecipeResultManager: Optional[PackageRecipeResultManager],
                         topLevelPackage: Optional[Package], tidyPackageList: List[Package], generator: GeneratorPlugin,
                         config: Config, generatorContext: GeneratorContext, customPackageFileFilter: Optional[CustomPackageFileFilter]) -> None:
        """
        The only reason we take optionals here is because they are optional in the main program, so its just easier to do the check here
        :currentDirPath: is used to process the '--file' argument
        """
        if toolConfig.ClangTidyConfiguration is None or packageRecipeResultManager is None or topLevelPackage is None:
            raise Exception("internal error")

        # Generate the build files (so that the run scripts exist)
        log.LogPrint("Generating build files")
        generator.Generate(generatorContext, config, tidyPackageList)

        clangFormatFilename = None if toolConfig.ClangFormatConfiguration is None else toolConfig.ClangFormatConfiguration.CustomFormatFile

        pythonScriptRoot = IOUtil.Join(config.SDKPath, ".Config")

        performClangTidyConfig = PerformClangTidyConfig(toolConfig.ClangTidyConfiguration, localToolConfig.ClangTidyArgs,
                                                        localToolConfig.ClangTidyPostfixArgs, localToolConfig.TidyOverrideChecks,
                                                        localToolConfig.ClangTidyProfile, not localToolConfig.ClangTidyNoDynamicVariantCache,
                                                        localToolConfig.Repair)
        PerformClangTidy.Run(log, toolConfig, generatorContext.Generator.PlatformId, topLevelPackage, tidyPackageList,
                             localToolConfig.BuildVariantsDict, pythonScriptRoot, generatorContext, config.SDKConfigTemplatePath,
                             packageRecipeResultManager, performClangTidyConfig, customPackageFileFilter, clangFormatFilename,
                             localToolConfig.BuildThreads, localToolConfig.Legacy)
示例#18
0
def Scan(log: Log, scanPackageList: List[Package],
         customPackageFileFilter: Optional[CustomPackageFileFilter],
         repairEnabled: bool, thirdpartyExceptionDir: Optional[str],
         checkType: CheckType, disableWrite: bool) -> None:
    """
    Run through all source files that are part of the packages and check for common errors
    :param scanPackageList: the packages that will be scanned.
    """

    log.LogPrint("Running source scan")

    extensionList = __g_includeExtensionList + __g_sourceExtensionList

    # Filter the package list so it only contains things we can process
    finalPackageList = [
        package for package in scanPackageList
        if PerformClangUtil.CanProcessPackage(package)
    ]

    totalErrorCount = 0
    for package in finalPackageList:
        filteredFiles = None if customPackageFileFilter is None else customPackageFileFilter.TryLocateFilePatternInPackage(
            log, package, extensionList)
        if customPackageFileFilter is None or filteredFiles is not None:
            totalErrorCount += __ScanFiles(log, package, filteredFiles,
                                           repairEnabled,
                                           thirdpartyExceptionDir, checkType,
                                           disableWrite)

    if totalErrorCount > 0 and not repairEnabled:
        log.DoPrint(
            "BEWARE: If you have made a backup of your files you can try to auto correct the errors with '--Repair' but do so at your own peril"
        )
示例#19
0
    def __FilterNotUserRequested(log: Log, sourcePackageBuildOrder: List[PreResolvePackageResult],
                                 requestedPackages: Optional[List[PreResolvePackageResult]]) -> List[PreResolvePackageResult]:
        if requestedPackages is None or len(requestedPackages) <= 0:
            return sourcePackageBuildOrder

        userRequestedPackageNameSet = set()
        for preResolvePackageResult in requestedPackages:
            package = preResolvePackageResult.SourcePackage
            if not package.NameInfo.FullName in userRequestedPackageNameSet:
                userRequestedPackageNameSet.add(package.NameInfo.FullName)
                for depPreResolvePackageResult in preResolvePackageResult.ResolvedBuildOrder:
                    if not depPreResolvePackageResult.SourcePackage.NameInfo.FullName in userRequestedPackageNameSet:
                        userRequestedPackageNameSet.add(depPreResolvePackageResult.SourcePackage.NameInfo.FullName)

        # This one liner
        #    return [entry for entry in sourcePackageBuildOrder if entry.SourcePackage.NameInfo.FullName in userRequestedPackageNameSet]
        # Was expanded because we need to log information

        logResult = log.Verbosity > 2
        result = []
        for entry in sourcePackageBuildOrder:
            if entry.SourcePackage.NameInfo.FullName in userRequestedPackageNameSet:
                result.append(entry)
            elif logResult:
                log.LogPrint("- {0} (Removed because it was not requested by the user)".format(entry.SourcePackage.NameInfo.FullName))
        return result
示例#20
0
    def ShowRecipeList(log: Log, topLevelPackage: Package,
                       requestedFiles: Optional[List[str]]) -> None:
        #requestedPackages = PackageUtil.GetPackageListFromFilenames(topLevelPackage, requestedFiles, True)

        recipeBuildOrder = topLevelPackage.ResolvedExperimentalRecipeBuildOrder
        if recipeBuildOrder is None or len(recipeBuildOrder) <= 0:
            log.LogPrint("No recipes found")
            return

        recipePackages = list(
            topLevelPackage.ResolvedExperimentalRecipeBuildOrder)
        recipePackages.sort(
            key=lambda s: s.ResolvedDirectExperimentalRecipe.FullName.lower()
            if s.ResolvedDirectExperimentalRecipe is not None else s.Name.
            lower())
        strAddIndent = "  "
        print("Recipes")
        for package in recipePackages:
            packageRecipe = package.ResolvedDirectExperimentalRecipe
            if packageRecipe is not None and packageRecipe.Type != RecipeType.External:
                print("{0}{1} (introduced by: {2}), type: {3}".format(
                    strAddIndent, packageRecipe.FullName, package.Name,
                    RecipeType.ToString(packageRecipe.Type)))

        print("External")
        for package in recipePackages:
            packageRecipe = package.ResolvedDirectExperimentalRecipe
            if packageRecipe is not None and packageRecipe.Type == RecipeType.External:
                print("{0}{1} (introduced by: {2})".format(
                    strAddIndent, packageRecipe.FullName, package.Name))
示例#21
0
    def GenerateNinjaTidyFile(log: Log, toolConfig: ToolConfig, ninjaOutputFile: str, outputFolder: str, toolVersionOutputFile: str,
                              clangFormatExeInfo: ClangExeInfo, customPackageFileFilter: Optional[CustomPackageFileFilter],
                              clangFormatConfiguration: ClangFormatConfiguration, sortedPackageList: List[Package], repairEnabled: bool) -> int:
        totalProcessedCount = 0
        toolProjectContextsDict = PackagePathUtil.CreateToolProjectContextsDict(toolConfig.ProjectInfo)
        with io.StringIO() as ninjaFile:
            ninjaFile.writelines("ninja_required_version = 1.8\n")

            writer = Writer(ninjaFile, 149)

            formatCommand = "{0} $in --style=file".format(clangFormatExeInfo.Command)
            if repairEnabled:
                formatCommand += " -i"
            if len(clangFormatConfiguration.AdditionalUserArguments) > 0:
                log.LogPrint("Adding user supplied arguments before '--' {0}".format(clangFormatConfiguration.AdditionalUserArguments))
                formatCommand += " {0}".format(" ".join(clangFormatConfiguration.AdditionalUserArguments))

            writer.rule(name=PerformClangFormatHelper2.RULE_FORMAT,
                        command=formatCommand,
                        restat=True)

            for package in sortedPackageList:
                PerformClangFormatHelper2.AddPackage(log, toolConfig, toolVersionOutputFile, writer, package, outputFolder, toolProjectContextsDict,
                                                     customPackageFileFilter, clangFormatConfiguration)
                totalProcessedCount += 1

            # finally we write the ninja file
            IOUtil.WriteFileIfChanged(ninjaOutputFile, ninjaFile.getvalue())
            writer.close()
        return totalProcessedCount
    def Process(log: Log, toolConfig: ToolConfig,
                customPackageFileFilter: Optional[CustomPackageFileFilter],
                clangFormatConfiguration: ClangFormatConfiguration,
                clangExeInfo: ClangExeInfo, packageList: List[Package],
                repairEnabled: bool, buildThreads: int) -> int:
        totalProcessedCount = 0
        if buildThreads <= 1 or len(packageList) <= 1:
            for package in packageList:
                filteredFiles = None if customPackageFileFilter is None else customPackageFileFilter.TryLocateFilePatternInPackage(
                    log, package, clangFormatConfiguration.FileExtensions)
                if customPackageFileFilter is None or filteredFiles is not None:
                    totalProcessedCount += 1
                    log.LogPrint("- {0}".format(package.Name))
                    _RunClangFormat(log, toolConfig, clangFormatConfiguration,
                                    clangExeInfo, package, filteredFiles,
                                    repairEnabled)
        else:
            # Do some threading magic. We can do this because each package touches separate files
            packageQueue = queue.Queue(len(packageList))  # type: Any
            for package in packageList:
                packageQueue.put(package)

            # Ensure we dont start threads we dont need
            finalBuildThreads = buildThreads if len(
                packageList) >= buildThreads else len(packageList)
            exceptionList = []
            cancellationToken = SimpleCancellationToken()
            totalExaminedCount = 0
            try:
                with ThreadPoolExecutor(
                        max_workers=finalBuildThreads) as executor:

                    futures = []
                    for index in range(0, buildThreads):
                        taskFuture = executor.submit(
                            PerformClangFormatHelper.RunInAnotherThread,
                            packageQueue, cancellationToken, log, toolConfig,
                            customPackageFileFilter, clangFormatConfiguration,
                            clangExeInfo, repairEnabled)
                        futures.append(taskFuture)
                    # Wait for all futures to finish
                    for future in futures:
                        try:
                            examinedCount, processedCount = future.result()
                            totalExaminedCount += examinedCount
                            totalProcessedCount += processedCount
                        except Exception as ex:
                            cancellationToken.Cancel()
                            exceptionList.append(ex)
            finally:
                cancellationToken.Cancel()

            if len(exceptionList) > 0:
                raise AggregateException(exceptionList)

            if totalExaminedCount != len(packageList):
                raise Exception(
                    "internal error: we did not process the expected amount of packages Expected: {0} processed {1}"
                    .format(len(packageList), totalExaminedCount))
        return totalProcessedCount
示例#23
0
    def __AppendMakeThreads(log: Log, rBuildCommandList: List[str], buildThreads: int) -> None:
        if buildThreads == BuildThreads.Auto:
             buildThreads = multiprocessing.cpu_count()

        if buildThreads != BuildThreads.NotDefined and buildThreads > 0:
            log.LogPrint("Builder using BuildThreads: {0}".format(buildThreads))
            rBuildCommandList += ['-j', str(buildThreads)]
    def TryLoadBuildInformation(log: Log, sourcePackage: Package,
                                path: str) -> Optional[JsonDictType]:
        try:
            if not PackageRecipeUtil.HasBuildPipeline(sourcePackage):
                return None

            sourceRecipe = sourcePackage.ResolvedDirectExperimentalRecipe
            if sourceRecipe is None or sourceRecipe.ResolvedInstallLocation is None:
                raise Exception("Invalid recipe")

            # Generally this should not be called if there is no pipeline

            srcFilePath = IOUtil.Join(
                sourceRecipe.ResolvedInstallLocation.ResolvedPath, path)

            fileContent = IOUtil.TryReadFile(srcFilePath)
            if fileContent is None:
                log.LogPrint(
                    "Package build information for package {0} not found in the expected file '{1}'"
                    .format(sourcePackage.Name, srcFilePath))
                return None

            jsonBuildInfoDict = json.loads(fileContent)
            if not BuildInfoFile.IsDictValid(jsonBuildInfoDict):
                log.LogPrint(
                    "Package build information for package {0} found in file '{1}' is invalid"
                    .format(sourcePackage.Name, srcFilePath))
                return None

            # Decode the complex element to a object of the right type
            jsonBuildInfoDict[
                BuildInfoFileElements.
                ContentState] = BuildInfoComplexJsonDecoder.DecodeJson(
                    jsonBuildInfoDict[BuildInfoFileElements.ContentState])
            if BuildInfoFileElements.SourceState in jsonBuildInfoDict:
                jsonBuildInfoDict[
                    BuildInfoFileElements.
                    SourceState] = BuildInfoComplexJsonDecoder.DecodeJson(
                        jsonBuildInfoDict[BuildInfoFileElements.SourceState])

            return cast(JsonDictType, jsonBuildInfoDict)
        except Exception as ex:
            log.LogPrintWarning(
                "TryLoadBuildInformation failed for package '{0}' with {1}".
                format(sourcePackage.Name, ex))
            return None
def __ValidateIncludeGuard(log: Log, sourceFile: SourceFile, shortFile: str, repairEnabled: bool) -> bool:
    if len(sourceFile.LinesModded) < 2:
        return False

    currentLine0 = sourceFile.LinesModded[0].strip()
    currentLine1 = sourceFile.LinesModded[1].strip()

    guard = __GenerateIncludeGuardName(sourceFile.Package, shortFile)
    line0Valid = "#ifndef %s" % (guard)
    line1Valid = "#define %s" % (guard)
    if currentLine0 == line0Valid and currentLine1 == line1Valid:
        return True

    # check that the file starts with the guard statements
    prefix0 = "#ifndef "
    prefix1 = "#define "
    if not currentLine0.startswith(prefix0):
        log.DoPrint("Line 0 does not start with '%s' in '%s'" % (prefix0, os.path.normpath(sourceFile.FileName)))
        if repairEnabled:
            log.LogPrint("Because of this repair was not attempted.")
        return False
    if not currentLine1.startswith(prefix1):
        log.DoPrint("Line 1 does not start with '%s' in '%s'" % (prefix1, os.path.normpath(sourceFile.FileName)))
        if repairEnabled:
            log.LogPrint("Because of this repair was not attempted.")
        return False

    # validate that the #ifndef and define works on the same string
    userDef0 = currentLine0[len(prefix0):].strip()
    userDef1 = currentLine1[len(prefix1):].strip()
    if userDef0 != userDef1:
        log.DoPrint("The include guards do not appear to match '%s' != '%s' in '%s'" % (userDef0, userDef1, os.path.normpath(sourceFile.FileName)))
        log.LogPrint("- Line 0 '%s'" % (userDef0))
        log.LogPrint("- Line 1 '%s'" % (userDef1))
        if repairEnabled:
            log.LogPrint("Because of this repair was not attempted.")
        return False

    # So we should be sure that the guard is just the incorrect name, so list it
    log.DoPrint("Wrong include guard: '%s' expected '%s'" % (os.path.normpath(sourceFile.FileName), guard))
    if currentLine0 != line0Valid:
        log.LogPrint("- Expected '%s'" % (line0Valid))
        log.LogPrint("- Was      '%s'" % (currentLine0))
    elif currentLine1 != line1Valid:
        log.LogPrint("- Expected '%s'" % (line1Valid))
        log.LogPrint("- Was      '%s'" % (currentLine1))

    if not repairEnabled:
        return False

    log.DoPrint("Include guard corrected")

    # We are allowed to repair the content, so lets do that
    sourceFile.LinesModded[0] = line0Valid
    sourceFile.LinesModded[1] = line1Valid
    return False
示例#26
0
 def AddBuildThreads(log: Log, rArgumentList: List[str], generatorOriginalName: str, buildThreads: int, external: bool = False) -> None:
     platformName = generatorOriginalName
     if (platformName == PlatformNameString.QNX or
         platformName == PlatformNameString.YOCTO or
         platformName == PlatformNameString.UBUNTU or
         (external and platformName == PlatformNameString.ANDROID)):
         PlatformBuildUtil.__AppendMakeThreads(log, rArgumentList, buildThreads)
     elif platformName == PlatformNameString.WINDOWS:
         if buildThreads == BuildThreads.Auto:
             log.LogPrint("Builder using BuildThreads: auto")
             rArgumentList += ['/maxcpucount']
         elif buildThreads != BuildThreads.NotDefined and buildThreads > 0:
             log.LogPrint("Builder using BuildThreads: {0}".format(buildThreads))
             rArgumentList += ['/maxcpucount:{0}'.format(buildThreads)]
     else:
         if buildThreads != BuildThreads.NotDefined:
             log.LogPrintWarning("The builder ignored 'BuildThreads'")
示例#27
0
    def Run(log: Log, createInfo: OpenProjectCreateInfo) -> None:
        log.LogPrintVerbose(
            1, "Configuring and launching Visual Studio Code for path '{0}'".
            format(createInfo.SourcePath))

        buildPlatformType = PlatformUtil.DetectBuildPlatformType()

        vsCodeConfigPath = IOUtil.Join(createInfo.SourcePath, ".vscode")
        launchFilePath = IOUtil.Join(vsCodeConfigPath, "launch.json")
        settingsFilePath = IOUtil.Join(vsCodeConfigPath, "settings.json")

        IOUtil.SafeMakeDirs(vsCodeConfigPath)

        log.LogPrintVerbose(
            1, "- Patching settings at '{0}'".format(settingsFilePath))
        log.PushIndent()
        try:
            VSCodeSettingsJsonUtil.Patch(log, settingsFilePath,
                                         createInfo.CMakeInfo)
        finally:
            log.PopIndent()

        exeInfo = createInfo.ExeInfo
        if exeInfo is not None:
            if log.Verbosity >= 1:
                log.LogPrint("- Patching launch settings at '{0}'".format(
                    launchFilePath))
                log.LogPrint("  - Exe: '{0}'".format(exeInfo.Executable))
                log.LogPrint("  - Cwd: '{0}'".format(
                    exeInfo.CurrentWorkingDirectory))
            if not VSCodeLaunchJsonUtil.TryPatch(
                    launchFilePath, buildPlatformType, exeInfo.Executable,
                    exeInfo.CurrentWorkingDirectory):
                log.LogPrintVerbose(
                    1, "WARNING Failed to patch launch file '{0}'".format(
                        launchFilePath))
        else:
            log.LogPrintVerbose(1, "- Launch: No executable information found")

        log.PushIndent()
        try:
            OpenProjectUtil.__RunVSCode(log, buildPlatformType,
                                        createInfo.SourcePath)
        finally:
            log.PopIndent()
示例#28
0
 def LogVariantSettings(log: Log, variantSettingsDict: Dict[str, str]) -> None:
     if len(variantSettingsDict) <= 0:
         return
     names = list(variantSettingsDict.keys())
     names.sort()
     result = []
     for name in names:
         result.append("{0}={1}".format(name, variantSettingsDict[name]))
     log.LogPrint("Variant settings: {0}".format(", ".join(result)))
示例#29
0
    def __Load(self, log: Log, path: str) -> None:
        if not os.path.exists(path):
            return
        content = IOUtil.ReadFile(path)

        self.Dirs = {}
        self.Entries = {}
        self.Removed = {}
        self.IsNew = True
        cacheHeader = GetCacheHeader()
        # if the file starts with a invalid header, we ignore it
        if not content.startswith(cacheHeader):
            log.LogPrint("Cache header invalid, ignoring cache")
            return

        entries = []  # type: List[ContentState]
        dirs = []
        lines = content.splitlines(False)
        if len(lines) < 3:
            log.LogPrintWarning("Cache at '{0}' is invalid, ignoring it.".format(path))
            return
        for line in lines:
            line = line.strip()
            if not line.startswith('#'):
                elements = line.split(GLOBAL_SEP)
                if len(elements) != 5:
                    log.LogPrint("Cache entry invalid, ignoring cache")
                    return
                contentState = ContentState()
                contentState.Name = elements[0]
                contentState.Length = int(elements[1])
                contentState.ModifiedDate = elements[2]
                contentState.Checksum = elements[3]
                contentState.TagChecksum = elements[4]
                if contentState.Length >= 0:
                    entries.append(contentState)
                else:
                    dirs.append(contentState)

        for entry in entries:
            self.Add(entry)
        for entry in dirs:
            self.AddDir(entry)
        self.IsNew = False
 def __ScanForTemplates(self, log: Log, path: str) -> List[XmlNewVSProjectTemplateFile]:
     files = IOUtil.GetFilePaths(path, self.TemplateFileName)
     templateList = []  # type: List[XmlNewVSProjectTemplateFile]
     for filename in files:
         template = self.__TryLoadTemplate(log, filename)
         if template is not None:
             templateList.append(template)
         else:
             log.LogPrint("Failed to load template '{0}'".format(filename))
     return templateList