]>
Commit | Line | Data |
---|---|---|
97fa0ee9 YL |
1 | ## @file\r |
2 | # Target Tool Parser\r | |
30fdf114 | 3 | #\r |
9eb87141 | 4 | # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r |
30fdf114 | 5 | #\r |
40d841f6 | 6 | # This program and the accompanying materials\r |
30fdf114 LG |
7 | # are licensed and made available under the terms and conditions of the BSD License\r |
8 | # which accompanies this distribution. The full text of the license may be found at\r | |
9 | # http://opensource.org/licenses/bsd-license.php\r | |
10 | #\r | |
11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | #\r | |
14 | \r | |
1ccc4d89 | 15 | from __future__ import print_function\r |
1be2ed90 | 16 | import Common.LongFilePathOs as os\r |
30fdf114 LG |
17 | import sys\r |
18 | import traceback\r | |
19 | from optparse import OptionParser\r | |
20 | \r | |
21 | import Common.EdkLogger as EdkLogger\r | |
22 | import Common.BuildToolError as BuildToolError\r | |
23 | from Common.DataType import *\r | |
b36d134f | 24 | from Common.BuildVersion import gBUILD_VERSION\r |
1be2ed90 | 25 | from Common.LongFilePathSupport import OpenLongFilePath as open\r |
30fdf114 LG |
26 | \r |
27 | # To Do 1.set clean, 2. add item, if the line is disabled.\r | |
28 | \r | |
29 | class TargetTool():\r | |
30 | def __init__(self, opt, args):\r | |
31 | self.WorkSpace = os.path.normpath(os.getenv('WORKSPACE'))\r | |
32 | self.Opt = opt\r | |
33 | self.Arg = args[0]\r | |
34 | self.FileName = os.path.normpath(os.path.join(self.WorkSpace, 'Conf', 'target.txt'))\r | |
35 | if os.path.isfile(self.FileName) == False:\r | |
72443dd2 | 36 | print("%s does not exist." % self.FileName)\r |
30fdf114 LG |
37 | sys.exit(1)\r |
38 | self.TargetTxtDictionary = {\r | |
39 | TAB_TAT_DEFINES_ACTIVE_PLATFORM : None,\r | |
40 | TAB_TAT_DEFINES_TOOL_CHAIN_CONF : None,\r | |
30fdf114 LG |
41 | TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER : None,\r |
42 | TAB_TAT_DEFINES_TARGET : None,\r | |
43 | TAB_TAT_DEFINES_TOOL_CHAIN_TAG : None,\r | |
44 | TAB_TAT_DEFINES_TARGET_ARCH : None,\r | |
45 | TAB_TAT_DEFINES_BUILD_RULE_CONF : None,\r | |
46 | }\r | |
47 | self.LoadTargetTxtFile(self.FileName)\r | |
48 | \r | |
49 | def LoadTargetTxtFile(self, filename):\r | |
50 | if os.path.exists(filename) and os.path.isfile(filename):\r | |
08dd311f | 51 | return self.ConvertTextFileToDict(filename, '#', '=')\r |
30fdf114 LG |
52 | else:\r |
53 | raise ParseError('LoadTargetTxtFile() : No Target.txt file exists.')\r | |
54 | return 1\r | |
55 | \r | |
56 | #\r | |
57 | # Convert a text file to a dictionary\r | |
58 | #\r | |
59 | def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter):\r | |
60 | """Convert a text file to a dictionary of (name:value) pairs."""\r | |
61 | try:\r | |
ccaa7754 | 62 | f = open(FileName, 'r')\r |
30fdf114 LG |
63 | for Line in f:\r |
64 | if Line.startswith(CommentCharacter) or Line.strip() == '':\r | |
65 | continue\r | |
ccaa7754 | 66 | LineList = Line.split(KeySplitCharacter, 1)\r |
30fdf114 LG |
67 | if len(LineList) >= 2:\r |
68 | Key = LineList[0].strip()\r | |
9eb87141 | 69 | if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary:\r |
30fdf114 | 70 | if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM or Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF \\r |
08dd311f | 71 | or Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER \\r |
30fdf114 LG |
72 | or Key == TAB_TAT_DEFINES_ACTIVE_MODULE:\r |
73 | self.TargetTxtDictionary[Key] = LineList[1].replace('\\', '/').strip()\r | |
74 | elif Key == TAB_TAT_DEFINES_TARGET or Key == TAB_TAT_DEFINES_TARGET_ARCH \\r | |
75 | or Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG or Key == TAB_TAT_DEFINES_BUILD_RULE_CONF:\r | |
76 | self.TargetTxtDictionary[Key] = LineList[1].split()\r | |
77 | f.close()\r | |
78 | return 0\r | |
79 | except:\r | |
80 | last_type, last_value, last_tb = sys.exc_info()\r | |
81 | traceback.print_exception(last_type, last_value, last_tb)\r | |
82 | \r | |
83 | def Print(self):\r | |
30fdf114 | 84 | errMsg = ''\r |
98120f5f | 85 | for Key in self.TargetTxtDictionary:\r |
0d1f5b2b | 86 | if isinstance(self.TargetTxtDictionary[Key], type([])):\r |
72443dd2 | 87 | print("%-30s = %s" % (Key, ''.join(elem + ' ' for elem in self.TargetTxtDictionary[Key])))\r |
4231a819 | 88 | elif self.TargetTxtDictionary[Key] is None:\r |
f7496d71 | 89 | errMsg += " Missing %s configuration information, please use TargetTool to set value!" % Key + os.linesep\r |
30fdf114 | 90 | else:\r |
72443dd2 | 91 | print("%-30s = %s" % (Key, self.TargetTxtDictionary[Key]))\r |
f7496d71 | 92 | \r |
30fdf114 | 93 | if errMsg != '':\r |
72443dd2 | 94 | print(os.linesep + 'Warning:' + os.linesep + errMsg)\r |
f7496d71 | 95 | \r |
30fdf114 LG |
96 | def RWFile(self, CommentCharacter, KeySplitCharacter, Num):\r |
97 | try:\r | |
98 | fr = open(self.FileName, 'r')\r | |
99 | fw = open(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), 'w')\r | |
100 | \r | |
101 | existKeys = []\r | |
102 | for Line in fr:\r | |
103 | if Line.startswith(CommentCharacter) or Line.strip() == '':\r | |
104 | fw.write(Line)\r | |
105 | else:\r | |
ccaa7754 | 106 | LineList = Line.split(KeySplitCharacter, 1)\r |
30fdf114 LG |
107 | if len(LineList) >= 2:\r |
108 | Key = LineList[0].strip()\r | |
9eb87141 | 109 | if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary:\r |
30fdf114 LG |
110 | if Key not in existKeys:\r |
111 | existKeys.append(Key)\r | |
112 | else:\r | |
72443dd2 | 113 | print("Warning: Found duplicate key item in original configuration files!")\r |
f7496d71 | 114 | \r |
30fdf114 LG |
115 | if Num == 0:\r |
116 | Line = "%-30s = \n" % Key\r | |
117 | else:\r | |
118 | ret = GetConfigureKeyValue(self, Key)\r | |
4231a819 | 119 | if ret is not None:\r |
30fdf114 LG |
120 | Line = ret\r |
121 | fw.write(Line)\r | |
9eb87141 | 122 | for key in self.TargetTxtDictionary:\r |
30fdf114 | 123 | if key not in existKeys:\r |
72443dd2 | 124 | print("Warning: %s does not exist in original configuration file" % key)\r |
30fdf114 | 125 | Line = GetConfigureKeyValue(self, key)\r |
4231a819 | 126 | if Line is None:\r |
30fdf114 LG |
127 | Line = "%-30s = " % key\r |
128 | fw.write(Line)\r | |
f7496d71 | 129 | \r |
30fdf114 LG |
130 | fr.close()\r |
131 | fw.close()\r | |
132 | os.remove(self.FileName)\r | |
133 | os.rename(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), self.FileName)\r | |
f7496d71 | 134 | \r |
30fdf114 LG |
135 | except:\r |
136 | last_type, last_value, last_tb = sys.exc_info()\r | |
137 | traceback.print_exception(last_type, last_value, last_tb)\r | |
138 | \r | |
139 | def GetConfigureKeyValue(self, Key):\r | |
140 | Line = None\r | |
4231a819 | 141 | if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM and self.Opt.DSCFILE is not None:\r |
30fdf114 LG |
142 | dscFullPath = os.path.join(self.WorkSpace, self.Opt.DSCFILE)\r |
143 | if os.path.exists(dscFullPath):\r | |
144 | Line = "%-30s = %s\n" % (Key, self.Opt.DSCFILE)\r | |
145 | else:\r | |
f7496d71 | 146 | EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND,\r |
30fdf114 | 147 | "DSC file %s does not exist!" % self.Opt.DSCFILE, RaiseError=False)\r |
4231a819 | 148 | elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF and self.Opt.TOOL_DEFINITION_FILE is not None:\r |
30fdf114 LG |
149 | tooldefFullPath = os.path.join(self.WorkSpace, self.Opt.TOOL_DEFINITION_FILE)\r |
150 | if os.path.exists(tooldefFullPath):\r | |
151 | Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_DEFINITION_FILE)\r | |
152 | else:\r | |
f7496d71 | 153 | EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND,\r |
30fdf114 | 154 | "Tooldef file %s does not exist!" % self.Opt.TOOL_DEFINITION_FILE, RaiseError=False)\r |
08dd311f LG |
155 | \r |
156 | elif self.Opt.NUM >= 2:\r | |
157 | Line = "%-30s = %s\n" % (Key, 'Enable')\r | |
158 | elif self.Opt.NUM <= 1:\r | |
f7496d71 | 159 | Line = "%-30s = %s\n" % (Key, 'Disable')\r |
4231a819 | 160 | elif Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER and self.Opt.NUM is not None:\r |
30fdf114 | 161 | Line = "%-30s = %s\n" % (Key, str(self.Opt.NUM))\r |
4231a819 | 162 | elif Key == TAB_TAT_DEFINES_TARGET and self.Opt.TARGET is not None:\r |
30fdf114 | 163 | Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET))\r |
4231a819 | 164 | elif Key == TAB_TAT_DEFINES_TARGET_ARCH and self.Opt.TARGET_ARCH is not None:\r |
30fdf114 | 165 | Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET_ARCH))\r |
4231a819 | 166 | elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG and self.Opt.TOOL_CHAIN_TAG is not None:\r |
30fdf114 | 167 | Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_CHAIN_TAG)\r |
4231a819 | 168 | elif Key == TAB_TAT_DEFINES_BUILD_RULE_CONF and self.Opt.BUILD_RULE_FILE is not None:\r |
30fdf114 LG |
169 | buildruleFullPath = os.path.join(self.WorkSpace, self.Opt.BUILD_RULE_FILE)\r |
170 | if os.path.exists(buildruleFullPath):\r | |
171 | Line = "%-30s = %s\n" % (Key, self.Opt.BUILD_RULE_FILE)\r | |
172 | else:\r | |
f7496d71 | 173 | EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND,\r |
30fdf114 LG |
174 | "Build rule file %s does not exist!" % self.Opt.BUILD_RULE_FILE, RaiseError=False)\r |
175 | return Line\r | |
176 | \r | |
b36d134f | 177 | VersionNumber = ("0.01" + " " + gBUILD_VERSION)\r |
30fdf114 | 178 | __version__ = "%prog Version " + VersionNumber\r |
f7496d71 | 179 | __copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserved."\r |
30fdf114 LG |
180 | __usage__ = "%prog [options] {args} \\r |
181 | \nArgs: \\r | |
182 | \n Clean clean the all default configuration of target.txt. \\r | |
183 | \n Print print the all default configuration of target.txt. \\r | |
184 | \n Set replace the default configuration with expected value specified by option."\r | |
185 | \r | |
186 | gParamCheck = []\r | |
187 | def SingleCheckCallback(option, opt_str, value, parser):\r | |
188 | if option not in gParamCheck:\r | |
189 | setattr(parser.values, option.dest, value)\r | |
190 | gParamCheck.append(option)\r | |
191 | else:\r | |
192 | parser.error("Option %s only allows one instance in command line!" % option)\r | |
193 | \r | |
194 | def RangeCheckCallback(option, opt_str, value, parser):\r | |
195 | if option not in gParamCheck:\r | |
196 | gParamCheck.append(option)\r | |
197 | if value < 1 or value > 8:\r | |
198 | parser.error("The count of multi-thread is not in valid range of 1 ~ 8.")\r | |
199 | else:\r | |
200 | setattr(parser.values, option.dest, value)\r | |
201 | else:\r | |
202 | parser.error("Option %s only allows one instance in command line!" % option)\r | |
f7496d71 | 203 | \r |
30fdf114 | 204 | def MyOptionParser():\r |
ccaa7754 | 205 | parser = OptionParser(version=__version__, prog="TargetTool.exe", usage=__usage__, description=__copyright__)\r |
39879ef2 FB |
206 | parser.add_option("-a", "--arch", action="append", type="choice", choices=['IA32', 'X64', 'EBC', 'ARM', 'AARCH64', '0'], dest="TARGET_ARCH",\r |
207 | 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.")\r | |
30fdf114 LG |
208 | parser.add_option("-p", "--platform", action="callback", type="string", dest="DSCFILE", callback=SingleCheckCallback,\r |
209 | 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.")\r | |
210 | parser.add_option("-c", "--tooldef", action="callback", type="string", dest="TOOL_DEFINITION_FILE", callback=SingleCheckCallback,\r | |
211 | 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.")\r | |
ccaa7754 | 212 | parser.add_option("-t", "--target", action="append", type="choice", choices=['DEBUG', 'RELEASE', '0'], dest="TARGET",\r |
30fdf114 LG |
213 | 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.")\r |
214 | parser.add_option("-n", "--tagname", action="callback", type="string", dest="TOOL_CHAIN_TAG", callback=SingleCheckCallback,\r | |
215 | 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.")\r | |
216 | parser.add_option("-r", "--buildrule", action="callback", type="string", dest="BUILD_RULE_FILE", callback=SingleCheckCallback,\r | |
217 | 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.")\r | |
218 | parser.add_option("-m", "--multithreadnum", action="callback", type="int", dest="NUM", callback=RangeCheckCallback,\r | |
219 | 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.")\r | |
30fdf114 LG |
220 | (opt, args)=parser.parse_args()\r |
221 | return (opt, args)\r | |
222 | \r | |
223 | if __name__ == '__main__':\r | |
224 | EdkLogger.Initialize()\r | |
225 | EdkLogger.SetLevel(EdkLogger.QUIET)\r | |
4231a819 | 226 | if os.getenv('WORKSPACE') is None:\r |
72443dd2 | 227 | print("ERROR: WORKSPACE should be specified or edksetup script should be executed before run TargetTool")\r |
30fdf114 | 228 | sys.exit(1)\r |
f7496d71 | 229 | \r |
30fdf114 LG |
230 | (opt, args) = MyOptionParser()\r |
231 | if len(args) != 1 or (args[0].lower() != 'print' and args[0].lower() != 'clean' and args[0].lower() != 'set'):\r | |
72443dd2 | 232 | print("The number of args isn't 1 or the value of args is invalid.")\r |
30fdf114 | 233 | sys.exit(1)\r |
4231a819 | 234 | if opt.NUM is not None and opt.NUM < 1:\r |
72443dd2 | 235 | print("The MAX_CONCURRENT_THREAD_NUMBER must be larger than 0.")\r |
30fdf114 | 236 | sys.exit(1)\r |
4231a819 | 237 | if opt.TARGET is not None and len(opt.TARGET) > 1:\r |
30fdf114 LG |
238 | for elem in opt.TARGET:\r |
239 | if elem == '0':\r | |
72443dd2 | 240 | print("0 will clear the TARGET setting in target.txt and can't combine with other value.")\r |
30fdf114 | 241 | sys.exit(1)\r |
4231a819 | 242 | if opt.TARGET_ARCH is not None and len(opt.TARGET_ARCH) > 1:\r |
30fdf114 LG |
243 | for elem in opt.TARGET_ARCH:\r |
244 | if elem == '0':\r | |
72443dd2 | 245 | print("0 will clear the TARGET_ARCH setting in target.txt and can't combine with other value.")\r |
30fdf114 LG |
246 | sys.exit(1)\r |
247 | \r | |
248 | try:\r | |
249 | FileHandle = TargetTool(opt, args)\r | |
250 | if FileHandle.Arg.lower() == 'print':\r | |
251 | FileHandle.Print()\r | |
252 | sys.exit(0)\r | |
253 | elif FileHandle.Arg.lower() == 'clean':\r | |
254 | FileHandle.RWFile('#', '=', 0)\r | |
255 | else:\r | |
256 | FileHandle.RWFile('#', '=', 1)\r | |
5b0671c1 | 257 | except Exception as e:\r |
30fdf114 LG |
258 | last_type, last_value, last_tb = sys.exc_info()\r |
259 | traceback.print_exception(last_type, last_value, last_tb)\r | |
260 | \r |