def __BuildClangTidyPackageIncludePaths( log: Log, localVariantInfo: LocalVariantInfo, virtualVariantEnvironmentCache: VirtualVariantEnvironmentCache, package: Package) -> List[str]: allIncludeDirs = package.ResolvedBuildAllIncludeDirs if allIncludeDirs is None: raise Exception("Package ResolvedBuildAllIncludeDirs was not resolved") if package.AbsolutePath is None: raise Exception("Package AbsolutePath was was None") variantIncludeDirs = __ExtractVariantIncludeDirs( log, localVariantInfo, virtualVariantEnvironmentCache, package) combinedIncludeDirs = allIncludeDirs + variantIncludeDirs variableDict = StringVariableDict() includeDirCommands = [] for includeDir in combinedIncludeDirs: if not includeDir.startswith("$("): packageIncludeDir = IOUtil.Join(package.AbsolutePath, includeDir) includeDirCommands.append('-I') includeDirCommands.append(IOUtil.NormalizePath(packageIncludeDir)) else: packageIncludeDir = __ResolveVariables( includeDir, variableDict, virtualVariantEnvironmentCache) includeDirCommands.append('-I') includeDirCommands.append(IOUtil.NormalizePath(packageIncludeDir)) return includeDirCommands
def __DoValidateEnvironmentVariable(self, rErrorRecordList: List[ErrorRecord], command: XmlRecipeValidateCommandEnvironmentVariable) -> Tuple[bool, Optional[str]]: value = os.environ.get(command.Name) if not value: rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Environment variable '{0}' is not defined, please define it as required.".format(command.Name))) return False, value if self.__BasicConfig.Verbosity >= 4: self.__BasicConfig.LogPrint("ValidateEnvironmentVariable: '{0}'='{1}'".format(command.Name, value)) if command.Method == BuildRecipeValidateMethod.IsDirectory: if not IOUtil.IsDirectory(value): rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Environment variable '{0}' contained '{1}' which is not a directory.".format(command.Name, value))) return False, value elif command.Method == BuildRecipeValidateMethod.IsFile: if not IOUtil.IsFile(value): fileHelp = self.__GetFailedFileCheckExtraHelpString(value) rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Environment variable '{0}' contained '{1}' which is not a file.{2}".format(command.Name, value, fileHelp))) return False, value elif command.Method == BuildRecipeValidateMethod.Exists: if not IOUtil.Exists(value): rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Environment variable '{0}' contained '{1}' which is a path that dont exist.".format(command.Name, value))) return False, value else: raise Exception("Unsupported BuildRecipeValidateMethod '{0}'".format(command.Method)) if not command.AllowEndSlash and (value.endswith('/') or value.endswith('\\')): rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Environment variable '{0}' content '{1}' can not end with a slash '/' or backslash '\\'.".format(command.Name, value))) return False, value return True, IOUtil.NormalizePath(value)
def __init__(self, basicConfig: BasicConfig, rootDirs: Optional[List[ToolConfigRootDirectory]], basedUponXML: XmlConfigPackageLocation, projectRootDirectory: Optional[str], resolvedPath: Optional[str] = None) -> None: super().__init__() if rootDirs is None or projectRootDirectory is None: if rootDirs is not None or projectRootDirectory is not None: raise Exception( "When rootDirs is none, then the projectRootDirectory must be none" ) # Do some basic validation of the path PathUtil.ValidateIsNormalizedPath(basedUponXML.Name, "Location") self.BasedOn = basedUponXML self.Id = basedUponXML.Id self.Name = basedUponXML.Name if resolvedPath is not None: self.ResolvedPath = IOUtil.NormalizePath(resolvedPath) else: if rootDirs is None or projectRootDirectory is None: raise Exception( "When resolvedPath is None then rootDirs and projectRootDirectory can not be None" ) self.ResolvedPath = self.__ResolvePath(basicConfig, rootDirs, self.Name, projectRootDirectory) self.ResolvedPathEx = "{0}/".format( self.ResolvedPath) if len(self.ResolvedPath) > 0 else "" self.ScanMethod = basedUponXML.ScanMethod
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 __DoBasicPathResolve(self, pathName: str, defaultResult: str, tag: Optional[object] = None) -> str: """ Resolve a path It can start with a environment variable $() or It can start with a variable ${} """ result = None environmentName = self.TryExtractLeadingEnvironmentVariableName( pathName, True, tag) if environmentName is not None: path = IOUtil.GetEnvironmentVariableForDirectory(environmentName) result = pathName.replace("$({0})".format(environmentName), path) else: variableName = self.__TryExtractLeadingVariableName( pathName, True, tag) if variableName is not None: if not variableName in self.Variables.Dict: raise VariableNotDefinedException( variableName, cast(Dict[str, Optional[object]], self.Variables.Dict)) strReplace = "${{{0}}}".format(variableName) result = pathName.replace(strReplace, self.Variables.Dict[variableName]) return IOUtil.NormalizePath( result if result is not None else defaultResult)
def __init__(self, log: Log, xmlElement: ET.Element) -> None: super().__init__(log, xmlElement, "FindFileInPath", BuildRecipeValidateCommand.FindExecutableFileInPath) self.Name = self._ReadAttrib(xmlElement, 'Name') alternatives = self._TryReadAttrib(xmlElement, 'Alternatives') self.ExpectedPath = self._TryReadAttrib(xmlElement, 'ExpectedPath') self.MinVersion = self._TryReadAttrib(xmlElement, 'MinVersion') self.VersionCommand = self._TryReadAttrib(xmlElement, 'VersionCommand') self.VersionRegEx = self._TryReadAttrib(xmlElement, 'VersionRegEx') self.Alternatives = self.__ParseAlternatives(alternatives) if '\\' in self.Name or '/' in self.Name: raise Exception("A filename can not contain backslash '\\' or slash '/': '{0}'".format(self.Name)) if not self.ExpectedPath is None: if '\\' in self.ExpectedPath: raise Exception("A path can not contain backslash '\\': '{0}'".format(self.ExpectedPath)) if self.ExpectedPath.startswith('/'): raise Exception("A path can not start with a slash '/': '{0}'".format(self.ExpectedPath)) if self.ExpectedPath.endswith('/'): raise Exception("A path can not end with a slash '/': '{0}'".format(self.ExpectedPath)) self.ExpectedPath = IOUtil.NormalizePath(self.ExpectedPath) self.__ValidateName() self.__ValidateVersionCheck()
def __GetEnvironmentVariable(self, name: str) -> str: # For cache entries we allow the variable to not be defined, but if it is defned we retrieve is as normal value = IOUtil.TryGetEnvironmentVariable(name) if value is None: raise EnvironmentError( "{0} environment variable not set".format(name)) value = IOUtil.NormalizePath(value) if value is None: raise EnvironmentError( "{0} environment variable not set".format(name)) if not IOUtil.IsAbsolutePath(value): raise EnvironmentError( "{0} environment path '{1}' is not absolute".format( name, value)) if value.endswith("/"): raise EnvironmentError( "{0} environment path '{1}' not allowed to end with '/' or '\'" .format(name, value)) # Create the directory if it didnt exist if not IOUtil.IsDirectory(value) and not IOUtil.Exists(value): self.__Log.LogPrint( "The directory '{0}' did not exist, creating it".format(value)) IOUtil.SafeMakeDirs(value) if not IOUtil.IsDirectory(value): raise EnvironmentError( "The {0} environment variable content '{1}' does not point to a valid directory" .format(name, value)) return value
def __init__(self, filename: str, strPackageName: Optional[str], packageLocation: ToolConfigPackageLocation) -> None: super(PackageFile, self).__init__() if not IOUtil.IsAbsolutePath(filename): raise UsageErrorException() if not isinstance(packageLocation, ToolConfigPackageLocation): raise UsageErrorException() filename = IOUtil.NormalizePath(filename) if not filename.startswith(packageLocation.ResolvedPathEx): raise UsageErrorException( "The filename '{0}' does not belong to the supplied location '{1}'" .format(filename, packageLocation.ResolvedPathEx)) self.Filename = IOUtil.GetFileName(filename) self.RelativeFilePath = filename[ len(packageLocation.ResolvedPathEx ):] # The full relative path to the file self.RelativeDirPath = IOUtil.GetDirectoryName( self.RelativeFilePath) # The relative containing directory self.AbsoluteFilePath = filename # type: str self.AbsoluteDirPath = IOUtil.GetDirectoryName(filename) # type: str self.PackageRootLocation = packageLocation # type: ToolConfigPackageLocation self.PackageName = self.__DeterminePackageNameFromRelativeName( self.RelativeDirPath ) if strPackageName is None else strPackageName # type: str
def __TryFindFileInPath(self, rErrorRecordList: List[ErrorRecord], installationPath: Optional[str], commandFileName: str, commandExpectedPath: Optional[str]) -> Tuple[bool, Optional[str]]: if self.__BasicConfig.Verbosity >= 4: self.__BasicConfig.LogPrint("FindFileInPath: '{0}'".format(commandFileName)) path = IOUtil.TryFindFileInPath(commandFileName) if path is None: rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "File '{0}' could not be found in path.".format(commandFileName))) return False, path if self.__BasicConfig.Verbosity >= 4: self.__BasicConfig.LogPrint("Found at '{0}'".format(path)) path = IOUtil.NormalizePath(path) if commandExpectedPath is not None: result, expectedPath = self.__TryResolvePath(rErrorRecordList, installationPath, commandExpectedPath) if not result or expectedPath is None: return False, path expectedPath = IOUtil.Join(expectedPath, commandFileName) if path != expectedPath: rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "File '{0}' was not found at the expected path '{1}' which resolves to '{2}' but at '{3}' instead".format(commandFileName, commandExpectedPath, expectedPath, path))) if expectedPath.lower() == path.lower(): rErrorRecordList.append(ErrorRecord(ErrorClassification.Help, "Please beware that '{0}'=='{1}' if you ignore character case".format(expectedPath, path))) return False, path return True, path
def __init__(self, log: Log, xmlElement: ET.Element) -> None: super().__init__(log, xmlElement, "FindFileInPath", BuildRecipeValidateCommand.FindFileInPath) self.Name = self._ReadAttrib(xmlElement, 'Name') self.ExpectedPath = self._TryReadAttrib(xmlElement, 'ExpectedPath') if '\\' in self.Name or '/' in self.Name: raise Exception( "A filename can not contain backslash '\\' or slash '/': '{0}'" .format(self.Name)) if not self.ExpectedPath is None: if '\\' in self.ExpectedPath: raise Exception( "A path can not contain backslash '\\': '{0}'".format( self.ExpectedPath)) if self.ExpectedPath.startswith('/'): raise Exception( "A path can not start with a slash '/': '{0}'".format( self.ExpectedPath)) if self.ExpectedPath.endswith('/'): raise Exception( "A path can not end with a slash '/': '{0}'".format( self.ExpectedPath)) self.ExpectedPath = IOUtil.NormalizePath(self.ExpectedPath)
def __CreateToolAppConfig(args: Any, defaultPlatform: str, toolCommonArgConfig: ToolCommonArgConfig, defaultVSVersion: int) -> ToolAppConfig: # Configure the ToolAppConfig part toolAppConfig = ToolAppConfig() toolAppConfig.DefaultPlatformName = defaultPlatform toolAppConfig.AllowDevelopmentPlugins = True if args.dev else False if toolCommonArgConfig.AddPlatformArg: toolAppConfig.PlatformName = args.platform else: toolAppConfig.PlatformName = defaultPlatform if toolCommonArgConfig.ProcessRemainingArgs: toolAppConfig.RemainingArgs = args.RemainingArgs if toolCommonArgConfig.AllowForceClaimInstallArea: toolAppConfig.ForceClaimInstallArea = args.ForceClaimInstallArea toolAppConfig.VSVersion = int(args.VSVersion) if hasattr( args, 'VSVersion') else defaultVSVersion if toolCommonArgConfig.AddBuildFiltering or toolCommonArgConfig.AddUseFeatures: toolAppConfig.BuildPackageFilters.FeatureNameList = ParseUtil.ParseFeatureList( args.UseFeatures) if toolCommonArgConfig.AddBuildFiltering: toolAppConfig.BuildPackageFilters.RequiredFeatureNameList = ParseUtil.ParseFeatureList( args.RequireFeatures) toolAppConfig.BuildPackageFilters.ExtensionNameList = ParseUtil.ParseExtensionList( args.UseExtensions) toolAppConfig.BuildPackageFilters.RecipeFilterManager = ParseUtil.ParseRecipeList( args.Recipes) if toolCommonArgConfig.AddBuildVariants: toolAppConfig.BuildVariantsDict = ParseUtil.ParseVariantDict( args.Variants) if toolCommonArgConfig.AddBuildThreads: toolAppConfig.BuildThreads = BuildThreads.FromString(args.BuildThreads) if toolCommonArgConfig.AllowRecursive: toolAppConfig.Recursive = args.recursive if hasattr(args, 'Generator'): # Convert to the internal value instead of string toolAppConfig.Generator = GeneratorType.FromString(args.Generator) # Handle the CMake parameters if hasattr(args, 'CMakeBuildDir'): toolAppConfig.CMakeBuildDir = None if args.CMakeBuildDir is None else IOUtil.NormalizePath( args.CMakeBuildDir) if hasattr(args, 'CMakeInstallPrefix'): toolAppConfig.CMakeInstallPrefix = None if args.CMakeInstallPrefix is None else IOUtil.NormalizePath( args.CMakeInstallPrefix) if hasattr(args, 'CMakeGeneratorName'): toolAppConfig.CMakeGeneratorName = args.CMakeGeneratorName return toolAppConfig
def __init__(self, log: Log, xmlElement: ET.Element) -> None: super().__init__(log, xmlElement, "AddHeaders", BuildRecipeValidateCommand.AddHeaders) self.Name = self._ReadAttrib(xmlElement, 'Name') if '\\' in self.Name: raise Exception("A path can not contain backslash '\\': '{0}'".format(self.Name)) if self.Name.endswith('/'): raise Exception("A path can not end with a slash '/': '{0}'".format(self.Name)) self.Name = IOUtil.NormalizePath(self.Name)
def __init__(self, packagePath: str, packageRelativeFilePath: str) -> None: packagePath = IOUtil.NormalizePath(packagePath) packageRelativeFilePath = IOUtil.NormalizePath(packageRelativeFilePath) if not IOUtil.IsAbsolutePath(packagePath): raise Exception("packagePath must be absolute") if IOUtil.IsAbsolutePath(packageRelativeFilePath): raise Exception("packageRelativeFilePath can not be absolute") self.Filename = IOUtil.GetFileName(packageRelativeFilePath) absFilePath = IOUtil.Join(packagePath, packageRelativeFilePath) self.AbsoluteFilePath = absFilePath self.AbsoluteDirPath = IOUtil.GetDirectoryName(absFilePath) self.PackageRelativeFilePath = packageRelativeFilePath self.PackageRelativeDirPath = IOUtil.GetDirectoryName( packageRelativeFilePath)
def __ValidateFileExtensions(self, fileExtensions: List[str]) -> None: for fileExt in fileExtensions: normalizedFileExt = IOUtil.NormalizePath(fileExt) directory = IOUtil.GetDirectoryName(normalizedFileExt) if len(directory) > 0: raise Exception("ClangTidyConfiguration: File extension '{0}' can not contain a directory '{1}'".format(fileExt, directory)) if fileExt.startswith(".."): raise Exception("ClangTidyConfiguration: File extension can not start with '..'") if not fileExt.startswith("."): raise Exception("ClangTidyConfiguration: File extension '{0}' does not start with '.'")
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) # Disable downloads and writes if config.ToolConfig.Experimental is not None: config.ToolConfig.Experimental.AllowDownloads = False config.ForceDisableAllWrite() if localToolConfig.IgnoreNotSupported: config.IgnoreNotSupported = True self.Log.PrintTitle() if not localToolConfig.ForceYes and not self.__AskYesNo("Delete all build directories"): return packageFilters = localToolConfig.BuildPackageFilters generator = PluginConfig.GetGeneratorPluginById(localToolConfig.PlatformName, False) theFiles = MainFlow.DoGetFiles(config, toolConfig.GetMinimalConfig(), currentDirPath, localToolConfig.Recursive) generatorContext = GeneratorContext(config, config.ToolConfig.Experimental, generator) packages = MainFlow.DoGetPackages(generatorContext, config, theFiles, packageFilters, autoAddRecipeExternals=False) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) requestedFiles = None if config.IsSDKBuild else theFiles self.Log.LogPrint("Deleting package build directories") for package in topLevelPackage.ResolvedBuildOrder: if package.AbsoluteBuildPath is not None: # While the path is most likely normalized we force it here removePath = IOUtil.NormalizePath(package.AbsoluteBuildPath) if IOUtil.IsDirectory(removePath): self.Log.LogPrint("- Deleting '{0}'".format(removePath)) drive, tail = os.path.splitdrive(removePath) driveId = IOUtil.NormalizePath(drive).lower() removePathId = removePath.lower() # some basic checks to prevent deletes of '/' or a drive letter. if ('../' in removePath or '/..' in removePath or removePath == '/' or removePath == '..' or len(removePath) <= 0 or removePathId==driveId or removePath.endswith('/')): raise Exception("Invalid path format '{0}'".format(removePath)) IOUtil.SafeRemoveDirectoryTree(removePath)
def __init__(self, log: Log, xmlElement: ET.Element) -> None: super().__init__(log, xmlElement, "Path", BuildRecipeValidateCommand.Path) self.Name = self._ReadAttrib(xmlElement, 'Name') method = self._ReadAttrib(xmlElement, 'Method') self.Method = BuildRecipeValidateMethod.FromString(method) if '\\' in self.Name: raise Exception("A path can not contain backslash '\\': '{0}'".format(self.Name)) if self.Name.endswith('/'): raise Exception("A path can not end with a slash '/': '{0}'".format(self.Name)) self.Name = IOUtil.NormalizePath(self.Name)
def ValidateIsNormalizedPath(path: str, pathTypeDesc: str) -> None: if '\\' in path: raise Exception("{0} '{1}' can not contain '\\'".format( pathTypeDesc, path)) if path.endswith('/'): raise Exception("{0} '{1}' can not end with '/'".format( pathTypeDesc, path)) normalizedName = IOUtil.NormalizePath(path) if path != normalizedName: raise Exception( "{0} '{1}' should be a normalized path like '{2}'".format( pathTypeDesc, path, normalizedName))
def __init__(self, userRequestedFNMatchPattern: str) -> None: super().__init__() userRequestedFNMatchPattern = IOUtil.NormalizePath( userRequestedFNMatchPattern) #self.FilterDirPath = IOUtil.NormalizePath(filterDirPath) self.UserRequestedFNMatchPattern = userRequestedFNMatchPattern self.IsAbsolutePattern = IOUtil.IsAbsolutePath( userRequestedFNMatchPattern) self.PatternFileName = IOUtil.GetFileName(userRequestedFNMatchPattern) patternDirectory = IOUtil.GetDirectoryName(userRequestedFNMatchPattern) if not self.IsAbsolutePattern and len( patternDirectory) > 0 and not patternDirectory.startswith('/'): patternDirectory = '/' + patternDirectory self.PatternDirectory = patternDirectory
def ProcessFromCommandLine(self, args: Any, currentDirPath: str, toolConfig: ToolConfig, userTag: Optional[object]) -> None: # Process the input arguments here, before calling the real work function localToolConfig = LocalToolConfig() # Configure the ToolAppConfig part localToolConfig.SetToolAppConfigValues(self.ToolAppContext.ToolAppConfig) # Configure the local part localToolConfig.Output = IOUtil.NormalizePath(args.output) if args.output is not None else None localToolConfig.PackageConfigurationType = args.type localToolConfig.Project = args.project localToolConfig.Validate = args.Validate self.Process(currentDirPath, toolConfig, localToolConfig)
def __ResolvePathIncludeDir(self, config: Config, allowNoInclude: bool) -> None: if self.AbsolutePath is None: raise Exception("AbsolutePath can not be None") self.AbsoluteIncludePath = IOUtil.NormalizePath( IOUtil.Join(self.AbsolutePath, self.BaseIncludePath)) includeDirExist = os.path.isdir(self.AbsoluteIncludePath) if not includeDirExist and ( os.path.exists(self.AbsoluteIncludePath) or not (allowNoInclude or config.DisableIncludeDirCheck)): raise PackageMissingRequiredIncludeDirectoryException( self.AbsoluteIncludePath) if not includeDirExist and allowNoInclude: self.AbsoluteIncludePath = None
def __init__(self, filename: str, strPackageName: Optional[str], packageLocation: ToolConfigPackageLocation) -> None: filename = IOUtil.NormalizePath(filename) if not IOUtil.IsAbsolutePath(filename): raise UsageErrorException() rootRelativePath = filename[len(packageLocation.ResolvedPathEx):] super().__init__(IOUtil.GetDirectoryName(rootRelativePath), packageLocation, False) self.Filename = IOUtil.GetFileName(filename) self.RootRelativeFilePath = rootRelativePath # The full root relative path to the file self.AbsoluteFilePath = filename # type: str self.PackageName = self.__DeterminePackageNameFromRelativeName( self.RootRelativeDirPath ) if strPackageName is None else strPackageName # type: str
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) # Disable downloads and writes if config.ToolConfig.Experimental is not None: config.ToolConfig.Experimental.AllowDownloads = False config.ForceDisableAllWrite() if localToolConfig.IgnoreNotSupported: config.IgnoreNotSupported = True self.Log.PrintTitle() if not localToolConfig.ForceYes and not self.__AskYesNo("Delete all build directories"): return packageFilters = localToolConfig.BuildPackageFilters buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig(localToolConfig.BuildVariantsDict) generator = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById(localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, config.ToolConfig.DefaultPackageLanguage, config.ToolConfig.CMakeConfiguration, localToolConfig.GetUserCMakeConfig(), False) theFiles = MainFlow.DoGetFiles(config, toolConfig.GetMinimalConfig(generator.CMakeConfig), currentDirPath, localToolConfig.Recursive) generatorContext = GeneratorContext(config, self.ErrorHelpManager, packageFilters.RecipeFilterManager, config.ToolConfig.Experimental, generator) packages = MainFlow.DoGetPackages(generatorContext, config, theFiles, packageFilters, autoAddRecipeExternals=False) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) #requestedFiles = None if config.IsSDKBuild else theFiles self.Log.LogPrint("Deleting package build directories") for package in topLevelPackage.ResolvedBuildOrder: if package.AbsoluteBuildPath is not None: # While the path is most likely normalized we force it here removePath = IOUtil.NormalizePath(package.AbsoluteBuildPath) if IOUtil.IsDirectory(removePath): self.Log.LogPrint("- Deleting '{0}'".format(removePath)) if IOUtil.IsDriveRootPath(removePath): raise Exception("Invalid path format '{0}'".format(removePath)) IOUtil.SafeRemoveDirectoryTree(removePath)
def __init__(self, path: str, packageLocation: ToolConfigPackageLocation, normalize: bool = True) -> None: super().__init__() path = IOUtil.NormalizePath(path) if normalize else path if not isinstance(packageLocation, ToolConfigPackageLocation): raise UsageErrorException() if IOUtil.IsAbsolutePath(path): if not path.startswith(packageLocation.ResolvedPathEx): raise UsageErrorException("The path '{0}' does not belong to the supplied location '{1}'".format(path, packageLocation.ResolvedPathEx)) rootRelativeDirPath = path[len(packageLocation.ResolvedPathEx):] absoluteDirPath = path else: rootRelativeDirPath = path absoluteDirPath = IOUtil.Join(packageLocation.ResolvedPath, path) self.RootRelativeDirPath = rootRelativeDirPath # The root relative containing directory self.AbsoluteDirPath = absoluteDirPath # type: str self.PackageRootLocation = packageLocation # type: ToolConfigPackageLocation
def __EarlyArgumentParser( allowStandaloneMode: bool) -> Optional[LowLevelToolConfig]: ### Parse the initial options this allows us to use the required debug and verbosity levels while ### creating the actual command line argumnets. debugEnabled = False try: parser = argparse.ArgumentParser(add_help=False) __AddDefaultOptions(parser, allowStandaloneMode) args, unknown = parser.parse_known_args() verbosityLevel = args.verbosity debugEnabled = True if args.debug else False allowDevelopmentPlugins = True if args.dev else False profilerEnabled = True if args.profile else False standaloneEnabled = False if not allowStandaloneMode else ( True if args.standalone else False) currentDir = IOUtil.NormalizePath( args.input) if args.input is not None else None if currentDir is None: currentDir = IOUtil.GetCurrentWorkingDirectory() elif not IOUtil.IsDirectory(currentDir): raise Exception( "Path '{0}' specified by --input is not a directory".format( currentDir)) elif verbosityLevel > 4: print("Using custom path from --input '{0}'".format(currentDir)) if args.version: print("V{0} Build {1}".format(CurrentVersionString, CurrentBuildString)) return LowLevelToolConfig(verbosityLevel, debugEnabled, allowDevelopmentPlugins, profilerEnabled, standaloneEnabled, currentDir) except (Exception) as ex: print("ERROR: {0}".format(str(ex))) if not debugEnabled: return None raise
def __init__(self, jsonDict: JsonDictType) -> None: super(BuildAreaInfoFile, self).__init__() self.FileFormatVersion = jsonDict[ BuildAreaInfoFileElements.FileFormatVersion] self.SDKPath = IOUtil.NormalizePath( jsonDict[BuildAreaInfoFileElements.SDKPath])
def __init__(self, sourceRootPath: str, relativePath: str) -> None: self.RootDirPath = IOUtil.NormalizePath(sourceRootPath) self.RelativeDirPath = IOUtil.NormalizePath(relativePath) self.AbsoluteDirPath = IOUtil.Join(sourceRootPath, relativePath)
def Process(self, currentDirPath: str, toolConfig: ToolConfig, localToolConfig: LocalToolConfig) -> None: #self.Log.LogPrintVerbose(2, "*** Forcing the legacy clang tidy mode ***") #localToolConfig.Legacy = True config = Config(self.Log, toolConfig, localToolConfig.PackageConfigurationType, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) # create a config we control and that can be used to just build the tool recipe's configToolCheck = Config(self.Log, toolConfig, PluginSharedValues.TYPE_DEFAULT, localToolConfig.BuildVariantsDict, localToolConfig.AllowDevelopmentPlugins) if localToolConfig.DryRun: config.ForceDisableAllWrite() configToolCheck.ForceDisableAllWrite() self.__CheckUserArgs(localToolConfig.ClangFormatArgs, "formatArgs") self.__CheckUserArgs(localToolConfig.ClangTidyArgs, "tidyArgs") self.__CheckUserArgs(localToolConfig.ClangTidyPostfixArgs, "tidyPostfixArgs") applyClangFormat = toolConfig.ClangFormatConfiguration is not None and localToolConfig.ClangFormat applyClangTidy = toolConfig.ClangTidyConfiguration is not None and localToolConfig.ClangTidy if localToolConfig.IgnoreNotSupported or ( (localToolConfig.ScanSource or applyClangFormat) and not applyClangTidy): config.IgnoreNotSupported = True configToolCheck.IgnoreNotSupported = True packageFilters = localToolConfig.BuildPackageFilters # Get the platform and see if its supported buildVariantConfig = BuildVariantConfigUtil.GetBuildVariantConfig( localToolConfig.BuildVariantsDict) if localToolConfig.Legacy and applyClangTidy and config.ToolConfig.CMakeConfiguration is not None: # For the LEGACY clangTidy implementation we disable allow find package for the build checks for now as we dont use cmake for those # We basically have to update the tidy pass to utilize ninja+cmake for the tidy pass so that find_package will work self.Log.LogPrintVerbose(2, "Force disabling 'AllowFindPackage'") config.ToolConfig.CMakeConfiguration.SetAllowFindPackage(False) cmakeUserConfig = localToolConfig.GetUserCMakeConfig() if not localToolConfig.Legacy and applyClangTidy: config.LogPrintVerbose( 2, "Forcing the ninja generator for clang tidy") cmakeUserConfig.GeneratorName = "Ninja" generator = self.ToolAppContext.PluginConfigContext.GetGeneratorPluginById( localToolConfig.PlatformName, localToolConfig.Generator, buildVariantConfig, config.ToolConfig.DefaultPackageLanguage, config.ToolConfig.CMakeConfiguration, cmakeUserConfig, True) PlatformUtil.CheckBuildPlatform(generator.PlatformName) generatorContext = GeneratorContext(config, self.ErrorHelpManager, packageFilters.RecipeFilterManager, config.ToolConfig.Experimental, generator) self.Log.LogPrint("Active platform: {0}".format( generator.PlatformName)) packageRecipeResultManager = None # type: Optional[PackageRecipeResultManager] toolPackageNamesSet = set() toolPackageNames = [] if applyClangFormat or applyClangTidy: if applyClangFormat: if toolConfig.ClangFormatConfiguration is None: raise Exception("internal error") toolPackageNamesSet.add( toolConfig.ClangFormatConfiguration.RecipePackageName) toolPackageNamesSet.add( toolConfig.ClangFormatConfiguration.NinjaRecipePackageName) if applyClangTidy: if toolConfig.ClangTidyConfiguration is None: raise Exception("internal error") toolPackageNamesSet.add( toolConfig.ClangTidyConfiguration.ClangRecipePackageName) toolPackageNamesSet.add(toolConfig.ClangTidyConfiguration. ClangTidyRecipePackageName) toolPackageNamesSet.add( toolConfig.ClangTidyConfiguration.NinjaRecipePackageName) toolPackageNames = list(toolPackageNamesSet) packageRecipeResultManager = ForceCheckBuildTools( configToolCheck, generatorContext, toolPackageNames) searchDir = currentDirPath if localToolConfig.File is not None: localToolConfig.File = IOUtil.NormalizePath(localToolConfig.File) if IOUtil.IsAbsolutePath(localToolConfig.File): searchDir = IOUtil.GetDirectoryName(localToolConfig.File) closestGenFilePath = FileFinder.TryFindClosestFileInRoot( config, toolConfig, searchDir, config.GenFileName) if closestGenFilePath is None: closestGenFilePath = searchDir if self.Log.Verbosity >= 4: self.Log.LogPrint("Closest '{0}' file path: '{1}'".format( toolConfig.GenFileName, closestGenFilePath)) packageProcess = None # type: Optional[MainFlow.PackageLoadAndResolveProcess] packages = None discoverFeatureList = '*' in packageFilters.FeatureNameList if discoverFeatureList or localToolConfig.Project is None or localToolConfig.ScanSource or applyClangFormat or applyClangTidy: if discoverFeatureList: config.LogPrint( "No features specified, so using package to determine them" ) if localToolConfig.ScanSource or applyClangFormat or applyClangTidy or discoverFeatureList: packageProcess = self.__CreatePackageProcess( config, toolConfig.GetMinimalConfig(generator.CMakeConfig), closestGenFilePath, localToolConfig.Recursive, generatorContext.Platform, toolPackageNames) packageProcess.Resolve(generatorContext, packageFilters, applyClangTidy, False) packages = packageProcess.Packages topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) if discoverFeatureList: packageFilters.FeatureNameList = [ entry.Name for entry in topLevelPackage.ResolvedAllUsedFeatures ] customPackageFileFilter = None # type: Optional[CustomPackageFileFilter] if not localToolConfig.ScanSource and not applyClangFormat and not applyClangTidy: Validate.ValidatePlatform(config, localToolConfig.PlatformName, packageFilters.FeatureNameList) if packageProcess is None: packageProcess = self.__CreatePackageProcess( config, toolConfig.GetMinimalConfig(generator.CMakeConfig), closestGenFilePath, localToolConfig.Recursive, generatorContext.Platform, toolPackageNames) if not packageProcess.IsFullResolve or packages is None: # For now this requires a full resolve (but basically it only requires basic + files) packages = packageProcess.Resolve(generatorContext, packageFilters, applyClangTidy, True) topLevelPackage = PackageListUtil.GetTopLevelPackage(packages) RecipeBuilder.ValidateInstallationForPackages( config, config.SDKPath, generatorContext, topLevelPackage.ResolvedBuildOrder) else: if localToolConfig.File is not None: # Delay extension validation customPackageFileFilter = CustomPackageFileFilter( localToolConfig.File) theTopLevelPackage = None # type: Optional[Package] filteredPackageList = [] # type: List[Package] if applyClangTidy or applyClangFormat or localToolConfig.ScanSource: addExternals = applyClangTidy filteredPackageList, theTopLevelPackage = self.__PreparePackages( self.Log, localToolConfig, packageProcess, generatorContext, packageFilters, addExternals, packages, config.IsSDKBuild, applyClangTidy, config) if len(filteredPackageList) <= 0: self.Log.DoPrint("No supported packages left to process") return if applyClangTidy: self.__ApplyClangTidy(self.Log, toolConfig, localToolConfig, packageRecipeResultManager, theTopLevelPackage, filteredPackageList, generator, config, generatorContext, customPackageFileFilter) if applyClangFormat: self.__ApplyClangFormat(self.Log, toolConfig, localToolConfig, packageRecipeResultManager, filteredPackageList, customPackageFileFilter, generatorContext.CMakeConfig) # Scan source after 'format' to ensure we dont warn about stuff that has been fixed if localToolConfig.ScanSource: self.__ApplyScanSource(self.Log, localToolConfig, config.IsSDKBuild, config.DisableWrite, filteredPackageList, customPackageFileFilter)