git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@384 7335b...
[people/mcb30/basetools.git] / Source / Python / build / build.py
index 81b061d..57acd5e 100644 (file)
 #  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 #\r
 \r
-import os, sys, string, glob, time\r
+import os, sys, string, glob, time, traceback\r
+from threading import *\r
 from optparse import OptionParser\r
 from os.path import normpath\r
 \r
+\r
 from subprocess import *\r
 \r
-from TargetTxtClassObject import *\r
-from EdkIIWorkspaceBuild import *\r
+from NewTargetTxtClassObject import *\r
+from NewEdkIIWorkspaceBuild import *\r
 from AutoGen import *\r
 from BuildToolError import *\r
+import EdkLogger\r
+from BuildSpawn import *\r
+\r
 \r
 VersionNumber = "0.01"\r
 __version__ = "%prog Version " + VersionNumber\r
@@ -78,170 +83,313 @@ __copyright__ = "Copyright (c) 2007, Intel Corporation  All rights reserved."
 ##-h, --help\r
 ##      Print copyright, version and usage of this program and exit code: PASS\r
 \r
-def CheckEnvVariable():\r
-    print "Running Operating System =", sys.platform\r
+class Build():\r
+    def __init__(self, opt, args):\r
+        self.SysPlatform  = sys.platform\r
+        self.EdkToolsPath = os.getenv("EDK_TOOLS_PATH")\r
+        self.WorkSpace    = os.getenv("WORKSPACE")\r
+        self.Path         = os.getenv("PATH")\r
+        self.Opt          = opt\r
+        self.Args         = args\r
+        self.TargetTxt    = NewTargetTxtClassObject()\r
+        self.ToolDef      = ToolDefClassObject()\r
+        self.Sem          = None\r
+        self.StartTime    = time.time()\r
+        print time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime())\r
+        \r
 \r
-    if os.getenv("EDK_TOOLS_PATH") == None:\r
-        print "Please set environment variable: EDK_TOOLS_PATH !\n"\r
-        return 1\r
-    else:\r
-        EDK_TOOLS_PATH = os.environ["EDK_TOOLS_PATH"]\r
-        print "EDK_TOOLS_PATH = %s" % EDK_TOOLS_PATH\r
+    def CheckEnvVariable(self):\r
+        print "Running Operating System =", self.SysPlatform\r
 \r
-    if os.getenv("WORKSPACE") == None:\r
-        print "Please set environment variable: WORKSPACE !\n"\r
-        return 1\r
-    else:\r
-        WORKSPACE = os.environ["WORKSPACE"]\r
-        print "WORKSPACE = %s" % WORKSPACE\r
+        if self.EdkToolsPath == None:\r
+            print "Please set environment variable: EDK_TOOLS_PATH !\n"\r
+            return 1\r
+        else:\r
+            print "EDK_TOOLS_PATH = %s" % self.EdkToolsPath\r
 \r
-    if os.getenv("PATH") == None:\r
-        print "Please set environment variable: PATH !\n"\r
-        return 1\r
-    else:\r
-        PATH = os.environ["PATH"]\r
-        if sys.platform == "win32":\r
-            #print EDK_TOOLS_PATH + "\Bin\Win32"\r
-            if str(PATH).find(EDK_TOOLS_PATH + "\Bin\Win32") == -1:\r
-                print "Please execute %s\Bin\Win32\edksetup.bat to set %s\Bin\Win32 in environment variable: PATH!\n" % (EDK_TOOLS_PATH, EDK_TOOLS_PATH)\r
+        if self.WorkSpace == None:\r
+            print "Please set environment variable: WORKSPACE !\n"\r
+            return 1\r
+        else:\r
+            print "WORKSPACE = %s" % self.WorkSpace\r
+\r
+        if self.Path == None:\r
+            print "Please set environment variable: PATH !\n"\r
+            return 1\r
+        else:\r
+            if self.SysPlatform == "win32":\r
+                #print EDK_TOOLS_PATH + "\Bin\Win32"\r
+                if str(self.Path).find(self.EdkToolsPath + "\Bin\Win32") == -1:\r
+                    print "Please execute %s\Bin\Win32\edksetup.bat to set %s\Bin\Win32 in environment variable: PATH!\n" % (self.EdkToolsPath, self.EdkToolsPath)\r
+                    return 1\r
+            if self.SysPlatform == "win64":\r
+                #print EDK_TOOLS_PATH + "\Bin\Win64"\r
+                if str(self.Path).find(self.EdkToolsPath + "\Bin\Win64") == -1:\r
+                    print "Please execute %s\Bin\Win32\edksetup.bat to set %s\Bin\Win64 in environment variable: PATH!\n" % (self.EdkToolsPath, self.EdkToolsPath)\r
+                    return 1\r
+        return 0\r
+\r
+    def LibBuild(LibFile, PlatformFile, ewb, a, b, c):\r
+        LibraryAutoGen = AutoGen(LibFile, PlatformFile, ewb, str(a), b, str(c))\r
+        LibraryAutoGen.CreateAutoGenFile()\r
+        LibraryAutoGen.CreateMakefile()\r
+        for f in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
+            (filename, ext) = os.path.splitext(os.environ["WORKSPACE"] + '\\' + f.replace('/','\\') + '\\' + a + '_' + b + '\\' + c + '\\' + str(LibFile))\r
+            DestDir = filename\r
+            print DestDir\r
+            FileList = glob.glob(DestDir + '\\makefile')\r
+            FileNum = len(FileList)\r
+            if FileNum > 0:\r
+                SameTypeFileInDir(FileNum, 'makefile', DestDir, self.StartTime)\r
+                BuildSpawn(self.Sem, FileList[0], 'lbuild', 1).start()\r
+            else:\r
+                print "There isn't makefils in %s.\n" % DestDir\r
                 return 1\r
