## @file # Target Tool Parser # # Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # from __future__ import print_function import Common.LongFilePathOs as os import sys import traceback from optparse import OptionParser import Common.EdkLogger as EdkLogger import Common.BuildToolError as BuildToolError from Common.DataType import * from Common.BuildVersion import gBUILD_VERSION from Common.LongFilePathSupport import OpenLongFilePath as open from Common.TargetTxtClassObject import gDefaultTargetTxtFile # To Do 1.set clean, 2. add item, if the line is disabled. class TargetTool(): def __init__(self, opt, args): self.WorkSpace = os.path.normpath(os.getenv('WORKSPACE')) self.Opt = opt self.Arg = args[0] self.FileName = os.path.normpath(os.path.join(self.WorkSpace, 'Conf', gDefaultTargetTxtFile)) if os.path.isfile(self.FileName) == False: print("%s does not exist." % self.FileName) sys.exit(1) self.TargetTxtDictionary = { TAB_TAT_DEFINES_ACTIVE_PLATFORM : None, TAB_TAT_DEFINES_TOOL_CHAIN_CONF : None, TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER : None, TAB_TAT_DEFINES_TARGET : None, TAB_TAT_DEFINES_TOOL_CHAIN_TAG : None, TAB_TAT_DEFINES_TARGET_ARCH : None, TAB_TAT_DEFINES_BUILD_RULE_CONF : None, } self.LoadTargetTxtFile(self.FileName) def LoadTargetTxtFile(self, filename): if os.path.exists(filename) and os.path.isfile(filename): return self.ConvertTextFileToDict(filename, '#', '=') else: raise ParseError('LoadTargetTxtFile() : No Target.txt file exists.') return 1 # # Convert a text file to a dictionary # def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter): """Convert a text file to a dictionary of (name:value) pairs.""" try: f = open(FileName, 'r') for Line in f: if Line.startswith(CommentCharacter) or Line.strip() == '': continue LineList = Line.split(KeySplitCharacter, 1) if len(LineList) >= 2: Key = LineList[0].strip() if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary: if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM or Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF \ or Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER \ or Key == TAB_TAT_DEFINES_ACTIVE_MODULE: self.TargetTxtDictionary[Key] = LineList[1].replace('\\', '/').strip() elif Key == TAB_TAT_DEFINES_TARGET or Key == TAB_TAT_DEFINES_TARGET_ARCH \ or Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG or Key == TAB_TAT_DEFINES_BUILD_RULE_CONF: self.TargetTxtDictionary[Key] = LineList[1].split() f.close() return 0 except: last_type, last_value, last_tb = sys.exc_info() traceback.print_exception(last_type, last_value, last_tb) def Print(self): errMsg = '' for Key in self.TargetTxtDictionary: if isinstance(self.TargetTxtDictionary[Key], type([])): print("%-30s = %s" % (Key, ''.join(elem + ' ' for elem in self.TargetTxtDictionary[Key]))) elif self.TargetTxtDictionary[Key] is None: errMsg += " Missing %s configuration information, please use TargetTool to set value!" % Key + os.linesep else: print("%-30s = %s" % (Key, self.TargetTxtDictionary[Key])) if errMsg != '': print(os.linesep + 'Warning:' + os.linesep + errMsg) def RWFile(self, CommentCharacter, KeySplitCharacter, Num): try: fr = open(self.FileName, 'r') fw = open(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), 'w') existKeys = [] for Line in fr: if Line.startswith(CommentCharacter) or Line.strip() == '': fw.write(Line) else: LineList = Line.split(KeySplitCharacter, 1) if len(LineList) >= 2: Key = LineList[0].strip() if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary: if Key not in existKeys: existKeys.append(Key) else: print("Warning: Found duplicate key item in original configuration files!") if Num == 0: Line = "%-30s = \n" % Key else: ret = GetConfigureKeyValue(self, Key) if ret is not None: Line = ret fw.write(Line) for key in self.TargetTxtDictionary: if key not in existKeys: print("Warning: %s does not exist in original configuration file" % key) Line = GetConfigureKeyValue(self, key) if Line is None: Line = "%-30s = " % key fw.write(Line) fr.close() fw.close() os.remove(self.FileName) os.rename(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), self.FileName) except: last_type, last_value, last_tb = sys.exc_info() traceback.print_exception(last_type, last_value, last_tb) def GetConfigureKeyValue(self, Key): Line = None if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM and self.Opt.DSCFILE is not None: dscFullPath = os.path.join(self.WorkSpace, self.Opt.DSCFILE) if os.path.exists(dscFullPath): Line = "%-30s = %s\n" % (Key, self.Opt.DSCFILE) else: EdkLogger.error("TargetTool", BuildToolError.FILE_NOT_FOUND, "DSC file %s does not exist!" % self.Opt.DSCFILE, RaiseError=False) elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF and self.Opt.TOOL_DEFINITION_FILE is not None: tooldefFullPath = os.path.join(self.WorkSpace, self.Opt.TOOL_DEFINITION_FILE) if os.path.exists(tooldefFullPath): Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_DEFINITION_FILE) else: EdkLogger.error("TargetTool", BuildToolError.FILE_NOT_FOUND, "Tooldef file %s does not exist!" % self.Opt.TOOL_DEFINITION_FILE, RaiseError=False) elif self.Opt.NUM >= 2: Line = "%-30s = %s\n" % (Key, 'Enable') elif self.Opt.NUM <= 1: Line = "%-30s = %s\n" % (Key, 'Disable') elif Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER and self.Opt.NUM is not None: Line = "%-30s = %s\n" % (Key, str(self.Opt.NUM)) elif Key == TAB_TAT_DEFINES_TARGET and self.Opt.TARGET is not None: Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET)) elif Key == TAB_TAT_DEFINES_TARGET_ARCH and self.Opt.TARGET_ARCH is not None: Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET_ARCH)) elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG and self.Opt.TOOL_CHAIN_TAG is not None: Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_CHAIN_TAG) elif Key == TAB_TAT_DEFINES_BUILD_RULE_CONF and self.Opt.BUILD_RULE_FILE is not None: buildruleFullPath = os.path.join(self.WorkSpace, self.Opt.BUILD_RULE_FILE) if os.path.exists(buildruleFullPath): Line = "%-30s = %s\n" % (Key, self.Opt.BUILD_RULE_FILE) else: EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND, "Build rule file %s does not exist!" % self.Opt.BUILD_RULE_FILE, RaiseError=False) return Line VersionNumber = ("0.01" + " " + gBUILD_VERSION) __version__ = "%prog Version " + VersionNumber __copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserved." __usage__ = "%prog [options] {args} \ \nArgs: \ \n Clean clean the all default configuration of target.txt. \ \n Print print the all default configuration of target.txt. \ \n Set replace the default configuration with expected value specified by option." gParamCheck = [] def SingleCheckCallback(option, opt_str, value, parser): if option not in gParamCheck: setattr(parser.values, option.dest, value) gParamCheck.append(option) else: parser.error("Option %s only allows one instance in command line!" % option) def RangeCheckCallback(option, opt_str, value, parser): if option not in gParamCheck: gParamCheck.append(option) if value < 1 or value > 8: parser.error("The count of multi-thread is not in valid range of 1 ~ 8.") else: setattr(parser.values, option.dest, value) else: parser.error("Option %s only allows one instance in command line!" % option) def MyOptionParser(): parser = OptionParser(version=__version__, prog="TargetTool.exe", usage=__usage__, description=__copyright__) parser.add_option("-a", "--arch", action="append", dest="TARGET_ARCH", help="ARCHS is one of list: IA32, X64, ARM, AARCH64 or EBC, which replaces target.txt's TARGET_ARCH definition. To specify more archs, please repeat this option. 0 will clear this setting in target.txt and can't combine with other value.") parser.add_option("-p", "--platform", action="callback", type="string", dest="DSCFILE", callback=SingleCheckCallback, help="Specify a DSC file, which replace target.txt's ACTIVE_PLATFORM definition. 0 will clear this setting in target.txt and can't combine with other value.") parser.add_option("-c", "--tooldef", action="callback", type="string", dest="TOOL_DEFINITION_FILE", callback=SingleCheckCallback, help="Specify the WORKSPACE relative path of tool_def.txt file, which replace target.txt's TOOL_CHAIN_CONF definition. 0 will clear this setting in target.txt and can't combine with other value.") parser.add_option("-t", "--target", action="append", type="choice", choices=['DEBUG', 'RELEASE', '0'], dest="TARGET", help="TARGET is one of list: DEBUG, RELEASE, which replaces target.txt's TARGET definition. To specify more TARGET, please repeat this option. 0 will clear this setting in target.txt and can't combine with other value.") parser.add_option("-n", "--tagname", action="callback", type="string", dest="TOOL_CHAIN_TAG", callback=SingleCheckCallback, help="Specify the Tool Chain Tagname, which replaces target.txt's TOOL_CHAIN_TAG definition. 0 will clear this setting in target.txt and can't combine with other value.") parser.add_option("-r", "--buildrule", action="callback", type="string", dest="BUILD_RULE_FILE", callback=SingleCheckCallback, help="Specify the build rule configure file, which replaces target.txt's BUILD_RULE_CONF definition. If not specified, the default value Conf/build_rule.txt will be set.") parser.add_option("-m", "--multithreadnum", action="callback", type="int", dest="NUM", callback=RangeCheckCallback, help="Specify the multi-thread number which replace target.txt's MAX_CONCURRENT_THREAD_NUMBER. If the value is less than 2, MULTIPLE_THREAD will be disabled. If the value is larger than 1, MULTIPLE_THREAD will be enabled.") (opt, args)=parser.parse_args() return (opt, args) if __name__ == '__main__': EdkLogger.Initialize() EdkLogger.SetLevel(EdkLogger.QUIET) if os.getenv('WORKSPACE') is None: print("ERROR: WORKSPACE should be specified or edksetup script should be executed before run TargetTool") sys.exit(1) (opt, args) = MyOptionParser() if len(args) != 1 or (args[0].lower() != 'print' and args[0].lower() != 'clean' and args[0].lower() != 'set'): print("The number of args isn't 1 or the value of args is invalid.") sys.exit(1) if opt.NUM is not None and opt.NUM < 1: print("The MAX_CONCURRENT_THREAD_NUMBER must be larger than 0.") sys.exit(1) if opt.TARGET is not None and len(opt.TARGET) > 1: for elem in opt.TARGET: if elem == '0': print("0 will clear the TARGET setting in target.txt and can't combine with other value.") sys.exit(1) if opt.TARGET_ARCH is not None and len(opt.TARGET_ARCH) > 1: for elem in opt.TARGET_ARCH: if elem == '0': print("0 will clear the TARGET_ARCH setting in target.txt and can't combine with other value.") sys.exit(1) try: FileHandle = TargetTool(opt, args) if FileHandle.Arg.lower() == 'print': FileHandle.Print() sys.exit(0) elif FileHandle.Arg.lower() == 'clean': FileHandle.RWFile('#', '=', 0) else: FileHandle.RWFile('#', '=', 1) except Exception as e: last_type, last_value, last_tb = sys.exc_info() traceback.print_exception(last_type, last_value, last_tb)