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 __CreateCommandGitClone( self, sourceCommand: XmlRecipePipelineFetchCommandGitClone, srcRootPath: str) -> PipelineCommand: if self.__SourcePackage is None or self.__SourceRecipe is None: raise Exception("Invalid state") readonlyCacheRootDir = self.__PathBuilder.ReadonlyCache_DownloadCacheRootPath if not readonlyCacheRootDir is None: cachePath = IOUtil.Join(readonlyCacheRootDir, self.__SourceRecipe.FullName) if IOUtil.IsDirectory(cachePath): info = PipelineInfo(self.PipelineTasks, self.__SourcePackage, self.__PathBuilder, cachePath, cachePath) return PipelineCommandNOP(self.__Log, sourceCommand, info) if self.__PathBuilder.DownloadCacheRootPath is None: raise Exception("Invalid State") dstPath = IOUtil.Join(self.__PathBuilder.DownloadCacheRootPath, self.__SourceRecipe.FullName) info = PipelineInfo(self.PipelineTasks, self.__SourcePackage, self.__PathBuilder, srcRootPath, dstPath, allowDownloads=self.__AllowDownloads) return PipelineCommandGitClone(self.__Log, sourceCommand, info)
def DoGetFiles(config: Config, toolMiniConfig: ToolMinimalConfig, currentDir: str, allowRecursiveScan: bool = False) -> List[str]: """ :param currentDir: currentDir must be part of a package root :param allowRecursiveScan: if True and not a sdk build all subdirectories will be scanned """ if allowRecursiveScan and config.IsSDKBuild: config.DoPrintWarning("recursive is ignored for sdk builds") if ToolConfigPackageRootUtil.TryFindRootDirectory( toolMiniConfig.RootDirectories, currentDir) is None: raise UsageErrorException( "the folder '{0}' does not reside inside one of the root dirs". format(currentDir)) theFiles = [] # type: List[str] if not config.IsSDKBuild: if allowRecursiveScan: theFiles += IOUtil.FindFileByName(currentDir, config.GenFileName, toolMiniConfig.IgnoreDirectories) else: theFile = IOUtil.Join(currentDir, config.GenFileName) if not os.path.isfile(theFile): raise Exception("File not found: '{0}'".format(theFile)) theFiles.append(theFile) return theFiles
def CreateUserTag(self, baseConfig: BaseConfig) -> Optional[object]: templateRootPaths = GetTemplatePaths(baseConfig.ToolConfig) subDirs = [] # type: List[str] for entry in templateRootPaths: subDirs += IOUtil.GetDirectoriesAt(entry.ResolvedPath, True) templates = {} # type: Dict[str, List[XmlNewTemplateFile]] for currentDir in subDirs: languageDir = IOUtil.GetFileName(currentDir) dirs = IOUtil.GetDirectoriesAt(currentDir, True) for possibleDir in dirs: templatePath = IOUtil.Join(possibleDir, g_templateFileName) if IOUtil.IsFile(templatePath): if not languageDir in templates: templates[languageDir] = [] xmlNewTemplateFile = XmlNewTemplateFile(baseConfig, templatePath) existingTemplateFile = TryFind(templates[languageDir], xmlNewTemplateFile) if existingTemplateFile is None: templates[languageDir].append(xmlNewTemplateFile) else: raise Exception("Duplicated template name '{0}' found at '{1}' and '{2}'".format(xmlNewTemplateFile.Name, xmlNewTemplateFile.Path, existingTemplateFile.Path)) # sort the templates for listEntry in templates.values(): listEntry.sort(key=lambda s: s.Name.lower()) removeKeys = [key for key in templates if len(templates[key]) <= 0] for key in removeKeys: templates.pop(key) return templates
def TryGetBuildExecutableInfo( log: Log, generatorConfig: GeneratorConfig, 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 __DoValidatePath(self, rErrorRecordList: List[ErrorRecord], installationPath: Optional[str], command: XmlRecipeValidateCommandPath) -> Tuple[bool, Optional[str]]: if self.__BasicConfig.Verbosity >= 4: self.__BasicConfig.LogPrint("ValidatePath '{0}'".format(command.Name)) result, path = self.__TryResolvePath(rErrorRecordList, installationPath, command.Name) if not result or path is None: return False, path if self.__BasicConfig.Verbosity >= 4: self.__BasicConfig.LogPrint("Resolving to '{0}'".format(path)) if command.Method == BuildRecipeValidateMethod.IsDirectory: if not IOUtil.IsDirectory(path): rErrorRecordList.append(ErrorRecord(ErrorClassification.Critical, "Path '{0}' resolved to '{1}' which is not a directory.".format(command.Name, path))) return False, path elif command.Method == BuildRecipeValidateMethod.IsFile: if not IOUtil.IsFile(path): fileHelp = self.__GetFailedFileCheckExtraHelpString(path) rErrorRecordList.append(ErrorRecord(ErrorClassification.Critical, "Path '{0}' resolved to '{1}' which is not a file.{2}".format(command.Name, path, fileHelp))) return False, path elif command.Method == BuildRecipeValidateMethod.Exists: if not IOUtil.Exists(path): rErrorRecordList.append(ErrorRecord(ErrorClassification.Critical, "Path '{0}' resolved to '{1}' which is a path that dont exist.".format(command.Name, path))) return False, path else: raise Exception("Unsupported BuildRecipeValidateMethod '{0}'".format(command.Method)) return True, path
def __TryResolvePath(self, rErrorRecordList: List[ErrorRecord], installationPath: Optional[str], sourcePath: str, allowEnvironmentVariable: bool = True) -> Tuple[bool, Optional[str]]: if not allowEnvironmentVariable: if installationPath is None: rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Path '{0}' tried to use a undefined install path. Is the recipe missing a Pipeline section, ExternalInstallDirectory or is the supplied path missing a environment variable to qualify it?".format(sourcePath))) return False, None return True, IOUtil.Join(installationPath, sourcePath) # NOTE: workaround Union of tuples not being iterable bug in mypy https://github.com/python/mypy/issues/1575 tupleResult = self.__VariableProcessor.TrySplitLeadingEnvironmentVariablesNameAndPath(sourcePath) environmentVariableName = tupleResult[0] restPath = tupleResult[1] if environmentVariableName is None: if installationPath is None: rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Path '{0}' tried to use a undefined install path. Is the recipe missing a Pipeline section, ExternalInstallDirectory or is the supplied path missing a environment variable to qualify it?".format(sourcePath))) return False, None return True, IOUtil.Join(installationPath, sourcePath) restPath = restPath if restPath is not None else "" value = os.environ.get(environmentVariableName) if value is None: rErrorRecordList.append(ErrorRecord(ErrorClassification.Environment, "Path '{0}' contained environment variable '{1}' which is not defined.".format(sourcePath, environmentVariableName))) return False, None path = IOUtil.Join(value, restPath) if self.__BasicConfig.Verbosity >= 4: self.__BasicConfig.LogPrint("Path: '{0}' using environment variable '{1}'='{2}' resolving to '{3}'".format(sourcePath, environmentVariableName, value, path)) return True, path
def SaveBuildInformation(log: Log, recipeRecord: Optional[RecipeRecord], recipePackageStateCache: RecipePackageStateCache, path: str) -> None: if recipeRecord is None or not PackageRecipeUtil.HasBuildPipeline( recipeRecord.SourcePackage): return if recipeRecord.SourceRecipe is None or recipeRecord.SourceRecipe.ResolvedInstallLocation is None: return installPath = recipeRecord.SourceRecipe.ResolvedInstallLocation.ResolvedPath jsonRootDict = BuildInfoFile.TryCreateJsonBuildInfoRootDict( log, path, recipeRecord.SourcePackage, recipeRecord.SourceRecipe, recipePackageStateCache) if jsonRootDict is None: return jsonText = json.dumps(jsonRootDict, ensure_ascii=False, sort_keys=True, indent=2, cls=BuildInfoComplexJsonEncoder) dstFilePath = IOUtil.Join(installPath, path) IOUtil.WriteFileIfChanged(dstFilePath, jsonText)
def Process(self, log: Log, configDisableWrite: bool, contentBuildPath: str, contentOutputPath: str, contentFileRecord: PathRecord) -> None: # we ask the tool to write to a temporary file so that we can ensure that the output file is only modified # if the content was changed tmpOutputFileName = self.GetTempFileName(contentBuildPath, contentFileRecord) buildCommand = [self.ToolCommand] buildCommand += self.__GetToolParameterList(tmpOutputFileName, contentFileRecord.ResolvedPath) if configDisableWrite: # if write is disabled we do a "tool-command" check directly since the subprocess call can't fail # which would normally trigger the check self.__ToolFinder.CheckToolCommand(self.ToolCommand, self.ToolDescription) return outputFileName = self.GetOutputFileName(log, contentOutputPath, contentFileRecord) self.EnsureDirectoryExist(configDisableWrite, outputFileName) try: result = subprocess.call(buildCommand, cwd=contentBuildPath) if result != 0: self.__ToolFinder.CheckToolCommand(self.ToolCommand, self.ToolDescription) raise Exception("{0}: Failed to process file '{1}' ({2})".format(self.ToolCommand, contentFileRecord.ResolvedPath, self.ToolDescription)) IOUtil.CopySmallFile(tmpOutputFileName, outputFileName) except: self.__ToolFinder.CheckToolCommand(self.ToolCommand, self.ToolDescription) raise finally: IOUtil.RemoveFile(tmpOutputFileName)
def __ResolvePaths(self, config: Config, filename: str, allowNoInclude: bool) -> None: if not os.path.isabs(filename): raise UsageErrorException() self.AbsolutePath = IOUtil.GetDirectoryName(filename) if not self.IsVirtual: sourcePath = self.BaseSourcePath if self.PackageLanguage == PackageLanguage.CPP: self.__ResolvePathIncludeDir(config, allowNoInclude) elif self.PackageLanguage == PackageLanguage.CSharp: #sourcePath = self.Name pass else: raise UnsupportedException( "Unsupported package language: {0}".format( self.PackageLanguage)) self.AbsoluteSourcePath = IOUtil.Join(self.AbsolutePath, sourcePath) self.AbsoluteContentPath = IOUtil.Join(self.AbsolutePath, "Content") self.AbsoluteContentSourcePath = IOUtil.Join( self.AbsolutePath, "Content.bld") if not os.path.isdir(self.AbsoluteSourcePath ) and not config.DisableSourceDirCheck: raise PackageMissingRequiredSourceDirectoryException( self.AbsoluteSourcePath) elif self.Type == PackageType.HeaderLibrary: if self.PackageLanguage == PackageLanguage.CPP: self.__ResolvePathIncludeDir(config, allowNoInclude) else: raise UsageErrorException( "HeaderLibrary is only supported for C++")
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 __BuildTargetLinkLibrariesForDirectExternalDependencies(log: Log, package: Package, resolvedDirectExternalDependencies: Union[List[PackageExternalDependency], List[PackagePlatformExternalDependency]], ignoreLibs: Optional[List[str]] = None) -> str: if ignoreLibs is None: ignoreLibs = [] isExternalLibrary = package.Type == PackageType.ExternalLibrary deps = "" for entry in resolvedDirectExternalDependencies: libraryName = LibUtil.ToUnixLibName(entry.Name) if libraryName not in ignoreLibs: if entry.Type == ExternalDependencyType.StaticLib or (entry.Type == ExternalDependencyType.DLL and entry.Name.lower().endswith(".so")): location = entry.Location if entry.Location is not None and (entry.IsManaged or not isExternalLibrary) else "" libraryName = libraryName if len(location) <= 0 else entry.Name fullPathLinkDir = Util.ChangeToCMakeEnvVariables(IOUtil.Join(location, libraryName)) if entry.DebugName != entry.Name: deps += "\n {0} optimized {1}".format(GetAccessTypeString(package, entry.Access, False), fullPathLinkDir) libraryName = LibUtil.ToUnixLibName(entry.DebugName) fullPathLinkDir = Util.ChangeToCMakeEnvVariables(IOUtil.Join(location, libraryName)) deps += "\n {0} debug {1}".format(GetAccessTypeString(package, entry.Access, False), fullPathLinkDir) else: deps += "\n {0} {1}".format(GetAccessTypeString(package, entry.Access, False), fullPathLinkDir) if entry.Type == ExternalDependencyType.Find: linkName = "${%s_LIBRARY}" % (libraryName) deps += "\n {0} {1}".format(GetAccessTypeString(package, entry.Access, False), linkName) else: log.LogPrintVerbose(2, "INFO: Force ignored '{0}'".format(libraryName)) return deps
def __DoReadFile(self, absoluteTemplatePath: str, overrideDirName: str, filename: str) -> str: templateFilename = IOUtil.Join(absoluteTemplatePath, "{0}/{1}".format(overrideDirName, filename)) res = IOUtil.TryReadFile(templateFilename) if res is None: templateFilename = IOUtil.Join(absoluteTemplatePath, filename) res = IOUtil.ReadFile(templateFilename) return res
def __init__( self, basicConfig: BasicConfig, basedUponXML: XmlConfigFileAddTemplateImportDirectory) -> None: super(ToolConfigDirectory, self).__init__() self.BasedOn = basedUponXML self.Name = self.BasedOn.Name variableProcessor = VariableProcessor(basicConfig) # NOTE: workaround Union of tuples not being iterable bug in mypy https://github.com/python/mypy/issues/1575 tupleResult = variableProcessor.TrySplitLeadingEnvironmentVariablesNameAndPath( self.Name) envName = tupleResult[0] rest = tupleResult[1] if envName is None: raise Exception( "Template import dirs are expected to contain environment variables" ) self.DecodedName = envName self.BashName = IOUtil.Join('$' + self.DecodedName, rest) self.DosName = IOUtil.Join('%' + self.DecodedName + '%', rest) if self.Name is None: raise XmlException2( basedUponXML.XmlElement, "Dirs are expected to contain environment variables") self.ResolvedPath = IOUtil.Join( IOUtil.GetEnvironmentVariableForDirectory(self.DecodedName), rest) self.ResolvedPathEx = "{0}/".format( self.ResolvedPath) if len(self.ResolvedPath) > 0 else ""
def TryGetInstallPath( self, xmlSourceRecipe: XmlExperimentalRecipe) -> Optional[ResolvedPath]: if xmlSourceRecipe is None: return None elif not xmlSourceRecipe.ExternalInstallDirectory is None: if not xmlSourceRecipe.Pipeline is None: self.__Log.DoPrintWarning( "SourceRecipe ExternalInstallDirectory overrides Pipeline '{0}'" .format(xmlSourceRecipe.Name)) sourcePath = xmlSourceRecipe.ExternalInstallDirectory resolvedPath = self.__VariableProcessor.ResolveAbsolutePathWithLeadingEnvironmentVariablePathAsDir( sourcePath) return ResolvedPath(sourcePath, resolvedPath) if not self.IsEnabled or self.InstallRootLocation is None: raise Exception( "Can not TryGetInstallPath since the builder functionality has been disabled, please enable the builder functionality for this project" ) if xmlSourceRecipe.Pipeline is None: return None sourcePath = IOUtil.Join(self.InstallRootLocation.SourcePath, xmlSourceRecipe.Name) resolvedPath = IOUtil.Join(self.InstallRootLocation.ResolvedPath, xmlSourceRecipe.Name) return ResolvedPath(sourcePath, resolvedPath)
def __GenerateExecutable( self, config: Config, package: Package, platformName: str, template: CMakeGeneratorUtil.CodeTemplateCMake, templateFileRecordManager: TemplateFileRecordManager, templateFileProcessor: TemplateFileProcessor, appPackageTemplateInfo: AndroidGeneratorUtil. AppPackageTemplateInfo, androidProjectDir: str, androidProjectCMakeDir: str, exeFileList: List[str], androidABIList: List[str], cmakePackageRootVariables: str) -> None: # copy files that need to be modified dstFilenameModifier = self.__GetDstFilenameModifier( config, androidProjectDir, package, appPackageTemplateInfo, template, androidProjectCMakeDir, androidABIList, templateFileProcessor, cmakePackageRootVariables) templateFileProcessor.Process(config, templateFileRecordManager, androidProjectDir, package, dstFilenameModifier) if not config.DisableWrite: # mark files as executable for entry in exeFileList: IOUtil.SetFileExecutable(IOUtil.Join(androidProjectDir, entry)) self.__GenerateCMakeFile(config, package, platformName, template, androidProjectDir, androidProjectCMakeDir)
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 __TryAddAsCMakeLib(self, recipe: Optional[PackageExperimentalRecipe], package: Package) -> Optional[AndroidCMakeLib]: if recipe is None or recipe.ResolvedInstallLocation is None or recipe.Pipeline is None: return None if not PackageRecipeUtil.CommandListContainsBuildCMake( recipe.Pipeline.CommandList): return None path = "{0}".format(recipe.ResolvedInstallLocation) staticLibs = [] # type: List[AndroidCMakeLibRecord] if recipe.ValidateInstallation is not None and recipe.ValidateInstallation.CommandList is not None: for command in recipe.ValidateInstallation.CommandList: if command.CommandType == BuildRecipeValidateCommand.AddLib: commandEx = cast(XmlRecipeValidateCommandAddLib, command) libName = LibUtil.ToUnixLibName( IOUtil.GetFileName(commandEx.Name)) libPath = IOUtil.Join(path, "${ANDROID_ABI}") libPath = IOUtil.Join(libPath, commandEx.Name) staticLibs.append(AndroidCMakeLibRecord(libName, libPath)) # elif command.CommandType == BuildRecipeValidateCommand.AddDLL: # dynamicLibs.append(LibUtil.ToUnixLibName(IOUtil.GetFileName(command.Name))) return AndroidCMakeLib(path, staticLibs)
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, templatePath: str) -> None: super().__init__() fileEnvironmentBasedRootVariable = IOUtil.Join( templatePath, "CMakeAndroid/DefineEnvironmentBasedRootVariable.txt") self.DefineEnvironmentBasedRootVariable = IOUtil.ReadFile( fileEnvironmentBasedRootVariable)
def __GenerateBuildScript(self, config: Config, generatorName: str, package: Package, template: str) -> None: strContent = "" for depPackage in package.ResolvedBuildOrder: if not depPackage.IsVirtual: if depPackage.AbsolutePath is None: raise Exception("Invalid package") strContent += "pushd " + config.ToBashPath( depPackage.AbsolutePath) + " > /dev/null\n" strContent += 'make "$@"\n' strContent += "popd > /dev/null\n" strContent += 'make "$@"\n' build = template build = build.replace("##PACKAGE_BUILD_COMMANDS##", strContent) if not config.DisableWrite: if package.AbsolutePath is None or package.ResolvedBuildPath is None: raise Exception("Invalid package") buildPath = IOUtil.Join(package.AbsolutePath, package.ResolvedBuildPath) # create folder structure IOUtil.SafeMakeDirs(buildPath) # This file has been superseded by the 'FslBuild.py' script # so for now we just write it inside the build dir to keep it around if needed #dstFile = IOUtil.Join(package.AbsolutePath, "build.sh") dstFile = IOUtil.Join(buildPath, "build.sh") IOUtil.WriteFileIfChanged(dstFile, build) IOUtil.SetFileExecutable(dstFile)
def __GetDirAndFilePaths(self, directory: str) -> Tuple[List[str], List[str]]: """ This function will generate the file names in a directory tree by walking the tree either top-down or bottom-up. For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames). """ filePaths = [ ] # type: List[str] # List which will store all of the full filepaths. dirPaths = [ ] # type: List[str] # List which will store all of the full dirpaths. # Walk the tree (skipping hidden files and directories). for root, directories, files in os.walk(directory): files = [f for f in files if not f[0] == '.'] directories[:] = [d for d in directories if not d[0] == '.'] for dirname in directories: dirpath = IOUtil.Join(root, dirname) dirPaths.append( IOUtil.ToUnixStylePath(dirpath)) # Add it to the list. for filename in files: filepath = IOUtil.Join(root, filename) filePaths.append( IOUtil.ToUnixStylePath(filepath)) # Add it to the list. return (dirPaths, filePaths)
def _GeneratedFileSet(log: Log, generatorConfig: GeneratorConfig, cmakeConfig: GeneratorCMakeConfig, topLevelPackage: Package) -> Set[str]: """ Generate a list of all build files that will be generated for the given topLevelPackage by this generator """ fileSet = set() # type: Set[str] for toolProjectContext in generatorConfig.ToolConfig.ProjectInfo.Contexts: filename = GeneratorCMake._GetProjectPackageBuildFileName( toolProjectContext.Location) if IOUtil.IsFile(filename): fileSet.add(filename) for depPackage in topLevelPackage.ResolvedAllDependencies: filename = GeneratorCMake._GetPackageBuildFileName( depPackage.Package) if IOUtil.IsFile(filename): fileSet.add(filename) # These should probably be added as "generated config files" # so we can detect if they are missing and use it as another reason to run configure (just as if a build file was modified) # But then again if people delete anything else from the "build" folder things might easily stop working #if dstPackage.Type == PackageType.Executable: # buildPath = GeneratorCMake._GetPackageBuildDir(generatorConfig, cmakeConfig, dstPackage) # fileSet.add(IOUtil.Join(buildPath, ".fsl-build/config_Debug.json")) # fileSet.add(IOUtil.Join(buildPath, ".fsl-build/config_Release.json")) return fileSet
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 TryBuildAndRun(toolAppContext: ToolAppContext, config: Config, package: Package) -> Optional[JsonDictType]: if not package.ResolvedPlatformSupported: return None if package.AbsolutePath is None: raise Exception("Invalid package") workDir = package.AbsolutePath tmpOutputFilename = IOUtil.Join(workDir, 'FslBuildDoc_AppArguments.json') try: # FslBuild.py --ForAllExe "(EXE) --System.Arguments.Save <filename>" toolFlowConfig = ToolFlowBuild.GetDefaultLocalConfig() toolFlowConfig.SetToolAppConfigValues(toolAppContext.ToolAppConfig) toolFlowConfig.ForAllExe = '(EXE) --System.Arguments.Save {0} -h'.format( tmpOutputFilename) buildFlow = ToolFlowBuild.ToolFlowBuild(toolAppContext) buildFlow.Process(workDir, config.ToolConfig, toolFlowConfig) return ReadJsonFile(tmpOutputFilename) except (Exception) as ex: if toolAppContext.LowLevelToolConfig.DebugEnabled: raise config.LogPrint( "Failed to build and run '{0}' due to exception {1}".format( package.Name, ex)) return None finally: IOUtil.RemoveFile(tmpOutputFilename)
def __GetFailedFileCheckExtraHelpString(self, sourcePath: str) -> str: directoryName = IOUtil.GetDirectoryName(sourcePath) if not directoryName or IOUtil.IsDirectory(directoryName): return "" #filename = IOUtil.GetDirectoryName(sourcePath) return " The parent directory '{0}' did not exist either.".format( directoryName)
def GetVersionStringFromSourceProperties(sdkPath: str) -> str: filePath = IOUtil.Join(sdkPath, 'source.properties') content = IOUtil.ReadFile(filePath) searchString = 'Pkg.Revision' index = content.find(searchString) if index < 0: raise Exception( "source.properties at '{0} did not contain the expected '{1}' entry" .format(filePath, searchString)) index += len(searchString) endIndex = content.find('\n', index) endIndex = endIndex if endIndex >= index else len(content) content = content[index:endIndex] content = content.strip() if len(content) <= 0: raise Exception( "Failed to retrieve version from '{0}' entry".format(filePath)) if content[0] != '=': raise Exception( "source.properties at '{0} did not contain the expected '{1}=' entry" .format(filePath, searchString)) content = content[1:len(content)].strip() if not AndroidUtil.IsValidVersionString(content): raise Exception( "Failed to retrieve version from '{0}' entry as was in a unexpected format" .format(filePath)) return content
def __GetToolConfigPath(defaultPath: str) -> str: """ Retrieve the full path of the tool config file """ toolConfigPath = defaultPath if not toolConfigPath: toolConfigPath = IOUtil.GetExecutablePath() toolConfigPath = IOUtil.Join(toolConfigPath, "FslBuildGen.xml") return toolConfigPath
def __init__( self, basicConfig: BasicConfig, basedUponXML: XmlConfigFileAddNewProjectTemplatesRootDirectory ) -> None: super().__init__() self.BasedOn = basedUponXML self.Id = basedUponXML.Id self.Name = basedUponXML.Name self.DynamicName = basedUponXML.Name variableProcessor = VariableProcessor(basicConfig) # NOTE: workaround Union of tuples not being iterable bug in mypy https://github.com/python/mypy/issues/1575 tupleResult = variableProcessor.TryExtractLeadingEnvironmentVariableNameAndPath( self.DynamicName, True) env = tupleResult[0] remainingPath = tupleResult[1] if env is None: raise Exception( "Root dirs are expected to contain environment variables '{0}'" .format(self.DynamicName)) remainingPath = remainingPath if remainingPath is not None else "" resolvedPath = IOUtil.GetEnvironmentVariableForDirectory( env) + remainingPath self.BashName = '${0}{1}'.format(env, remainingPath) self.DosName = '%{0}%{1}'.format(env, remainingPath) self.ResolvedPath = IOUtil.ToUnixStylePath(resolvedPath) self.ResolvedPathEx = "{0}/".format( self.ResolvedPath) if len(self.ResolvedPath) > 0 else "" self.__EnvironmentVariableName = env
def __ResolvePaths(self, configDisableIncludeDirCheck: bool, configDisableSourceDirCheck: bool, packagePath: PackagePath, allowNoInclude: bool) -> None: rootRelativeDirPath = packagePath.RootRelativeDirPath if not self.IsVirtual: sourcePath = self.BaseSourcePath if self.PackageLanguage == PackageLanguage.CPP: self.__ResolvePathIncludeDir(configDisableIncludeDirCheck, allowNoInclude) elif self.PackageLanguage == PackageLanguage.CSharp: #sourcePath = self.Name pass else: raise UnsupportedException("Unsupported package language: {0}".format(self.PackageLanguage)) self.SourcePath = PackagePath(IOUtil.Join(rootRelativeDirPath, sourcePath), packagePath.PackageRootLocation) self.ContentPath = PackagePath(IOUtil.Join(rootRelativeDirPath, ToolSharedValues.CONTENT_FOLDER_NAME), packagePath.PackageRootLocation) self.ContentSourcePath = PackagePath(IOUtil.Join(rootRelativeDirPath, ToolSharedValues.CONTENT_BUILD_FOLDER_NAME), packagePath.PackageRootLocation) if not os.path.isdir(self.SourcePath.AbsoluteDirPath) and not configDisableSourceDirCheck: raise PackageMissingRequiredSourceDirectoryException(self.SourcePath.AbsoluteDirPath) elif self.Type == PackageType.HeaderLibrary: if self.PackageLanguage == PackageLanguage.CPP: self.__ResolvePathIncludeDir(configDisableIncludeDirCheck, allowNoInclude) else: raise UsageErrorException("HeaderLibrary is only supported for C++")