-        if sys.platform == "win64":\r
-            #print EDK_TOOLS_PATH + "\Bin\Win64"\r
-            if str(PATH).find(EDK_TOOLS_PATH + "\Bin\Win64") == -1:\r
-                print "Please execute %s\Bin\Win32\edksetup.bat to set %s\Bin\Win64 in environment variable: PATH!\n" % (EDK_TOOLS_PATH, EDK_TOOLS_PATH)\r
+\r
+    def ModuleBuild(ModuleFile, PlatformFile, ewb, a, b, c, ModuleAutoGen):\r
+        ModuleAutoGen.CreateAutoGenFile()\r
+        ModuleAutoGen.CreateMakefile()\r
+        for f in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
+            (filename, ext) = os.path.splitext(os.environ["WORKSPACE"] + '\\' + f.replace('/','\\') + '\\' + a + '_' + b + '\\' + c + '\\' + ModuleFile)\r
+            DestDir = filename\r
+            FileList = glob.glob(DestDir + '\\makefile')\r
+            FileNum = len(FileList)\r
+            if FileNum > 0:\r
+                SameTypeFileInDir(FileNum, 'makefile', DestDir, self.StartTime)\r
+                for i in range(0, int(self.Opt.NUM)):\r
+                    self.Sem.acquire()\r
+                p = Popen(["nmake", "/nologo", "-f", FileList[0], 'pbuild'], env=os.environ, cwd=os.path.dirname(FileList[0]))\r
+                p.communicate()\r
+                if p.returncode != 0:\r
+                    return p.returncode\r
+                for i in range(0, int(self.Opt.NUM)):\r
+                    self.Sem.release()\r
+            else:\r
+                print "There isn't makefile in %s.\n" % DestDir\r
                 return 1\r
-    return 0\r
 \r
