git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@384 7335b...
[people/mcb30/basetools.git] / Source / Python / build / build.py
1 #\r
2 #  Copyright (c) 2007, Intel Corporation\r
3 #\r
4 #  All rights reserved. This program and the accompanying materials\r
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, sys, string, glob, time, traceback\r
14 from threading import *\r
15 from optparse import OptionParser\r
16 from os.path import normpath\r
17 \r
18 \r
19 from subprocess import *\r
20 \r
21 from NewTargetTxtClassObject import *\r
22 from NewEdkIIWorkspaceBuild import *\r
23 from AutoGen import *\r
24 from BuildToolError import *\r
25 import EdkLogger\r
26 from BuildSpawn import *\r
27 \r
28 \r
29 VersionNumber = "0.01"\r
30 __version__ = "%prog Version " + VersionNumber\r
31 __copyright__ = "Copyright (c) 2007, Intel Corporation  All rights reserved."\r
32 \r
33 \r
34 # target, command options process\r
35 ##-a, --arch <ARCHS>\r
36 ##      ARCHS is a comma separated list containing one or more of: IA32, X64, IPF or EBC which should be built, overrides target.txt?s TARGET_ARCH\r
37 ##-p, --platform PlatformName.dsc\r
38 ##      Build the platform specified by the DSC file name argument, over rides the ACTIVE_PLATFORM\r
39 ##-m, --module Module.inf\r
40 ##      Build the module specified by the INF file name argument.\r
41 ##-b, --buildtarget BuildTarget\r
42 ##      Build the platform using the BuildTarget, overrides target.txt?s TARGET definition.\r
43 ##-t, --tagname Tagname\r
44 ##      Build the platform using the Tool chain, Tagname, overrides target.txt?s TOOL_CHAIN_TAG definition.\r
45 ##-s, --spawn\r
46 ##      If this flag is specified, the first two phases, AutoGen and MAKE are mixed, such that as soon as a module can be built, the build will start, without waiting for AutoGen to complete on remaining modules.  While this option provides feedback that looks fast, due to overhead of the AutoGen function, this option is slower than letting AutoGen complete before starting the MAKE phase.\r
47 ##-n #\r
48 ##      Build the platform using multi-threaded compiler with # threads, values less than 2 will disable multi-thread builds.  Overrides target.txt?s MULTIPLE_THREAD and MAX_CONCURRENT_THREAD_NUMBER\r
49 ##-f, --fdf Filename.fdf\r
50 ##      The name of the FDF file to use, over-riding the setting in the DSC file.\r
51 ##-k, --msft\r
52 ##      Make Option: Generate only NMAKE Makefiles: Makefile\r
53 ##-g, --gcc\r
54 ##      Make Option: Generate only GMAKE Makefiles: GNUmakefile\r
55 ##-l, --all\r
56 ##      Make Option: Generate both NMAKE and GMAKE makefiles.\r
57 \r
58 # VFR related options: should not be in this tool\r
59 ##-r, --vfr VfrScriptFile\r
60 ##      VFR Option: Name of the VFR Script File to use\r
61 ##-e, --CreateC [Filename]\r
62 ##      VFR Option: [DEFAULT] Create the C File, named Filename, otherwise use the VfrScriptFile name as the C code?s filename, i.e., VfrFilename.c\r
63 ##-x, --CreateList [Filename]\r
64 ##      VFR Option: Create the text list file, named Filename, otherwise use the VfrScriptFile name as the List file?s filename, i.e., VfrFilename.lst\r
65 ##-i, --include [Path]\r
66 ##      One or more statements to add to the include path for searching.\r
67 ##-o, --outdir [DirName]\r
68 ##      VFR Option: Directory Location where the C, Lst and/or IFR files are to be created.\r
69 ##-b, --Bin [Filename]\r
70 ##      VFR Option: Create a binary IFR HII pack file, named Filename, otherwise use the VfrScriptFile name as the IFR file?s name, i.e., VfrFilename.i\r
71 \r
72 #\r
73 ##-c, --flashheader [Filename]\r
74 ##      Flash option: Create a header file, default to FlashMap.h, containing flash device definitions for EDK modules which need those flash information.\r
75 ##--version\r
76 ##      Print version and copyright of this program and exit\r
77 ##-v, --verbose\r
78 ##      Turn on verbose output with informational messages printed. This is a count value, so specifying ?vv can be used to increase the verbosity level.\r
79 ##-q, --quiet\r
80 ##      disable all messages except FATAL ERRORS\r
81 ##-d, --debug [#]\r
82 ##      Enable debug messages, at level #\r
83 ##-h, --help\r
84 ##      Print copyright, version and usage of this program and exit code: PASS\r
85 \r
86 class Build():\r
87     def __init__(self, opt, args):\r
88         self.SysPlatform  = sys.platform\r
89         self.EdkToolsPath = os.getenv("EDK_TOOLS_PATH")\r
90         self.WorkSpace    = os.getenv("WORKSPACE")\r
91         self.Path         = os.getenv("PATH")\r
92         self.Opt          = opt\r
93         self.Args         = args\r
94         self.TargetTxt    = NewTargetTxtClassObject()\r
95         self.ToolDef      = ToolDefClassObject()\r
96         self.Sem          = None\r
97         self.StartTime    = time.time()\r
98         print time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime())\r
99         \r
100 \r
101     def CheckEnvVariable(self):\r
102         print "Running Operating System =", self.SysPlatform\r
103 \r
104         if self.EdkToolsPath == None:\r
105             print "Please set environment variable: EDK_TOOLS_PATH !\n"\r
106             return 1\r
107         else:\r
108             print "EDK_TOOLS_PATH = %s" % self.EdkToolsPath\r
109 \r
110         if self.WorkSpace == None:\r
111             print "Please set environment variable: WORKSPACE !\n"\r
112             return 1\r
113         else:\r
114             print "WORKSPACE = %s" % self.WorkSpace\r
115 \r
116         if self.Path == None:\r
117             print "Please set environment variable: PATH !\n"\r
118             return 1\r
119         else:\r
120             if self.SysPlatform == "win32":\r
121                 #print EDK_TOOLS_PATH + "\Bin\Win32"\r
122                 if str(self.Path).find(self.EdkToolsPath + "\Bin\Win32") == -1:\r
123                     print "Please execute %s\Bin\Win32\edksetup.bat to set %s\Bin\Win32 in environment variable: PATH!\n" % (self.EdkToolsPath, self.EdkToolsPath)\r
124                     return 1\r
125             if self.SysPlatform == "win64":\r
126                 #print EDK_TOOLS_PATH + "\Bin\Win64"\r
127                 if str(self.Path).find(self.EdkToolsPath + "\Bin\Win64") == -1:\r
128                     print "Please execute %s\Bin\Win32\edksetup.bat to set %s\Bin\Win64 in environment variable: PATH!\n" % (self.EdkToolsPath, self.EdkToolsPath)\r
129                     return 1\r
130         return 0\r
131 \r
132     def LibBuild(LibFile, PlatformFile, ewb, a, b, c):\r
133         LibraryAutoGen = AutoGen(LibFile, PlatformFile, ewb, str(a), b, str(c))\r
134         LibraryAutoGen.CreateAutoGenFile()\r
135         LibraryAutoGen.CreateMakefile()\r
136         for f in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
137             (filename, ext) = os.path.splitext(os.environ["WORKSPACE"] + '\\' + f.replace('/','\\') + '\\' + a + '_' + b + '\\' + c + '\\' + str(LibFile))\r
138             DestDir = filename\r
139             print DestDir\r
140             FileList = glob.glob(DestDir + '\\makefile')\r
141             FileNum = len(FileList)\r
142             if FileNum > 0:\r
143                 SameTypeFileInDir(FileNum, 'makefile', DestDir, self.StartTime)\r
144                 BuildSpawn(self.Sem, FileList[0], 'lbuild', 1).start()\r
145             else:\r
146                 print "There isn't makefils in %s.\n" % DestDir\r
147                 return 1\r
148 \r
149     def ModuleBuild(ModuleFile, PlatformFile, ewb, a, b, c, ModuleAutoGen):\r
150         ModuleAutoGen.CreateAutoGenFile()\r
151         ModuleAutoGen.CreateMakefile()\r
152         for f in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
153             (filename, ext) = os.path.splitext(os.environ["WORKSPACE"] + '\\' + f.replace('/','\\') + '\\' + a + '_' + b + '\\' + c + '\\' + ModuleFile)\r
154             DestDir = filename\r
155             FileList = glob.glob(DestDir + '\\makefile')\r
156             FileNum = len(FileList)\r
157             if FileNum > 0:\r
158                 SameTypeFileInDir(FileNum, 'makefile', DestDir, self.StartTime)\r
159                 for i in range(0, int(self.Opt.NUM)):\r
160                     self.Sem.acquire()\r
161                 p = Popen(["nmake", "/nologo", "-f", FileList[0], 'pbuild'], env=os.environ, cwd=os.path.dirname(FileList[0]))\r
162                 p.communicate()\r
163                 if p.returncode != 0:\r
164                     return p.returncode\r
165                 for i in range(0, int(self.Opt.NUM)):\r
166                     self.Sem.release()\r
167             else:\r
168                 print "There isn't makefile in %s.\n" % DestDir\r
169                 return 1\r
170 \r
171     def SameTypeFileInDir(FileNum, FileType, Dir):\r
172         if FileNum >= 2:\r
173             print "There are %d %s files in %s.\n" % (FileNum, FileType, CurWorkDir)\r
174             self.CalculateTime()\r
175             sys.exit(1)\r
176 \r
177     def TrackInfo(self):\r
178         if self.Opt.debug != None:\r
179             last_type, last_value, last_tb = sys.exc_info()\r
180             traceback.print_exception(last_type, last_value, last_tb)\r
181 \r
182     def GenCFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
183         try:\r
184             AutoGenResult = AutoGen(ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch)\r
185             AutoGenResult.CreateAutoGenFile()\r
186         except Exception, e:\r
187             TrackInfo()\r
188             print e\r
189             return 1\r
190 \r
191     def GenMakeFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
192         try:\r
193             AutoGenResult = AutoGen(ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch)\r
194             AutoGenResult.CreateAutoGenFile()\r
195             makefile = AutoGenResult.CreateMakefile()\r
196         except Exception, e:\r
197             TrackInfo()\r
198             print e\r
199             return 1\r
200 \r
201 \r
202     def CleanAllFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
203         for d in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
204             if ModuleFile == None:\r
205                 DestDir = os.environ["WORKSPACE"] + '\\' + d.replace('/','\\') + '\\' + Target + '_' + ToolChain\r
206             else:\r
207                 (filename, ext) = os.path.splitext(os.environ["WORKSPACE"] + '\\' + d.replace('/','\\') + '\\' + Target + '_' + ToolChain + '\\' + Arch + '\\' + ModuleFile)\r
208                 DestDir = filename\r
209             FileList = glob.glob(DestDir + '\\makefile')\r
210             FileNum = len(FileList)\r
211             if FileNum > 0:\r
212                 SameTypeFileInDir(FileNum, 'makefile', DestDir, StartTime)\r
213                 p = Popen(["nmake", "/nologo", "-f", FileList[0], 'cleanall'], env=os.environ, cwd=os.path.dirname(FileList[0]))\r
214                 p.communicate()\r
215                 if p.returncode != None:\r
216                     return p.returncode\r
217             else:\r
218                 return 1\r
219 \r
220     def ALLFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
221         try:\r
222             AutoGenResult = AutoGen(ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch)\r
223             AutoGenResult.CreateAutoGenFile()\r
224             makefile = AutoGenResult.CreateMakefile()\r
225         except Exception, e:\r
226             TrackInfo()\r
227             print e\r
228             return 1\r
229         if makefile != "":\r
230             p = Popen(["nmake", "/nologo", "-f", makefile, 'all'], env=os.environ, cwd=os.path.dirname(makefile))\r
231             p.communicate()\r
232             if p.returncode != None:\r
233                 return p.returncode\r
234         else:\r
235             print "Can find Makefile.\n"\r
236             return 1\r
237 \r
238 \r
239     def Process(self, ModuleFile, PlatformFile, ewb):\r
240 \r
241         #\r
242         # Merge Arch\r
243         #\r
244         self.Opt.TARGET_ARCH = list(set(self.Opt.TARGET_ARCH) & set(ewb.SupArchList))\r
245 \r
246         GenC = 0\r
247         GenMake = 0\r
248         CleanAll = 0\r
249         for t in self.Args:\r
250             t = t.lower()\r
251             if t == 'genc':\r
252                 GenC = 1\r
253             elif t == 'genmake':\r
254                 GenMake = 1\r
255             elif t == 'cleanall':\r
256                 CleanAll = 1\r
257 \r
258         if self.Opt.spawn == True:\r
259             for a in self.Opt.TARGET:\r
260                 for b in self.Opt.TOOL_CHAIN_TAG:\r
261                     if ModuleFile == None:\r
262                         PlatformAutoGen = AutoGen(None, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
263                         print "PlatformAutoGen : %s", PlatformFile\r
264                         for c in self.Opt.TARGET_ARCH:\r
265                             li = []\r
266                             for d in PlatformAutoGen.Platform[c].Modules:\r
267                                 if ewb.InfDatabase[d].Defines.DefinesDictionary['LIBRARY_CLASS'] == ['']:\r
268                                     print "Module : %s, Arch : %s" % (d, c)\r
269                                     ModuleAutoGen = AutoGen(d, PlatformFile, ewb, a, b, c)\r
270                                     for e in ModuleAutoGen.BuildInfo.DependentLibraryList:\r
271                                         print "Library: %s, Arch : %s" % (e, c)\r
272                                         if e in li:\r
273                                             continue\r
274                                         else:\r
275                                             li.append(e)\r
276                                         self.LibBuild(e, PlatformFile, ewb, a, b, c)\r
277                                     self.ModuleBuild(d, PlatformFile, ewb, a, b, c, ModuleAutoGen)\r
278                                 else:\r
279                                     self.LibBuild(d, PlatformFile, ewb, a, b, c)\r
280 \r
281                         PlatformAutoGen.CreateAutoGenFile()\r
282                         PlatformAutoGen.CreateMakefile()\r
283                         for i in range(0, int(self.Opt.NUM)):\r
284                             Sem.acquire()\r
285                         print "successful"\r
286                         for i in range(0, int(self.Opt.NUM)):\r
287                             Sem.release()\r
288                             \r
289                         # call GenFds\r
290                         #GenFds -f C:\Work\Temp\T1\Nt32Pkg\Nt32Pkg.fdf -o $(BUILD_DIR) -p Nt32Pkg\Nt32Pkg.dsc\r
291                         if self.Opt.FDFFILE != '':\r
292                             self.Opt.FDFFILE =  os.environ["WORKSPACE"] + '\\' + self.Opt.FDFFILE.replace('/','\\')\r
293                             f = ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']\r
294                             f = os.environ["WORKSPACE"] + '\\' + f.replace('/', '\\') + '\\' + a + '_' + b\r
295                             if os.path.isdir(f + "\\" + "FV") != True:\r
296                                 os.mkdir(f + "\\" + "FV")\r
297                             p = Popen(["GenFds", "-f", self.Opt.FDFFILE, "-o", f, "-p", self.Opt.DSCFILE], env=os.environ, cwd=os.path.dirname(self.Opt.FDFFILE))\r
298                             p.communicate()\r
299                             if p.returncode != 0:\r
300                                 return p.returncode\r
301 \r
302                     else:\r
303                         for c in self.Opt.TARGET_ARCH:\r
304                             ModuleAutoGen = AutoGen(ModuleFile, PlatformFile, ewb, a, b, c)\r
305                             print "ModuleAutoGen : %s"  % ModuleFile\r
306                             for e in ModuleAutoGen.BuildInfo.DependentLibraryList:\r
307                                 print "Library: %s" % stre\r
308                                 self.LibBuild(e, PlatformFile, ewb, a, b, c)\r
309                             self.ModuleBuild(ModuleFile, PlatformFile, ewb, a, b, c, ModuleAutoGen)\r
310             return 0\r
311 \r
312     # normal build\r
313         for a in self.Opt.TARGET:\r
314             for b in self.Opt.TOOL_CHAIN_TAG:\r
315                 if ModuleFile == None:\r
316                     if GenC == 1:\r
317                         self.GenCFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
318                     elif GenMake == 1:\r
319                         self.GenMakeFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
320                     elif CleanAll == 1:\r
321                         self.CleanAllFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
322                     else:\r
323                         self.ALLFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
324                 else:\r
325                     for c in self.Opt.TARGET_ARCH:\r
326                         if GenC == 1:\r
327                             self.GenCFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
328                         elif GenMake == 1:\r
329                             self.GenMakeFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
330                         elif CleanAll == 1:\r
331                             self.CleanAllFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
332                         else:\r
333                             self.ALLFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
334         return 0\r
335 \r
336     def CalculateTime(self):\r
337         print time.strftime("Current time is %a, %d %b %Y %H:%M:%S +0000", time.localtime())\r
338         Hour = 0\r
339         Min = 0\r
340         Sec = int(time.time() - self.StartTime)\r
341         Hour = Sec/3600\r
342         Min = (Sec%3600)/60\r
343         Sec = (Sec%3600)%60\r
344         if Hour < 10 and Min < 10 and Sec < 10:\r
345             print "Totol Run Time is 0%d:0%d:0%d" %(Hour, Min, Sec)\r
346         elif Hour < 10 and Min < 10 and Sec > 10:\r
347             print "Totol Run Time is 0%d:0%d:%2d" %(Hour, Min, Sec)\r
348         elif Hour < 10 and Min > 10 and Sec < 10:\r
349             print "Totol Run Time is 0%d:%2d:0%d" %(Hour, Min, Sec)\r
350         elif Hour < 10 and Min > 10 and Sec > 10:\r
351             print "Totol Run Time is 0%d:%2d:%2d" %(Hour, Min, Sec)\r
352         elif Hour > 10 and Min < 10 and Sec < 10:\r
353             print "Totol Run Time is %2d:0%d:0%d" %(Hour, Min, Sec)\r
354         elif Hour > 10 and Min < 10 and Sec > 10:\r
355             print "Totol Run Time is %2d:0%d:%2d" %(Hour, Min, Sec)\r
356         elif Hour > 10 and Min > 10 and Sec < 10:\r
357             print "Totol Run Time is %2d:%2d:0%d" %(Hour, Min, Sec)\r
358         elif Hour > 10 and Min < 10 and Sec > 10:\r
359             print "Totol Run Time is %2d:%2d:0%d" %(Hour, Min, Sec)\r
360 \r
361 def MyOptionParser():\r
362     parser = OptionParser(description=__copyright__,version=__version__,prog="bld.exe",usage="%prog [options] [target]")\r
363     parser.add_option("-a", "--arch", action="append", type="choice", choices=['IA32','X64','IPF','EBC'], dest="TARGET_ARCH",\r
364         help="ARCHS is a comma separated list containing one or more of: IA32, X64, IPF or EBC which should be built, overrides target.txt's TARGET_ARCH")\r
365     parser.add_option("-p", "--platform", action="store", type="string", dest="DSCFILE",\r
366         help="Build the platform specified by the DSC file name argument, over rides the ACTIVE_PLATFORM")\r
367     parser.add_option("-m", "--module", action="store", type="string", dest="INFFILE",\r
368         help="Build the module specified by the INF file name argument.")\r
369     parser.add_option("-b", "--buildtarget", action="append", type="choice", choices=['DEBUG','RELEASE'], dest="TARGET",\r
370         help="Build the platform using the BuildTarget, overrides target.txt's TARGET definition.")\r
371     parser.add_option("-t", "--tagname", action="append", type="string", dest="TOOL_CHAIN_TAG",\r
372         help="Build the platform using the Tool chain, Tagname, overrides target.txt's TOOL_CHAIN_TAG definition.")\r
373     parser.add_option("-s", "--spawn", action="store_true", type=None,\r
374         help="If this flag is specified, the first two phases, AutoGen and MAKE are mixed, such that as soon as a module can be built, the build will start, without waiting for AutoGen to complete on remaining modules.  While this option provides feedback that looks fast, due to overhead of the AutoGen function, this option is slower than letting AutoGen complete before starting the MAKE phase.")\r
375     parser.add_option("-n", action="store", type="int", dest="NUM",\r
376         help="Build the platform using multi-threaded compiler with # threads, values less than 2 will disable multi-thread builds. Overrides target.txt's MULTIPLE_THREAD and MAX_CONCURRENT_THREAD_NUMBER")\r
377     parser.add_option("-f", "--fdf", action="store", type="string", dest="FDFFILE",\r
378         help="The name of the FDF file to use, over-riding the setting in the DSC file.")\r
379     parser.add_option("-k", "--msft", action="store_true", type=None, help="Make Option: Generate only NMAKE Makefiles: Makefile")\r
380     parser.add_option("-g", "--gcc", action="store_true", type=None, help="Make Option: Generate only GMAKE Makefiles: GNUmakefile")\r
381     parser.add_option("-l", "--all", action="store_true", type=None, help="Make Option: Generate both NMAKE and GMAKE makefiles.")\r
382     parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
383     parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
384     parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
385 \r
386     (opt, args)=parser.parse_args()\r
387     return (opt, args)\r
388 \r
389 \r
390 \r
391 \r
392 if __name__ == '__main__':\r
393 #\r
394 # Parse the options and args\r
395 #\r
396     try:\r
397         (opt, args) = MyOptionParser()\r
398     except Exception, e:\r
399         print e\r
400         sys.exit(1)\r
401 \r
402 #\r
403 # Check environment variable: EDK_TOOLS_PATH, WORKSPACE, PATH\r
404 #\r
405     build = Build(opt, args)\r
406     StatusCode = build.CheckEnvVariable()\r
407     if StatusCode != 0:\r
408         build.CalculateTime()\r
409         sys.exit(StatusCode)\r
410 \r
411 #\r
412 # Check target.txt and tools_def.txt and Init them\r
413 #\r
414     if os.path.isfile(build.WorkSpace + '\\Conf\\target.txt') == True:\r
415         StatusCode =build.TargetTxt.LoadTargetTxtFile(build.WorkSpace + '\\Conf\\target.txt')\r
416         if os.path.isfile(build.WorkSpace + '\\' + build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]) == True:\r
417             StatusCode = build.ToolDef.LoadToolDefFile(build.WorkSpace + '\\' + build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF])\r
418         else:\r
419             print "%s is not existed." % build.WorkSpace + '\\' + build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
420             build.CalculateTime()\r
421             sys.exit(1)\r
422     else:\r
423         print "%s is not existed." % build.WorkSpace + '\\Conf\\target.txt'\r
424         build.CalculateTime()\r
425         sys.exit(1)\r
426 \r
427 #\r
428 # Merge the Build Options\r
429 #\r
430     if build.Opt.TARGET_ARCH == None:\r
431         build.Opt.TARGET_ARCH = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET_ARCH]\r
432         if build.Opt.TARGET_ARCH == ['']:\r
433             build.Opt.TARGET_ARCH = ['IA32', 'X64', 'IPF', 'EBC']\r
434     print "TARGET_ARCH is", " ".join(opt.TARGET_ARCH)\r
435 \r
436     if build.Opt.DSCFILE == None:\r
437         build.Opt.DSCFILE = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM]\r
438     print "ACTIVE_PLATFORM is %s" % build.Opt.DSCFILE\r
439 \r
440     if build.Opt.TARGET == None:\r
441         build.Opt.TARGET = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]\r
442         if build.Opt.TARGET == ['']:\r
443             build.Opt.TARGET_ARCH = ['DEBUG', 'RELEASE']\r
444     print "TARGET is", " ".join(build.Opt.TARGET)\r
445 \r
446     if build.Opt.TOOL_CHAIN_TAG == None:\r
447         build.Opt.TOOL_CHAIN_TAG = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
448         if build.Opt.TOOL_CHAIN_TAG == '':\r
449             print "TOOL_CHAIN_TAG is None. Don't What to Build.\n"\r
450             build.CalculateTime()\r
451             sys.exit(1)\r
452     print "TOOL_CHAIN_TAG is", build.Opt.TOOL_CHAIN_TAG\r
453 \r
454     if build.Opt.NUM == None:\r
455         build.Opt.NUM = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER]\r
456     if build.Opt.NUM == '':\r
457         build.Opt.NUM = 1\r
458     else:\r
459         build.Opt.NUM = int(build.Opt.NUM)\r
460     print "MAX_CONCURRENT_THREAD_NUMBER is", build.Opt.NUM\r
461     if build.Opt.spawn == True:\r
462         build.Sem = BoundedSemaphore(int(build.Opt.NUM))\r
463 \r
464     if build.Opt.verbose != None:\r
465         EdkLogger.setLevel(EdkLogger.VERBOSE)\r
466     elif build.Opt.quiet != None:\r
467         EdkLogger.setLevel(EdkLogger.QUIET)\r
468     elif build.Opt.debug != None:\r
469         EdkLogger.setLevel(build.Opt.debug)\r
470     else:\r
471         EdkLogger.setLevel(EdkLogger.INFO)\r
472 \r
473 #\r
474 # Call Parser\r
475 #\r
476     if (build.Opt.DSCFILE != None or build.Opt.DSCFILE != '') and os.path.isfile(build.WorkSpace + '\\' + build.Opt.DSCFILE) == False:\r
477         print "The input file: %s is not existed!", build.Opt.DSCFILE\r
478         build.CalculateTime()\r
479         sys.exit(1)\r
480     if build.Opt.FDFFILE != None and os.path.isfile(build.WorkSpace + '\\' + build.Opt.FDFFILE) == False:\r
481         print "The input file: %s is not existed!", build.Opt.FDFFILE\r
482         build.CalculateTime()\r
483         sys.exit(1)\r
484     try:\r
485         if build.Opt.DSCFILE != None and build.Opt.DSCFILE != '':\r
486             ewb = NewWorkspaceBuild(build.Opt.DSCFILE, build.WorkSpace)  #opt.DSCFILE is relative path plus filename\r
487     except Exception, e:\r
488         print e\r
489         build.CalculateTime()\r
490         sys.exit(1)\r
491 \r
492 #\r
493 # Platform Build or Module Build\r
494 #\r
495     CurWorkDir = os.getcwd()\r
496 \r
497     if build.Opt.INFFILE:\r
498         if build.Opt.DSCFILE:\r
499             ModuleFile = build.Opt.INFFILE\r
500             print "MODULE build:", ModuleFile\r
501             PlatformFile = str(os.path.normpath(build.Opt.DSCFILE))\r
502             print "PlatformFile is:", PlatformFile\r
503             StatusCode = build.Process(ModuleFile, PlatformFile, ewb, build.Opt)\r
504         else:\r
505             print "ERROR: DON'T KNOW WHAT TO BUILD\n"\r
506     elif len(glob.glob(CurWorkDir + '\\*.inf')) > 0:\r
507         FileList = glob.glob(CurWorkDir + '\\*.inf')\r
508         FileNum = len(FileList)\r
509         if FileNum >= 2:\r
510             print "There are %d INF filss in %s.\n" % (FileNum, CurWorkDir)\r
511             sys.exit(1)\r
512         if build.Opt.DSCFILE:\r
513             if ewb.Workspace.WorkspaceDir[len(ewb.Workspace.WorkspaceDir)-1] == '\\':\r
514                 ModuleFile = FileList[0][len(ewb.Workspace.WorkspaceDir):]\r
515             else:\r
516                 ModuleFile = FileList[0][len(ewb.Workspace.WorkspaceDir)+1:]\r
517             print "Module build:", ModuleFile\r
518             PlatformFile = str(os.path.normpath(build.Opt.DSCFILE))\r
519             print "PlatformFile is:", PlatformFile\r
520             StatusCode = build.Process(ModuleFile, PlatformFile, ewb)\r
521         else:\r
522             print "ERROR: DON'T KNOW WHAT TO BUILD\n"\r
523     elif build.Opt.DSCFILE:\r
524         PlatformFile = os.path.normpath(build.Opt.DSCFILE)\r
525         print "Platform build:", PlatformFile\r
526         StatusCode = build.Process(None, PlatformFile, ewb)\r
527     else:\r
528         FileList = glob.glob(CurWorkDir + '\\*.dsc')\r
529         FileNum = len(FileList)\r
530         if FileNum > 0:\r
531             if FileNum >= 2:\r
532                 print "There are %d DSC files in %s.\n" % (FileNum, CurWorkDir)\r
533                 sys.exit(1)\r
534             if os.environ('WORKSPACE')[len(os.environ('WORKSPACE'))-1] == '\\':\r
535                 PlatformFile = FileList[0][len(os.environ('WORKSPACE')):]\r
536             else:\r
537                 PlatformFile = FileList[0][len(os.environ('WORKSPACE'))+1:]\r
538             print "Platform build:", PlatformFile\r
539             #\r
540             # Call Parser Again\r
541             #\r
542             ewb = NewWorkspaceBuild(PlatformFile, build.WorkSpace)\r
543             StatusCode = build.Process(None, PlatformFile, ewb)\r
544         else:\r
545             print "ERROR: DON'T KNOW WHAT TO BUILD\n"\r
546 \r
547 #\r
548 # Record Build Process Time\r
549 #\r
550     build.CalculateTime()\r
551 \r
552 # To Do: add a judgement for return code\r
553     sys.exit(StatusCode)\r