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