+    def SameTypeFileInDir(FileNum, FileType, Dir):\r
+        if FileNum >= 2:\r
+            print "There are %d %s files in %s.\n" % (FileNum, FileType, CurWorkDir)\r
+            self.CalculateTime()\r
+            sys.exit(1)\r
+\r
+    def TrackInfo(self):\r
+        if self.Opt.debug != None:\r
+            last_type, last_value, last_tb = sys.exc_info()\r
+            traceback.print_exception(last_type, last_value, last_tb)\r
+\r
+    def GenCFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
+        try:\r
+            AutoGenResult = AutoGen(ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch)\r
+            AutoGenResult.CreateAutoGenFile()\r
+        except Exception, e:\r
+            TrackInfo()\r
+            print e\r
+            return 1\r
+\r
+    def GenMakeFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
+        try:\r
+            AutoGenResult = AutoGen(ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch)\r
+            AutoGenResult.CreateAutoGenFile()\r
+            makefile = AutoGenResult.CreateMakefile()\r
+        except Exception, e:\r
+            TrackInfo()\r
+            print e\r
+            return 1\r
+\r
+\r
+    def CleanAllFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
+        for d in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
+            if ModuleFile == None:\r
+                DestDir = os.environ["WORKSPACE"] + '\\' + d.replace('/','\\') + '\\' + Target + '_' + ToolChain\r
+            else:\r
+                (filename, ext) = os.path.splitext(os.environ["WORKSPACE"] + '\\' + d.replace('/','\\') + '\\' + Target + '_' + ToolChain + '\\' + Arch + '\\' + ModuleFile)\r
+                DestDir = filename\r
+            FileList = glob.glob(DestDir + '\\makefile')\r
+            FileNum = len(FileList)\r
+            if FileNum > 0:\r
+                SameTypeFileInDir(FileNum, 'makefile', DestDir, StartTime)\r
+                p = Popen(["nmake", "/nologo", "-f", FileList[0], 'cleanall'], env=os.environ, cwd=os.path.dirname(FileList[0]))\r
+                p.communicate()\r
+                if p.returncode != None:\r
+                    return p.returncode\r
+            else:\r
+                return 1\r
+\r
+    def ALLFunc(self, ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch):\r
+        try:\r
+            AutoGenResult = AutoGen(ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch)\r
+            AutoGenResult.CreateAutoGenFile()\r
+            makefile = AutoGenResult.CreateMakefile()\r
+        except Exception, e:\r
+            TrackInfo()\r
+            print e\r
+            return 1\r
+        if makefile != "":\r
+            p = Popen(["nmake", "/nologo", "-f", makefile, 'all'], env=os.environ, cwd=os.path.dirname(makefile))\r
+            p.communicate()\r
+            if p.returncode != None:\r
+                return p.returncode\r
+        else:\r
+            print "Can find Makefile.\n"\r
+            return 1\r
+\r
+\r
+    def Process(self, ModuleFile, PlatformFile, ewb):\r
+\r
+        #\r
+        # Merge Arch\r
+        #\r
+        self.Opt.TARGET_ARCH = list(set(self.Opt.TARGET_ARCH) & set(ewb.SupArchList))\r
+\r
+        GenC = 0\r
+        GenMake = 0\r
+        CleanAll = 0\r
+        for t in self.Args:\r
+            t = t.lower()\r
+            if t == 'genc':\r
+                GenC = 1\r
+            elif t == 'genmake':\r
+                GenMake = 1\r
+            elif t == 'cleanall':\r
+                CleanAll = 1\r
+\r
+        if self.Opt.spawn == True:\r
+            for a in self.Opt.TARGET:\r
+                for b in self.Opt.TOOL_CHAIN_TAG:\r
+                    if ModuleFile == None:\r
+                        PlatformAutoGen = AutoGen(None, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
+                        print "PlatformAutoGen : %s", PlatformFile\r
+                        for c in self.Opt.TARGET_ARCH:\r
+                            li = []\r
+                            for d in PlatformAutoGen.Platform[c].Modules:\r
+                                if ewb.InfDatabase[d].Defines.DefinesDictionary['LIBRARY_CLASS'] == ['']:\r
+                                    print "Module : %s, Arch : %s" % (d, c)\r
+                                    ModuleAutoGen = AutoGen(d, PlatformFile, ewb, a, b, c)\r
+                                    for e in ModuleAutoGen.BuildInfo.DependentLibraryList:\r
+                                        print "Library: %s, Arch : %s" % (e, c)\r
+                                        if e in li:\r
+                                            continue\r
+                                        else:\r
+                                            li.append(e)\r
+                                        self.LibBuild(e, PlatformFile, ewb, a, b, c)\r
+                                    self.ModuleBuild(d, PlatformFile, ewb, a, b, c, ModuleAutoGen)\r
+                                else:\r
+                                    self.LibBuild(d, PlatformFile, ewb, a, b, c)\r
+\r
+                        PlatformAutoGen.CreateAutoGenFile()\r
+                        PlatformAutoGen.CreateMakefile()\r
+                        for i in range(0, int(self.Opt.NUM)):\r
+                            Sem.acquire()\r
+                        print "successful"\r
+                        for i in range(0, int(self.Opt.NUM)):\r
+                            Sem.release()\r
+                            \r
+                        # call GenFds\r
+                        #GenFds -f C:\Work\Temp\T1\Nt32Pkg\Nt32Pkg.fdf -o $(BUILD_DIR) -p Nt32Pkg\Nt32Pkg.dsc\r
+                        if self.Opt.FDFFILE != '':\r
+                            self.Opt.FDFFILE =  os.environ["WORKSPACE"] + '\\' + self.Opt.FDFFILE.replace('/','\\')\r
+                            f = ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']\r
+                            f = os.environ["WORKSPACE"] + '\\' + f.replace('/', '\\') + '\\' + a + '_' + b\r
+                            if os.path.isdir(f + "\\" + "FV") != True:\r
+                                os.mkdir(f + "\\" + "FV")\r
+                            p = Popen(["GenFds", "-f", self.Opt.FDFFILE, "-o", f, "-p", self.Opt.DSCFILE], env=os.environ, cwd=os.path.dirname(self.Opt.FDFFILE))\r
+                            p.communicate()\r
+                            if p.returncode != 0:\r
+                                return p.returncode\r
+\r
+                    else:\r
+                        for c in self.Opt.TARGET_ARCH:\r
+                            ModuleAutoGen = AutoGen(ModuleFile, PlatformFile, ewb, a, b, c)\r
+                            print "ModuleAutoGen : %s"  % ModuleFile\r
+                            for e in ModuleAutoGen.BuildInfo.DependentLibraryList:\r
+                                print "Library: %s" % stre\r
+                                self.LibBuild(e, PlatformFile, ewb, a, b, c)\r
+                            self.ModuleBuild(ModuleFile, PlatformFile, ewb, a, b, c, ModuleAutoGen)\r
+            return 0\r
+\r
+    # normal build\r
+        for a in self.Opt.TARGET:\r
+            for b in self.Opt.TOOL_CHAIN_TAG:\r
+                if ModuleFile == None:\r
+                    if GenC == 1:\r
+                        self.GenCFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
+                    elif GenMake == 1:\r
+                        self.GenMakeFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
+                    elif CleanAll == 1:\r
+                        self.CleanAllFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
+                    else:\r
+                        self.ALLFunc(ModuleFile, PlatformFile, ewb, a, b, self.Opt.TARGET_ARCH)\r
+                else:\r
+                    for c in self.Opt.TARGET_ARCH:\r
+                        if GenC == 1:\r
+                            self.GenCFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
+                        elif GenMake == 1:\r
+                            self.GenMakeFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
+                        elif CleanAll == 1:\r
+                            self.CleanAllFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
+                        else:\r
+                            self.ALLFunc(ModuleFile, PlatformFile, ewb, a, b, c)\r
+        return 0\r
+\r
+    def CalculateTime(self):\r
+        print time.strftime("Current time is %a, %d %b %Y %H:%M:%S +0000", time.localtime())\r
+        Hour = 0\r
+        Min = 0\r
+        Sec = int(time.time() - self.StartTime)\r
+        Hour = Sec/3600\r
+        Min = (Sec%3600)/60\r
+        Sec = (Sec%3600)%60\r
+        if Hour < 10 and Min < 10 and Sec < 10:\r
+            print "Totol Run Time is 0%d:0%d:0%d" %(Hour, Min, Sec)\r
+        elif Hour < 10 and Min < 10 and Sec > 10:\r
+            print "Totol Run Time is 0%d:0%d:%2d" %(Hour, Min, Sec)\r
+        elif Hour < 10 and Min > 10 and Sec < 10:\r
+            print "Totol Run Time is 0%d:%2d:0%d" %(Hour, Min, Sec)\r
+        elif Hour < 10 and Min > 10 and Sec > 10:\r
+            print "Totol Run Time is 0%d:%2d:%2d" %(Hour, Min, Sec)\r
+        elif Hour > 10 and Min < 10 and Sec < 10:\r
+            print "Totol Run Time is %2d:0%d:0%d" %(Hour, Min, Sec)\r
+        elif Hour > 10 and Min < 10 and Sec > 10:\r
+            print "Totol Run Time is %2d:0%d:%2d" %(Hour, Min, Sec)\r
+        elif Hour > 10 and Min > 10 and Sec < 10:\r
+            print "Totol Run Time is %2d:%2d:0%d" %(Hour, Min, Sec)\r
+        elif Hour > 10 and Min < 10 and Sec > 10:\r
+            print "Totol Run Time is %2d:%2d:0%d" %(Hour, Min, Sec)\r
 \r
 def MyOptionParser():\r
     parser = OptionParser(description=__copyright__,version=__version__,prog="bld.exe",usage="%prog [options] [target]")\r
-    parser.add_option("-a", "--arch", action="append", type="choice", choices=[str('IA32'),"X64","IPF","EBC"], dest="TARGET_ARCH",\r
+    parser.add_option("-a", "--arch", action="append", type="choice", choices=['IA32','X64','IPF','EBC'], dest="TARGET_ARCH",\r
         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
     parser.add_option("-p", "--platform", action="store", type="string", dest="DSCFILE",\r
         help="Build the platform specified by the DSC file name argument, over rides the ACTIVE_PLATFORM")\r
     parser.add_option("-m", "--module", action="store", type="string", dest="INFFILE",\r
         help="Build the module specified by the INF file name argument.")\r
     parser.add_option("-b", "--buildtarget", action="append", type="choice", choices=['DEBUG','RELEASE'], dest="TARGET",\r
-        help="Build the platform using the BuildTarget, overrides target.txt?s TARGET definition.")\r
+        help="Build the platform using the BuildTarget, overrides target.txt's TARGET definition.")\r
     parser.add_option("-t", "--tagname", action="append", type="string", dest="TOOL_CHAIN_TAG",\r
-        help="Build the platform using the Tool chain, Tagname, overrides target.txt?s TOOL_CHAIN_TAG definition.")\r
+        help="Build the platform using the Tool chain, Tagname, overrides target.txt's TOOL_CHAIN_TAG definition.")\r
     parser.add_option("-s", "--spawn", action="store_true", type=None,\r
         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
     parser.add_option("-n", action="store", type="int", dest="NUM",\r
-        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
+        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
     parser.add_option("-f", "--fdf", action="store", type="string", dest="FDFFILE",\r
         help="The name of the FDF file to use, over-riding the setting in the DSC file.")\r
     parser.add_option("-k", "--msft", action="store_true", type=None, help="Make Option: Generate only NMAKE Makefiles: Makefile")\r
     parser.add_option("-g", "--gcc", action="store_true", type=None, help="Make Option: Generate only GMAKE Makefiles: GNUmakefile")\r
     parser.add_option("-l", "--all", action="store_true", type=None, help="Make Option: Generate both NMAKE and GMAKE makefiles.")\r
+    parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
+    parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
+    parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
+\r
     (opt, args)=parser.parse_args()\r
     return (opt, args)\r
 \r
-def Process(ModuleFile, PlatformFile, ewb, Target, ToolChain, Arch, args):\r
-    GenC = set(['GenC']) & set(args)\r
-    GenMake = set(['GenMake']) & set(args)\r
-    CleanAll = set(['CleanAll']) & set(args)\r
-    t = str(' '.join(args))\r
-\r
-    for a in Target:\r
-        for b in ToolChain:\r
-            for c in Arch:\r
-                try:\r
-                    ModuleAutoGen = AutoGen(ModuleFile, PlatformFile, ewb, str(a), b, str(c))\r
-                except Exception, e:\r
-                    print e\r
-                    return 1\r
-                if GenC != set([]):\r
-                    try:\r
-                        ModuleAutoGen.CreateAutoGenFile()\r
-                    except Exception, e:\r
-                        print e\r
-                        return 1\r
-                elif GenMake != set([]):\r
-                    try:\r
-                        ModuleAutoGen.CreateAutoGenFile()\r
-                        makefile = ModuleAutoGen.CreateMakefile()\r
-                    except Exception, e:\r
-                        print e\r
-                        return 1\r
-                elif CleanAll != set([]):\r
-                    if ModuleFile != None:\r
-                        for d in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
-                            DestDir = os.path.dirname(os.environ["WORKSPACE"] + '\\' + d.replace('/','\\') + '\\' + a + '_' + b + '\\' + c + '\\' + ModuleFile)\r
-                            DestDir = DestDir + '\\' + ewb.InfDatabase[ModuleFile].Defines.DefinesDictionary['BASE_NAME'][0]\r
-                    else:\r
-                        for d in ewb.DscDatabase[PlatformFile].Defines.DefinesDictionary['OUTPUT_DIRECTORY']:\r
-                            DestDir = os.environ["WORKSPACE"] + '\\' + d.replace('/','\\') + '\\' + a + '_' + b\r
-                        \r
-                    FileList = glob.glob(DestDir + '\\makefile')\r
-                    FileNum = len(FileList)\r
-                    if FileNum > 0:\r
-                        if FileNum >= 2:\r
-                            print "There are %d makefilss in %s.\n" % (FileNum, DestDir)\r
-                            return 1\r
-                        p = Popen(["nmake", "/nologo", "-f", FileList[0], t], env=os.environ, cwd=os.path.dirname(FileList[0]))\r
-                        p.communicate()\r
-                        if p.returncode != None:\r
-                            return p.returncode\r
-                    return 1\r
-                else:\r
-                    try:\r
-                        ModuleAutoGen.CreateAutoGenFile()\r
-                        makefile = ModuleAutoGen.CreateMakefile()\r
-                    except Exception, e:\r
-                        print e\r
-                        return 1\r
-                    if makefile != "":\r
-                        p = Popen(["nmake", "/nologo", "-f", makefile, t], env=os.environ, cwd=os.path.dirname(makefile))\r
-                        p.communicate()\r
-                        if p.returncode != None:\r
-                            return p.returncode\r
-                    else:\r
-                        print "Can find Makefile.\n"\r
-                        return 1\r
-    return 0\r
-\r
-def CalculateTime(StartTime):\r
-    print time.strftime("Current time is %a, %d %b %Y %H:%M:%S +0000", time.localtime())\r
-    Hour = 0\r
-    Min = 0\r
-    Sec = int(time.time() - StartTime)\r
-    Hour = Sec/3600\r
-    Min = (Sec%3600)/60\r
-    Sec = (Sec%3600)%60\r
-    if Hour < 10 and Min < 10 and Sec < 10:\r
-        print "Totol Run Time is 0%d:0%d:0%d" %(Hour, Min, Sec)\r
-    elif Hour < 10 and Min < 10 and Sec > 10:\r
-        print "Totol Run Time is 0%d:0%d:%2d" %(Hour, Min, Sec)\r
-    elif Hour < 10 and Min > 10 and Sec < 10:\r
-        print "Totol Run Time is 0%d:%2d:0%d" %(Hour, Min, Sec)\r
-    elif Hour < 10 and Min > 10 and Sec > 10:\r
-        print "Totol Run Time is 0%d:%2d:%2d" %(Hour, Min, Sec)\r
-    elif Hour > 10 and Min < 10 and Sec < 10:\r
-        print "Totol Run Time is %2d:0%d:0%d" %(Hour, Min, Sec)\r
-    elif Hour > 10 and Min < 10 and Sec > 10:\r
-        print "Totol Run Time is %2d:0%d:%2d" %(Hour, Min, Sec)\r
-    elif Hour > 10 and Min > 10 and Sec < 10:\r
-        print "Totol Run Time is %2d:%2d:0%d" %(Hour, Min, Sec)\r
-    elif Hour > 10 and Min < 10 and Sec > 10:\r
-        print "Totol Run Time is %2d:%2d:0%d" %(Hour, Min, Sec)\r
 \r
-if __name__ == '__main__':\r
-#\r
-# Record Start Time\r
-#\r
-    StartTime = time.time()\r
-    print time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime())\r
-#\r
-# Check environment variable: EDK_TOOLS_PATH, WORKSPACE, PATH\r
-#\r
-    StatusCode = CheckEnvVariable()\r
-    if StatusCode != 0:\r
-        CalculateTime(StartTime)\r
-        sys.exit(StatusCode)\r
 \r
-# be compatibile with Ant build.bat ???\r
 \r
+if __name__ == '__main__':\r
 #\r
 # Parse the options and args\r
 #\r
@@ -249,75 +397,110 @@ if __name__ == '__main__':
         (opt, args) = MyOptionParser()\r
     except Exception, e:\r
         print e\r
-        CalculateTime(StartTime)\r
         sys.exit(1)\r
+\r
 #\r
-# Call Parser\r
+# Check environment variable: EDK_TOOLS_PATH, WORKSPACE, PATH\r
 #\r
-    try:\r
-        ewb = WorkspaceBuild(opt.DSCFILE)  #opt.DSCFILE is relative path plus filename\r
-    except Exception, e:\r
-        print e\r
-        CalculateTime(StartTime)\r
-        sys.exit(1)\r
+    build = Build(opt, args)\r
+    StatusCode = build.CheckEnvVariable()\r
+    if StatusCode != 0:\r
+        build.CalculateTime()\r
+        sys.exit(StatusCode)\r
+\r
 #\r
-# Merge the Build Options with Parser's Result\r
+# Check target.txt and tools_def.txt and Init them\r
 #\r
-    if opt.TARGET_ARCH == None:\r
-        opt.TARGET_ARCH = ewb.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET_ARCH]\r
-        if opt.TARGET_ARCH == ['']:\r
-            print "TARGET_ARCH is None. Don't What to Build.\n"\r
-            CalculateTime(StartTime)\r
+    if os.path.isfile(build.WorkSpace + '\\Conf\\target.txt') == True:\r
+        StatusCode =build.TargetTxt.LoadTargetTxtFile(build.WorkSpace + '\\Conf\\target.txt')\r
+        if os.path.isfile(build.WorkSpace + '\\' + build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]) == True:\r
+            StatusCode = build.ToolDef.LoadToolDefFile(build.WorkSpace + '\\' + build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF])\r
+        else:\r
+            print "%s is not existed." % build.WorkSpace + '\\' + build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
+            build.CalculateTime()\r
             sys.exit(1)\r
