--- /dev/null
+## @file\r
+# Create makefile for MS nmake and GNU make\r
+#\r
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+from __future__ import absolute_import\r
+import multiprocessing as mp\r
+import threading\r
+from Common.Misc import PathClass\r
+from AutoGen.ModuleAutoGen import ModuleAutoGen\r
+from AutoGen.ModuleAutoGenHelper import WorkSpaceInfo,AutoGenInfo\r
+import Common.GlobalData as GlobalData\r
+import Common.EdkLogger as EdkLogger\r
+import os\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+from AutoGen.AutoGen import AutoGen\r
+from Workspace.WorkspaceDatabase import BuildDB\r
+from queue import Empty\r
+import traceback\r
+import sys\r
+from AutoGen.DataPipe import MemoryDataPipe\r
+def clearQ(q):\r
+ try:\r
+ while True:\r
+ q.get_nowait()\r
+ except Empty:\r
+ pass\r
+class AutoGenManager(threading.Thread):\r
+ def __init__(self,autogen_workers, feedback_q,error_event):\r
+ super(AutoGenManager,self).__init__()\r
+ self.autogen_workers = autogen_workers\r
+ self.feedback_q = feedback_q\r
+ self.terminate = False\r
+ self.Status = True\r
+ self.error_event = error_event\r
+ def run(self):\r
+ try:\r
+ fin_num = 0\r
+ while True:\r
+ badnews = self.feedback_q.get()\r
+ if badnews is None:\r
+ break\r
+ if badnews == "Done":\r
+ fin_num += 1\r
+ else:\r
+ self.Status = False\r
+ self.TerminateWorkers()\r
+ if fin_num == len(self.autogen_workers):\r
+ self.clearQueue()\r
+ for w in self.autogen_workers:\r
+ w.join()\r
+ break\r
+ except Exception:\r
+ return\r
+\r
+ def clearQueue(self):\r
+ taskq = self.autogen_workers[0].module_queue\r
+ clearQ(taskq)\r
+ clearQ(self.feedback_q)\r
+\r
+ def TerminateWorkers(self):\r
+ self.error_event.set()\r
+ def kill(self):\r
+ self.feedback_q.put(None)\r
+class AutoGenWorkerInProcess(mp.Process):\r
+ def __init__(self,module_queue,data_pipe_file_path,feedback_q,file_lock,error_event):\r
+ mp.Process.__init__(self)\r
+ self.module_queue = module_queue\r
+ self.data_pipe_file_path =data_pipe_file_path\r
+ self.data_pipe = None\r
+ self.feedback_q = feedback_q\r
+ self.PlatformMetaFileSet = {}\r
+ self.file_lock = file_lock\r
+ self.error_event = error_event\r
+ def GetPlatformMetaFile(self,filepath,root):\r
+ try:\r
+ return self.PlatformMetaFileSet[(filepath,root)]\r
+ except:\r
+ self.PlatformMetaFileSet[(filepath,root)] = filepath\r
+ return self.PlatformMetaFileSet[(filepath,root)]\r
+ def run(self):\r
+ try:\r
+ taskname = "Init"\r
+ with self.file_lock:\r
+ if not os.path.exists(self.data_pipe_file_path):\r
+ self.feedback_q.put(taskname + ":" + "load data pipe %s failed." % self.data_pipe_file_path)\r
+ self.data_pipe = MemoryDataPipe()\r
+ self.data_pipe.load(self.data_pipe_file_path)\r
+ EdkLogger.Initialize()\r
+ loglevel = self.data_pipe.Get("LogLevel")\r
+ if not loglevel:\r
+ loglevel = EdkLogger.INFO\r
+ EdkLogger.SetLevel(loglevel)\r
+ logfile = self.data_pipe.Get("LogFile")\r
+ if logfile:\r
+ EdkLogger.SetLogFile(logfile)\r
+ target = self.data_pipe.Get("P_Info").get("Target")\r
+ toolchain = self.data_pipe.Get("P_Info").get("ToolChain")\r
+ archlist = self.data_pipe.Get("P_Info").get("ArchList")\r
+\r
+ active_p = self.data_pipe.Get("P_Info").get("ActivePlatform")\r
+ workspacedir = self.data_pipe.Get("P_Info").get("WorkspaceDir")\r
+ PackagesPath = os.getenv("PACKAGES_PATH")\r
+ mws.setWs(workspacedir, PackagesPath)\r
+ self.Wa = WorkSpaceInfo(\r
+ workspacedir,active_p,target,toolchain,archlist\r
+ )\r
+ self.Wa._SrcTimeStamp = self.data_pipe.Get("Workspace_timestamp")\r
+ GlobalData.gGlobalDefines = self.data_pipe.Get("G_defines")\r
+ GlobalData.gCommandLineDefines = self.data_pipe.Get("CL_defines")\r
+ os.environ._data = self.data_pipe.Get("Env_Var")\r
+ GlobalData.gWorkspace = workspacedir\r
+ GlobalData.gDisableIncludePathCheck = False\r
+ GlobalData.gFdfParser = self.data_pipe.Get("FdfParser")\r
+ GlobalData.gDatabasePath = self.data_pipe.Get("DatabasePath")\r
+ pcd_from_build_option = []\r
+ for pcd_tuple in self.data_pipe.Get("BuildOptPcd"):\r
+ pcd_id = ".".join((pcd_tuple[0],pcd_tuple[1]))\r
+ if pcd_tuple[2].strip():\r
+ pcd_id = ".".join((pcd_id,pcd_tuple[2]))\r
+ pcd_from_build_option.append("=".join((pcd_id,pcd_tuple[3])))\r
+ GlobalData.BuildOptionPcd = pcd_from_build_option\r
+ module_count = 0\r
+ FfsCmd = self.data_pipe.Get("FfsCommand")\r
+ if FfsCmd is None:\r
+ FfsCmd = {}\r
+ PlatformMetaFile = self.GetPlatformMetaFile(self.data_pipe.Get("P_Info").get("ActivePlatform"),\r
+ self.data_pipe.Get("P_Info").get("WorkspaceDir"))\r
+ libConstPcd = self.data_pipe.Get("LibConstPcd")\r
+ Refes = self.data_pipe.Get("REFS")\r
+ while True:\r
+ if self.module_queue.empty():\r
+ break\r
+ if self.error_event.is_set():\r
+ break\r
+ module_count += 1\r
+ module_file,module_root,module_path,module_basename,module_originalpath,module_arch,IsLib = self.module_queue.get_nowait()\r
+ modulefullpath = os.path.join(module_root,module_file)\r
+ taskname = " : ".join((modulefullpath,module_arch))\r
+ module_metafile = PathClass(module_file,module_root)\r
+ if module_path:\r
+ module_metafile.Path = module_path\r
+ if module_basename:\r
+ module_metafile.BaseName = module_basename\r
+ if module_originalpath:\r
+ module_metafile.OriginalPath = PathClass(module_originalpath,module_root)\r
+ arch = module_arch\r
+ target = self.data_pipe.Get("P_Info").get("Target")\r
+ toolchain = self.data_pipe.Get("P_Info").get("ToolChain")\r
+ Ma = ModuleAutoGen(self.Wa,module_metafile,target,toolchain,arch,PlatformMetaFile,self.data_pipe)\r
+ Ma.IsLibrary = IsLib\r
+ if IsLib:\r
+ if (Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path) in libConstPcd:\r
+ Ma.ConstPcd = libConstPcd[(Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path)]\r
+ if (Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path) in Refes:\r
+ Ma.ReferenceModules = Refes[(Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path)]\r
+ Ma.CreateCodeFile(False)\r
+ Ma.CreateMakeFile(False,GenFfsList=FfsCmd.get((Ma.MetaFile.File, Ma.Arch),[]))\r
+ except Empty:\r
+ pass\r
+ except:\r
+ traceback.print_exc(file=sys.stdout)\r
+ self.feedback_q.put(taskname)\r
+ finally:\r
+ self.feedback_q.put("Done")\r
+ def printStatus(self):\r
+ print("Processs ID: %d Run %d modules in AutoGen " % (os.getpid(),len(AutoGen.Cache())))\r
+ print("Processs ID: %d Run %d modules in AutoGenInfo " % (os.getpid(),len(AutoGenInfo.GetCache())))\r
+ groupobj = {}\r
+ for buildobj in BuildDB.BuildObject.GetCache().values():\r
+ if str(buildobj).lower().endswith("dec"):\r
+ try:\r
+ groupobj['dec'].append(str(buildobj))\r
+ except:\r
+ groupobj['dec'] = [str(buildobj)]\r
+ if str(buildobj).lower().endswith("dsc"):\r
+ try:\r
+ groupobj['dsc'].append(str(buildobj))\r
+ except:\r
+ groupobj['dsc'] = [str(buildobj)]\r
+\r
+ if str(buildobj).lower().endswith("inf"):\r
+ try:\r
+ groupobj['inf'].append(str(buildobj))\r
+ except:\r
+ groupobj['inf'] = [str(buildobj)]\r
+\r
+ print("Processs ID: %d Run %d pkg in WDB " % (os.getpid(),len(groupobj.get("dec",[]))))\r
+ print("Processs ID: %d Run %d pla in WDB " % (os.getpid(),len(groupobj.get("dsc",[]))))\r
+ print("Processs ID: %d Run %d inf in WDB " % (os.getpid(),len(groupobj.get("inf",[]))))\r
import os\r
import pickle\r
from pickle import HIGHEST_PROTOCOL\r
+from Common import EdkLogger\r
\r
class PCD_DATA():\r
def __init__(self,TokenCName,TokenSpaceGuidCName,Type,DatumType,SkuInfoList,DefaultValue,\r
def __init__(self, BuildDir=None):\r
self.data_container = {}\r
self.BuildDir = BuildDir\r
+ self.dump_file = ""\r
\r
class MemoryDataPipe(DataPipe):\r
\r
return self.data_container.get(key)\r
\r
def dump(self,file_path):\r
+ self.dump_file = file_path\r
with open(file_path,'wb') as fd:\r
pickle.dump(self.data_container,fd,pickle.HIGHEST_PROTOCOL)\r
\r
for m in PlatformInfo.Platform.Modules:\r
m_pcds = PlatformInfo.Platform.Modules[m].Pcds\r
if m_pcds:\r
- ModulePcds[(m.File,m.Root)] = [PCD_DATA(\r
+ ModulePcds[(m.File,m.Root,m.Arch)] = [PCD_DATA(\r
pcd.TokenCName,pcd.TokenSpaceGuidCName,pcd.Type,\r
pcd.DatumType,pcd.SkuInfoList,pcd.DefaultValue,\r
pcd.MaxDatumSize,pcd.UserDefinedDefaultStoresFlag,pcd.validateranges,\r
\r
#Module's Library Instance\r
ModuleLibs = {}\r
+ libModules = {}\r
for m in PlatformInfo.Platform.Modules:\r
module_obj = BuildDB.BuildObject[m,PlatformInfo.Arch,PlatformInfo.BuildTarget,PlatformInfo.ToolChain]\r
Libs = GetModuleLibInstances(module_obj, PlatformInfo.Platform, BuildDB.BuildObject, PlatformInfo.Arch,PlatformInfo.BuildTarget,PlatformInfo.ToolChain)\r
- ModuleLibs[(m.File,m.Root,module_obj.Arch)] = [(l.MetaFile.File,l.MetaFile.Root,l.Arch) for l in Libs]\r
+ for lib in Libs:\r
+ try:\r
+ libModules[(lib.MetaFile.File,lib.MetaFile.Root,lib.Arch,lib.MetaFile.Path)].append((m.File,m.Root,module_obj.Arch,m.Path))\r
+ except:\r
+ libModules[(lib.MetaFile.File,lib.MetaFile.Root,lib.Arch,lib.MetaFile.Path)] = [(m.File,m.Root,module_obj.Arch,m.Path)]\r
+ ModuleLibs[(m.File,m.Root,module_obj.Arch,m.Path)] = [(l.MetaFile.File,l.MetaFile.Root,l.Arch,l.MetaFile.Path) for l in Libs]\r
self.DataContainer = {"DEPS":ModuleLibs}\r
+ self.DataContainer = {"REFS":libModules}\r
\r
#Platform BuildOptions\r
\r
\r
self.DataContainer = {"GuidDict": PlatformInfo.Platform._GuidDict}\r
\r
+ self.DataContainer = {"DatabasePath":GlobalData.gDatabasePath}\r
self.DataContainer = {"FdfParser": True if GlobalData.gFdfParser else False}\r
\r
+ self.DataContainer = {"LogLevel": EdkLogger.GetLevel()}\r
+ self.DataContainer = {"LogFile": GlobalData.gOptions.LogFile if GlobalData.gOptions.LogFile is not None else ""}\r
\r
if Info.ModuleType in [SUP_MODULE_PEI_CORE, SUP_MODULE_DXE_CORE, SUP_MODULE_SMM_CORE, SUP_MODULE_MM_CORE_STANDALONE]:\r
if Info.SourceFileList:\r
- if NumEntryPoints != 1:\r
- EdkLogger.error(\r
+ if NumEntryPoints != 1:\r
+ EdkLogger.error(\r
"build",\r
AUTOGEN_ERROR,\r
'%s must have exactly one entry point' % Info.ModuleType,\r
if not self.IsLibrary and CreateLibraryMakeFile:\r
for LibraryAutoGen in self.LibraryAutoGenList:\r
LibraryAutoGen.CreateMakeFile()\r
+\r
# Don't enable if hash feature enabled, CanSkip uses timestamps to determine build skipping\r
if not GlobalData.gUseHashCache and self.CanSkip():\r
return\r
if not self.IsLibrary and CreateLibraryCodeFile:\r
for LibraryAutoGen in self.LibraryAutoGenList:\r
LibraryAutoGen.CreateCodeFile()\r
-\r
# Don't enable if hash feature enabled, CanSkip uses timestamps to determine build skipping\r
if not GlobalData.gUseHashCache and self.CanSkip():\r
return\r
self.DataPipe.FillData(self)\r
\r
return True\r
+ def FillData_LibConstPcd(self):\r
+ libConstPcd = {}\r
+ for LibAuto in self.LibraryAutoGenList:\r
+ if LibAuto.ConstPcd:\r
+ libConstPcd[(LibAuto.MetaFile.File,LibAuto.MetaFile.Root,LibAuto.Arch,LibAuto.MetaFile.Path)] = LibAuto.ConstPcd\r
+ self.DataPipe.DataContainer = {"LibConstPcd":libConstPcd}\r
## hash() operator of PlatformAutoGen\r
#\r
# The platform file path and arch string will be used to represent\r
return\r
\r
for Ma in self.ModuleAutoGenList:\r
- Ma.CreateCodeFile(True)\r
+ Ma.CreateCodeFile(CreateModuleCodeFile)\r
\r
## Generate Fds Command\r
@cached_property\r
for Ma in self._MaList:\r
key = (Ma.MetaFile.File, self.Arch)\r
if key in FfsCommand:\r
- Ma.CreateMakeFile(True, FfsCommand[key])\r
+ Ma.CreateMakeFile(CreateModuleMakeFile, FfsCommand[key])\r
else:\r
- Ma.CreateMakeFile(True)\r
+ Ma.CreateMakeFile(CreateModuleMakeFile)\r
\r
# no need to create makefile for the platform more than once\r
if self.IsMakeFileCreated:\r
Libs = GetModuleLibInstances(module_obj, self.Platform, self.BuildDatabase, self.Arch,self.BuildTarget,self.ToolChain)\r
else:\r
Libs = []\r
- ModuleLibs.update( set([(l.MetaFile.File,l.MetaFile.Root,l.Arch,True) for l in Libs]))\r
+ ModuleLibs.update( set([(l.MetaFile.File,l.MetaFile.Root,l.MetaFile.Path,l.MetaFile.BaseName,l.MetaFile.OriginalPath,l.Arch,True) for l in Libs]))\r
if WithoutPcd and module_obj.PcdIsDriver:\r
continue\r
- ModuleLibs.add((m.File,m.Root,module_obj.Arch,False))\r
+ ModuleLibs.add((m.File,m.Root,m.Path,m.BaseName,m.OriginalPath,module_obj.Arch,bool(module_obj.LibraryClass)))\r
\r
return ModuleLibs\r
\r
self.ProcessMixedPcd()\r
self.VerifyPcdsFromFDF()\r
self.CollectAllPcds()\r
+ for Pa in self.AutoGenObjectList:\r
+ Pa.FillData_LibConstPcd()\r
self.GeneratePkgLevelHash()\r
#\r
# Check PCDs token value conflict in each DEC file.\r
if not CreateDepsMakeFile:\r
return\r
for Pa in self.AutoGenObjectList:\r
- Pa.CreateMakeFile(True)\r
+ Pa.CreateMakeFile(CreateDepsMakeFile)\r
\r
## Create autogen code for platform and modules\r
#\r
if not CreateDepsCodeFile:\r
return\r
for Pa in self.AutoGenObjectList:\r
- Pa.CreateCodeFile(True)\r
+ Pa.CreateCodeFile(CreateDepsCodeFile)\r
\r
## Create AsBuilt INF file the platform\r
#\r
from AutoGen.PlatformAutoGen import PlatformAutoGen\r
from AutoGen.ModuleAutoGen import ModuleAutoGen\r
from AutoGen.WorkspaceAutoGen import WorkspaceAutoGen\r
+from AutoGen.AutoGenWorker import AutoGenWorkerInProcess,AutoGenManager\r
from AutoGen import GenMake\r
from Common import Misc as Utils\r
\r
\r
import Common.GlobalData as GlobalData\r
from GenFds.GenFds import GenFds, GenFdsApi\r
-\r
+import multiprocessing as mp\r
\r
# Version and Copyright\r
VersionNumber = "0.60" + ' ' + gBUILD_VERSION\r
# @param Obj The ModuleAutoGen object the build is working on\r
# @param Target The build target name, one of gSupportedTarget\r
#\r
- def __init__(self, Obj, Target):\r
- Dependency = [ModuleMakeUnit(La, Target) for La in Obj.LibraryAutoGenList]\r
- BuildUnit.__init__(self, Obj, Obj.BuildCommand, Target, Dependency, Obj.MakeFileDir)\r
+ def __init__(self, Obj, BuildCommand,Target):\r
+ Dependency = [ModuleMakeUnit(La, BuildCommand,Target) for La in Obj.LibraryAutoGenList]\r
+ BuildUnit.__init__(self, Obj, BuildCommand, Target, Dependency, Obj.MakeFileDir)\r
if Target in [None, "", "all"]:\r
self.Target = "tbuild"\r
\r
# @param Obj The PlatformAutoGen object the build is working on\r
# @param Target The build target name, one of gSupportedTarget\r
#\r
- def __init__(self, Obj, Target):\r
- Dependency = [ModuleMakeUnit(Lib, Target) for Lib in self.BuildObject.LibraryAutoGenList]\r
- Dependency.extend([ModuleMakeUnit(Mod, Target) for Mod in self.BuildObject.ModuleAutoGenList])\r
- BuildUnit.__init__(self, Obj, Obj.BuildCommand, Target, Dependency, Obj.MakeFileDir)\r
+ def __init__(self, Obj, BuildCommand, Target):\r
+ Dependency = [ModuleMakeUnit(Lib, BuildCommand, Target) for Lib in self.BuildObject.LibraryAutoGenList]\r
+ Dependency.extend([ModuleMakeUnit(Mod, BuildCommand,Target) for Mod in self.BuildObject.ModuleAutoGenList])\r
+ BuildUnit.__init__(self, Obj, BuildCommand, Target, Dependency, Obj.MakeFileDir)\r
\r
## The class representing the task of a module build or platform build\r
#\r
if not (self.LaunchPrebuildFlag and os.path.exists(self.PlatformBuildPath)):\r
self.InitBuild()\r
\r
+ self.AutoGenMgr = None\r
EdkLogger.info("")\r
os.chdir(self.WorkspaceDir)\r
+ def StartAutoGen(self,mqueue, DataPipe,SkipAutoGen,PcdMaList):\r
+ try:\r
+ if SkipAutoGen:\r
+ return True,0\r
+ feedback_q = mp.Queue()\r
+ file_lock = mp.Lock()\r
+ error_event = mp.Event()\r
+ auto_workers = [AutoGenWorkerInProcess(mqueue,DataPipe.dump_file,feedback_q,file_lock,error_event) for _ in range(self.ThreadNumber)]\r
+ self.AutoGenMgr = AutoGenManager(auto_workers,feedback_q,error_event)\r
+ self.AutoGenMgr.start()\r
+ for w in auto_workers:\r
+ w.start()\r
+ if PcdMaList is not None:\r
+ for PcdMa in PcdMaList:\r
+ PcdMa.CreateCodeFile(False)\r
+ PcdMa.CreateMakeFile(False,GenFfsList = DataPipe.Get("FfsCommand").get((PcdMa.MetaFile.File, PcdMa.Arch),[]))\r
+\r
+ self.AutoGenMgr.join()\r
+ rt = self.AutoGenMgr.Status\r
+ return rt, 0\r
+ except Exception as e:\r
+ return False,e.errcode\r
\r
## Load configuration\r
#\r
# @param CreateDepModuleMakeFile Flag used to indicate creating makefile\r
# for dependent modules/Libraries\r
#\r
- def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False, FfsCommand={}):\r
+ def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False, FfsCommand=None, PcdMaList=None):\r
if AutoGenObject is None:\r
return False\r
-\r
+ if FfsCommand is None:\r
+ FfsCommand = {}\r
# skip file generation for cleanxxx targets, run and fds target\r
if Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:\r
# for target which must generate AutoGen code and makefile\r
- if not self.SkipAutoGen or Target == 'genc':\r
- self.Progress.Start("Generating code")\r
- AutoGenObject.CreateCodeFile(CreateDepsCodeFile)\r
- self.Progress.Stop("done!")\r
- if Target == "genc":\r
- return True\r
-\r
- if not self.SkipAutoGen or Target == 'genmake':\r
- self.Progress.Start("Generating makefile")\r
- AutoGenObject.CreateMakeFile(CreateDepsMakeFile, FfsCommand)\r
- self.Progress.Stop("done!")\r
- if Target == "genmake":\r
- return True\r
- else:\r
- # always recreate top/platform makefile when clean, just in case of inconsistency\r
+ mqueue = mp.Queue()\r
+ for m in AutoGenObject.GetAllModuleInfo:\r
+ mqueue.put(m)\r
+\r
+ AutoGenObject.DataPipe.DataContainer = {"FfsCommand":FfsCommand}\r
+ self.Progress.Start("Generating makefile and code")\r
+ data_pipe_file = os.path.join(AutoGenObject.BuildDir, "GlobalVar_%s_%s.bin" % (str(AutoGenObject.Guid),AutoGenObject.Arch))\r
+ AutoGenObject.DataPipe.dump(data_pipe_file)\r
+ autogen_rt,errorcode = self.StartAutoGen(mqueue, AutoGenObject.DataPipe, self.SkipAutoGen, PcdMaList)\r
+ self.Progress.Stop("done!")\r
+ if not autogen_rt:\r
+ self.AutoGenMgr.TerminateWorkers()\r
+ self.AutoGenMgr.join(0.1)\r
+ raise FatalError(errorcode)\r
AutoGenObject.CreateCodeFile(False)\r
AutoGenObject.CreateMakeFile(False)\r
+ else:\r
+ # always recreate top/platform makefile when clean, just in case of inconsistency\r
+ AutoGenObject.CreateCodeFile(True)\r
+ AutoGenObject.CreateMakeFile(True)\r
\r
if EdkLogger.GetLevel() == EdkLogger.QUIET:\r
EdkLogger.quiet("Building ... %s" % repr(AutoGenObject))\r
return True\r
else:\r
# always recreate top/platform makefile when clean, just in case of inconsistency\r
- AutoGenObject.CreateCodeFile(False)\r
- AutoGenObject.CreateMakeFile(False)\r
+ AutoGenObject.CreateCodeFile(True)\r
+ AutoGenObject.CreateMakeFile(True)\r
\r
if EdkLogger.GetLevel() == EdkLogger.QUIET:\r
EdkLogger.quiet("Building ... %s" % repr(AutoGenObject))\r
continue\r
if Ma.PcdIsDriver:\r
Ma.PlatformInfo = Pa\r
+ Ma.Workspace = Wa\r
PcdMaList.append(Ma)\r
self.BuildModules.append(Ma)\r
- self._BuildPa(self.Target, Pa, FfsCommand=CmdListDict)\r
+ self._BuildPa(self.Target, Pa, FfsCommand=CmdListDict,PcdMaList=PcdMaList)\r
\r
# Create MAP file when Load Fix Address is enabled.\r
if self.Target in ["", "all", "fds"]:\r
MakeStart = time.time()\r
for Ma in self.BuildModules:\r
if not Ma.IsBinaryModule:\r
- Bt = BuildTask.New(ModuleMakeUnit(Ma, self.Target))\r
+ Bt = BuildTask.New(ModuleMakeUnit(Ma, Pa.BuildCommand,self.Target))\r
# Break build if any build thread has error\r
if BuildTask.HasError():\r
# we need a full version of makefile for platform\r
Wa.CreateMakeFile(False)\r
\r
# Add ffs build to makefile\r
- CmdListDict = None\r
+ CmdListDict = {}\r
if GlobalData.gEnableGenfdsMultiThread and self.Fdf:\r
CmdListDict = self._GenFfsCmd(Wa.ArchList)\r
\r
ExitFlag = threading.Event()\r
ExitFlag.clear()\r
self.AutoGenTime += int(round((time.time() - WorkspaceAutoGenTime)))\r
+ self.BuildModules = []\r
for Arch in Wa.ArchList:\r
PcdMaList = []\r
AutoGenStart = time.time()\r
if Inf in Pa.Platform.Modules:\r
continue\r
ModuleList.append(Inf)\r
+ Pa.DataPipe.DataContainer = {"FfsCommand":CmdListDict}\r
+ Pa.DataPipe.DataContainer = {"Workspace_timestamp": Wa._SrcTimeStamp}\r
for Module in ModuleList:\r
# Get ModuleAutoGen object to generate C code file and makefile\r
Ma = ModuleAutoGen(Wa, Module, BuildTarget, ToolChain, Arch, self.PlatformFile,Pa.DataPipe)\r
continue\r
if Ma.PcdIsDriver:\r
Ma.PlatformInfo = Pa\r
+ Ma.Workspace = Wa\r
PcdMaList.append(Ma)\r
if Ma.CanSkipbyHash():\r
self.HashSkipModules.append(Ma)\r
EdkLogger.quiet("cache miss: %s[%s]" % (Ma.MetaFile.Path, Ma.Arch))\r
\r
# Not to auto-gen for targets 'clean', 'cleanlib', 'cleanall', 'run', 'fds'\r
- if self.Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:\r
# for target which must generate AutoGen code and makefile\r
- if not self.SkipAutoGen or self.Target == 'genc':\r
- Ma.CreateCodeFile(True)\r
- if self.Target == "genc":\r
- continue\r
\r
- if not self.SkipAutoGen or self.Target == 'genmake':\r
- if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict:\r
- Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch])\r
- del CmdListDict[Module.File, Arch]\r
- else:\r
- Ma.CreateMakeFile(True)\r
- if self.Target == "genmake":\r
- continue\r
self.BuildModules.append(Ma)\r
# Initialize all modules in tracking to 'FAIL'\r
if Ma.Arch not in GlobalData.gModuleBuildTracking:\r
GlobalData.gModuleBuildTracking[Ma.Arch] = dict()\r
if Ma not in GlobalData.gModuleBuildTracking[Ma.Arch]:\r
GlobalData.gModuleBuildTracking[Ma.Arch][Ma] = 'FAIL'\r
+ mqueue = mp.Queue()\r
+ for m in Pa.GetAllModuleInfo:\r
+ mqueue.put(m)\r
+ data_pipe_file = os.path.join(Pa.BuildDir, "GlobalVar_%s_%s.bin" % (str(Pa.Guid),Pa.Arch))\r
+ Pa.DataPipe.dump(data_pipe_file)\r
+ autogen_rt, errorcode = self.StartAutoGen(mqueue, Pa.DataPipe, self.SkipAutoGen, PcdMaList)\r
self.Progress.Stop("done!")\r
self.AutoGenTime += int(round((time.time() - AutoGenStart)))\r
+ if not autogen_rt:\r
+ self.AutoGenMgr.TerminateWorkers()\r
+ self.AutoGenMgr.join(0.1)\r
+ raise FatalError(errorcode)\r
+ for Arch in Wa.ArchList:\r
MakeStart = time.time()\r
for Ma in self.BuildModules:\r
# Generate build task for the module\r
if not Ma.IsBinaryModule:\r
- Bt = BuildTask.New(ModuleMakeUnit(Ma, self.Target))\r
+ Bt = BuildTask.New(ModuleMakeUnit(Ma, Pa.BuildCommand,self.Target))\r
# Break build if any build thread has error\r
if BuildTask.HasError():\r
# we need a full version of makefile for platform\r
EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
ReturnCode = FORMAT_INVALID\r
except KeyboardInterrupt:\r
+ if MyBuild is not None:\r
+\r
+ # for multi-thread build exits safely\r
+ MyBuild.Relinquish()\r
ReturnCode = ABORT_ERROR\r
if Option is not None and Option.debug is not None:\r
EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())\r
return ReturnCode\r
\r
if __name__ == '__main__':\r
+ try:\r
+ mp.set_start_method('spawn')\r
+ except:\r
+ pass\r
r = Main()\r
## 0-127 is a safe return range, and 1 is a standard default error\r
if r < 0 or r > 127: r = 1\r