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