+    else:\r
+        print "%s is not existed." % build.WorkSpace + '\\Conf\\target.txt'\r
+        build.CalculateTime()\r
+        sys.exit(1)\r
+\r
+#\r
+# Merge the Build Options\r
+#\r
+    if build.Opt.TARGET_ARCH == None:\r
+        build.Opt.TARGET_ARCH = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET_ARCH]\r
+        if build.Opt.TARGET_ARCH == ['']:\r
+            build.Opt.TARGET_ARCH = ['IA32', 'X64', 'IPF', 'EBC']\r
     print "TARGET_ARCH is", " ".join(opt.TARGET_ARCH)\r
-            \r
-    if opt.DSCFILE == None:\r
-        opt.DSCFILE = ewb.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM][0]\r
-#        if opt.DSCFILE == '':\r
-#            print "ACTIVE_PLATFORM is None. Don't What to Build.\n"\r
-#            exit()\r
-    print "ACTIVE_PLATFORM is %s" % opt.DSCFILE\r
-\r
-    if opt.TARGET == None:\r
-        opt.TARGET = ewb.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]\r
-        if opt.TARGET == ['']:\r
-            print "TARGET is None. Don't What to Build.\n"\r
-            CalculateTime(StartTime)\r
-            sys.exit(1)\r
-    print "TARGET is", " ".join(opt.TARGET)\r
 \r
