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