X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2Fbuild%2Fbuild.py;h=e4adee2bebca101623369b7e4857a4c342ca6981;hp=8275f1b5b9d99e1a1af75a7ca0518d9b59592701;hb=f21547ff64a58909c85ce215531345f6f8364884;hpb=1b8eca8b1affc81357c9f685ac90e5de75ba4b87 diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 8275f1b5b9..e4adee2beb 100644 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -2,7 +2,7 @@ # build a platform or a module # # Copyright (c) 2014, Hewlett-Packard Development Company, L.P.
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -26,6 +26,7 @@ import platform import traceback import encodings.ascii import itertools +import multiprocessing from struct import * from threading import * @@ -50,6 +51,7 @@ from PatchPcdValue.PatchPcdValue import * import Common.EdkLogger import Common.GlobalData as GlobalData +from GenFds.GenFds import GenFds # Version and Copyright VersionNumber = "0.60" + ' ' + gBUILD_VERSION @@ -760,6 +762,8 @@ class Build(): self.SkipAutoGen = BuildOptions.SkipAutoGen self.Reparse = BuildOptions.Reparse self.SkuId = BuildOptions.SkuId + if self.SkuId: + GlobalData.gSKUID_CMD = self.SkuId self.ConfDirectory = BuildOptions.ConfDirectory self.SpawnMode = True self.BuildReport = BuildReport(BuildOptions.ReportFile, BuildOptions.ReportType) @@ -771,6 +775,37 @@ class Build(): GlobalData.BuildOptionPcd = BuildOptions.OptionPcd #Set global flag for build mode GlobalData.gIgnoreSource = BuildOptions.IgnoreSources + GlobalData.gUseHashCache = BuildOptions.UseHashCache + GlobalData.gBinCacheDest = BuildOptions.BinCacheDest + GlobalData.gBinCacheSource = BuildOptions.BinCacheSource + GlobalData.gEnableGenfdsMultiThread = BuildOptions.GenfdsMultiThread + + if GlobalData.gBinCacheDest and not GlobalData.gUseHashCache: + EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-destination must be used together with --hash.") + + if GlobalData.gBinCacheSource and not GlobalData.gUseHashCache: + EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-source must be used together with --hash.") + + if GlobalData.gBinCacheDest and GlobalData.gBinCacheSource: + EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-destination can not be used together with --binary-source.") + + if GlobalData.gBinCacheSource: + BinCacheSource = os.path.normpath(GlobalData.gBinCacheSource) + if not os.path.isabs(BinCacheSource): + BinCacheSource = mws.join(self.WorkspaceDir, BinCacheSource) + GlobalData.gBinCacheSource = BinCacheSource + else: + if GlobalData.gBinCacheSource != None: + EdkLogger.error("build", OPTION_VALUE_INVALID, ExtraData="Invalid value of option --binary-source.") + + if GlobalData.gBinCacheDest: + BinCacheDest = os.path.normpath(GlobalData.gBinCacheDest) + if not os.path.isabs(BinCacheDest): + BinCacheDest = mws.join(self.WorkspaceDir, BinCacheDest) + GlobalData.gBinCacheDest = BinCacheDest + else: + if GlobalData.gBinCacheDest != None: + EdkLogger.error("build", OPTION_VALUE_INVALID, ExtraData="Invalid value of option --binary-destination.") if self.ConfDirectory: # Get alternate Conf location, if it is absolute, then just use the absolute directory name @@ -799,6 +834,7 @@ class Build(): self.LoadFixAddress = 0 self.UniFlag = BuildOptions.Flag self.BuildModules = [] + self.HashSkipModules = [] self.Db_Flag = False self.LaunchPrebuildFlag = False self.PlatformBuildPath = os.path.join(GlobalData.gConfDirectory,'.cache', '.PlatformBuild') @@ -907,7 +943,10 @@ class Build(): self.ThreadNumber = int(self.ThreadNumber, 0) if self.ThreadNumber == 0: - self.ThreadNumber = 1 + try: + self.ThreadNumber = multiprocessing.cpu_count() + except (ImportError, NotImplementedError): + self.ThreadNumber = 1 if not self.PlatformFile: PlatformFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM] @@ -1184,7 +1223,7 @@ class Build(): # @param CreateDepModuleMakeFile Flag used to indicate creating makefile # for dependent modules/Libraries # - def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False): + def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False, FfsCommand={}): if AutoGenObject == None: return False @@ -1200,7 +1239,7 @@ class Build(): if not self.SkipAutoGen or Target == 'genmake': self.Progress.Start("Generating makefile") - AutoGenObject.CreateMakeFile(CreateDepsMakeFile) + AutoGenObject.CreateMakeFile(CreateDepsMakeFile, FfsCommand) self.Progress.Stop("done!") if Target == "genmake": return True @@ -1707,6 +1746,12 @@ class Build(): self.LoadFixAddress = Wa.Platform.LoadFixAddress self.BuildReport.AddPlatformReport(Wa) self.Progress.Stop("done!") + + # Add ffs build to makefile + CmdListDict = {} + if GlobalData.gEnableGenfdsMultiThread and self.Fdf: + CmdListDict = self._GenFfsCmd() + for Arch in Wa.ArchList: GlobalData.gGlobalDefines['ARCH'] = Arch Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch) @@ -1716,7 +1761,7 @@ class Build(): if Ma == None: continue self.BuildModules.append(Ma) - self._BuildPa(self.Target, Pa) + self._BuildPa(self.Target, Pa, FfsCommand=CmdListDict) # Create MAP file when Load Fix Address is enabled. if self.Target in ["", "all", "fds"]: @@ -1795,6 +1840,10 @@ class Build(): self.Fdf = Wa.FdfFile self.LoadFixAddress = Wa.Platform.LoadFixAddress Wa.CreateMakeFile(False) + # Add ffs build to makefile + CmdListDict = None + if GlobalData.gEnableGenfdsMultiThread and self.Fdf: + CmdListDict = self._GenFfsCmd() self.Progress.Stop("done!") MaList = [] ExitFlag = threading.Event() @@ -1805,10 +1854,24 @@ class Build(): GlobalData.gGlobalDefines['ARCH'] = Arch Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch) for Module in Pa.Platform.Modules: - if self.ModuleFile.Dir == Module.Dir and self.ModuleFile.File == Module.File: + if self.ModuleFile.Dir == Module.Dir and self.ModuleFile.Name == Module.Name: Ma = ModuleAutoGen(Wa, Module, BuildTarget, ToolChain, Arch, self.PlatformFile) if Ma == None: continue MaList.append(Ma) + if Ma.CanSkipbyHash(): + self.HashSkipModules.append(Ma) + continue + # Not to auto-gen for targets 'clean', 'cleanlib', 'cleanall', 'run', 'fds' + if self.Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']: + # for target which must generate AutoGen code and makefile + if not self.SkipAutoGen or self.Target == 'genc': + Ma.CreateCodeFile(True) + if not self.SkipAutoGen or self.Target == 'genmake': + if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict: + Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch]) + del CmdListDict[Module.File, Arch] + else: + Ma.CreateMakeFile(True) self.BuildModules.append(Ma) self.AutoGenTime += int(round((time.time() - AutoGenStart))) MakeStart = time.time() @@ -1891,6 +1954,17 @@ class Build(): # self._SaveMapFile (MapBuffer, Wa) + def _GenFfsCmd(self): + CmdListDict = {} + GenFfsDict = GenFds.GenFfsMakefile('', GlobalData.gFdfParser, self, self.ArchList, GlobalData) + for Cmd in GenFfsDict: + tmpInf, tmpArch = GenFfsDict[Cmd] + if (tmpInf, tmpArch) not in CmdListDict.keys(): + CmdListDict[tmpInf, tmpArch] = [Cmd] + else: + CmdListDict[tmpInf, tmpArch].append(Cmd) + return CmdListDict + ## Build a platform in multi-thread mode # def _MultiThreadBuildPlatform(self): @@ -1926,6 +2000,11 @@ class Build(): self.BuildReport.AddPlatformReport(Wa) Wa.CreateMakeFile(False) + # Add ffs build to makefile + CmdListDict = None + if GlobalData.gEnableGenfdsMultiThread and self.Fdf: + CmdListDict = self._GenFfsCmd() + # multi-thread exit flag ExitFlag = threading.Event() ExitFlag.clear() @@ -1952,6 +2031,10 @@ class Build(): if Ma == None: continue + if Ma.CanSkipbyHash(): + self.HashSkipModules.append(Ma) + continue + # Not to auto-gen for targets 'clean', 'cleanlib', 'cleanall', 'run', 'fds' if self.Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']: # for target which must generate AutoGen code and makefile @@ -1961,7 +2044,11 @@ class Build(): continue if not self.SkipAutoGen or self.Target == 'genmake': - Ma.CreateMakeFile(True) + if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict: + Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch]) + del CmdListDict[Module.File, Arch] + else: + Ma.CreateMakeFile(True) if self.Target == "genmake": continue self.BuildModules.append(Ma) @@ -2144,7 +2231,10 @@ class Build(): def CreateAsBuiltInf(self): for Module in self.BuildModules: Module.CreateAsBuiltInf() + for Module in self.HashSkipModules: + Module.CreateAsBuiltInf(True) self.BuildModules = [] + self.HashSkipModules = [] ## Do some clean-up works when error occurred def Relinquish(self): OldLogLevel = EdkLogger.GetLevel() @@ -2274,7 +2364,10 @@ def MyOptionParser(): Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files") Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ") Parser.add_option("-l", "--cmd-len", action="store", type="int", dest="CommandLength", help="Specify the maximum line length of build command. Default is 4096.") - + Parser.add_option("--hash", action="store_true", dest="UseHashCache", default=False, help="Enable hash-based caching during build process.") + Parser.add_option("--binary-destination", action="store", type="string", dest="BinCacheDest", help="Generate a cache of binary files in the specified directory.") + Parser.add_option("--binary-source", action="store", type="string", dest="BinCacheSource", help="Consume a cache of binary files from the specified directory.") + Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.") (Opt, Args) = Parser.parse_args() return (Opt, Args)