-    if opt.TOOL_CHAIN_TAG == None:\r
-        opt.TOOL_CHAIN_TAG = ewb.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
-        if opt.TOOL_CHAIN_TAG == ['']:\r
+    if build.Opt.DSCFILE == None:\r
+        build.Opt.DSCFILE = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM]\r
+    print "ACTIVE_PLATFORM is %s" % build.Opt.DSCFILE\r
+\r
+    if build.Opt.TARGET == None:\r
+        build.Opt.TARGET = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]\r
+        if build.Opt.TARGET == ['']:\r
+            build.Opt.TARGET_ARCH = ['DEBUG', 'RELEASE']\r
+    print "TARGET is", " ".join(build.Opt.TARGET)\r
+\r
+    if build.Opt.TOOL_CHAIN_TAG == None:\r
+        build.Opt.TOOL_CHAIN_TAG = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
+        if build.Opt.TOOL_CHAIN_TAG == '':\r
             print "TOOL_CHAIN_TAG is None. Don't What to Build.\n"\r
-            CalculateTime(StartTime)\r
+            build.CalculateTime()\r
             sys.exit(1)\r
-    print "TOOL_CHAIN_TAG is", " ".join(opt.TOOL_CHAIN_TAG)\r
+    print "TOOL_CHAIN_TAG is", build.Opt.TOOL_CHAIN_TAG\r
 \r
-    if opt.NUM == None:\r
-        opt.NUM = ewb.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER][0]\r
-    print "MAX_CONCURRENT_THREAD_NUMBER is", " ".join(opt.NUM)\r
+    if build.Opt.NUM == None:\r
+        build.Opt.NUM = build.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER]\r
+    if build.Opt.NUM == '':\r
+        build.Opt.NUM = 1\r
+    else:\r
+        build.Opt.NUM = int(build.Opt.NUM)\r
+    print "MAX_CONCURRENT_THREAD_NUMBER is", build.Opt.NUM\r
+    if build.Opt.spawn == True:\r
+        build.Sem = BoundedSemaphore(int(build.Opt.NUM))\r
+\r
+    if build.Opt.verbose != None:\r
+        EdkLogger.setLevel(EdkLogger.VERBOSE)\r
+    elif build.Opt.quiet != None:\r
+        EdkLogger.setLevel(EdkLogger.QUIET)\r
+    elif build.Opt.debug != None:\r
+        EdkLogger.setLevel(build.Opt.debug)\r
+    else:\r
+        EdkLogger.setLevel(EdkLogger.INFO)\r
 \r
-    if opt.FDFFILE == None and opt.DSCFILE != '':\r
-        opt.FDFFILE = ewb.DscDatabase[os.path.normpath(opt.DSCFILE)].Defines.DefinesDictionary[TAB_DSC_DEFINES_FLASH_DEFINITION][0]\r
-        if opt.FDFFILE == '':\r
-            pass\r
-    print "FDF FILE is", opt.FDFFILE\r
+#\r
+# Call Parser\r
+#\r
+    if (build.Opt.DSCFILE != None or build.Opt.DSCFILE != '') and os.path.isfile(build.WorkSpace + '\\' + build.Opt.DSCFILE) == False:\r
+        print "The input file: %s is not existed!", build.Opt.DSCFILE\r
+        build.CalculateTime()\r
+        sys.exit(1)\r
+    if build.Opt.FDFFILE != None and os.path.isfile(build.WorkSpace + '\\' + build.Opt.FDFFILE) == False:\r
+        print "The input file: %s is not existed!", build.Opt.FDFFILE\r
+        build.CalculateTime()\r
+        sys.exit(1)\r
+    try:\r
+        if build.Opt.DSCFILE != None and build.Opt.DSCFILE != '':\r
+            ewb = NewWorkspaceBuild(build.Opt.DSCFILE, build.WorkSpace)  #opt.DSCFILE is relative path plus filename\r
+    except Exception, e:\r
+        print e\r
+        build.CalculateTime()\r
+        sys.exit(1)\r
 \r
-    \r
 #\r
 # Platform Build or Module Build\r
 #\r
     CurWorkDir = os.getcwd()\r
 \r
-    if opt.INFFILE:\r
-        if opt.DSCFILE:\r
-            ModuleFile = opt.INFFILE\r
+    if build.Opt.INFFILE:\r
+        if build.Opt.DSCFILE:\r
+            ModuleFile = build.Opt.INFFILE\r
             print "MODULE build:", ModuleFile\r
-            PlatformFile = str(os.path.normpath(opt.DSCFILE))\r
-            print os.path.normpath(opt.DSCFILE)\r
+            PlatformFile = str(os.path.normpath(build.Opt.DSCFILE))\r
             print "PlatformFile is:", PlatformFile\r
-            StatusCode = Process(ModuleFile, PlatformFile, ewb, opt.TARGET, opt.TOOL_CHAIN_TAG, opt.TARGET_ARCH, args)\r
+            StatusCode = build.Process(ModuleFile, PlatformFile, ewb, build.Opt)\r
         else:\r
             print "ERROR: DON'T KNOW WHAT TO BUILD\n"\r
     elif len(glob.glob(CurWorkDir + '\\*.inf')) > 0:\r
@@ -326,19 +509,21 @@ if __name__ == '__main__':
         if FileNum >= 2:\r
             print "There are %d INF filss in %s.\n" % (FileNum, CurWorkDir)\r
             sys.exit(1)\r
-        if opt.DSCFILE:\r
-            ModuleFile = FileList[0][len(ewb.Workspace.WorkspaceDir)+1:]\r
+        if build.Opt.DSCFILE:\r
+            if ewb.Workspace.WorkspaceDir[len(ewb.Workspace.WorkspaceDir)-1] == '\\':\r
+                ModuleFile = FileList[0][len(ewb.Workspace.WorkspaceDir):]\r
+            else:\r
+                ModuleFile = FileList[0][len(ewb.Workspace.WorkspaceDir)+1:]\r
             print "Module build:", ModuleFile\r
-            PlatformFile = str(os.path.normpath(opt.DSCFILE))\r
-            print os.path.normpath(opt.DSCFILE)\r
+            PlatformFile = str(os.path.normpath(build.Opt.DSCFILE))\r
             print "PlatformFile is:", PlatformFile\r
-            StatusCode = Process(ModuleFile, PlatformFile, ewb, opt.TARGET, opt.TOOL_CHAIN_TAG, opt.TARGET_ARCH, args)\r
+            StatusCode = build.Process(ModuleFile, PlatformFile, ewb)\r
         else:\r
             print "ERROR: DON'T KNOW WHAT TO BUILD\n"\r
-    elif opt.DSCFILE:\r
-        PlatformFile = os.path.normpath(opt.DSCFILE)\r
+    elif build.Opt.DSCFILE:\r
+        PlatformFile = os.path.normpath(build.Opt.DSCFILE)\r
         print "Platform build:", PlatformFile\r
-        StatusCode = Process(None, PlatformFile, ewb, opt.TARGET, opt.TOOL_CHAIN_TAG, opt.TARGET_ARCH, args)\r
+        StatusCode = build.Process(None, PlatformFile, ewb)\r
     else:\r
         FileList = glob.glob(CurWorkDir + '\\*.dsc')\r
         FileNum = len(FileList)\r
@@ -346,21 +531,23 @@ if __name__ == '__main__':
             if FileNum >= 2:\r
                 print "There are %d DSC files in %s.\n" % (FileNum, CurWorkDir)\r
                 sys.exit(1)\r
-            PlatformFile = FileList[0][len(ewb.Workspace.WorkspaceDir)+1:]\r
+            if os.environ('WORKSPACE')[len(os.environ('WORKSPACE'))-1] == '\\':\r
+                PlatformFile = FileList[0][len(os.environ('WORKSPACE')):]\r
+            else:\r
+                PlatformFile = FileList[0][len(os.environ('WORKSPACE'))+1:]\r
             print "Platform build:", PlatformFile\r
             #\r
             # Call Parser Again\r
             #\r
-            ewb = WorkspaceBuild(PlatformFile)\r
-            StatusCode = Process(None, PlatformFile, ewb, opt.TARGET, opt.TOOL_CHAIN_TAG, opt.TARGET_ARCH, args)\r
-\r
+            ewb = NewWorkspaceBuild(PlatformFile, build.WorkSpace)\r
+            StatusCode = build.Process(None, PlatformFile, ewb)\r
         else:\r
             print "ERROR: DON'T KNOW WHAT TO BUILD\n"\r
 \r
 #\r
 # Record Build Process Time\r
 #\r
-    CalculateTime(StartTime)\r
+    build.CalculateTime()\r
 \r
 # To Do: add a judgement for return code\r
     sys.exit(StatusCode)\r