]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/AutoGen/AutoGenWorker.py
BaseTools: Fixed the bug of multi-thread genffs for override inf
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGenWorker.py
CommitLineData
673d09a2
FB
1## @file\r
2# Create makefile for MS nmake and GNU make\r
3#\r
4# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
5# SPDX-License-Identifier: BSD-2-Clause-Patent\r
6#\r
7from __future__ import absolute_import\r
8import multiprocessing as mp\r
9import threading\r
10from Common.Misc import PathClass\r
11from AutoGen.ModuleAutoGen import ModuleAutoGen\r
12from AutoGen.ModuleAutoGenHelper import WorkSpaceInfo,AutoGenInfo\r
13import Common.GlobalData as GlobalData\r
14import Common.EdkLogger as EdkLogger\r
15import os\r
16from Common.MultipleWorkspace import MultipleWorkspace as mws\r
17from AutoGen.AutoGen import AutoGen\r
18from Workspace.WorkspaceDatabase import BuildDB\r
4acae2b3
FB
19try:\r
20 from queue import Empty\r
21except:\r
22 from Queue import Empty\r
673d09a2
FB
23import traceback\r
24import sys\r
25from AutoGen.DataPipe import MemoryDataPipe\r
1a624dd7
FB
26import logging\r
27\r
673d09a2
FB
28def clearQ(q):\r
29 try:\r
30 while True:\r
31 q.get_nowait()\r
32 except Empty:\r
33 pass\r
636ed13a
FB
34\r
35class LogAgent(threading.Thread):\r
36 def __init__(self,log_q,log_level,log_file=None):\r
37 super(LogAgent,self).__init__()\r
38 self.log_q = log_q\r
39 self.log_level = log_level\r
40 self.log_file = log_file\r
41 def InitLogger(self):\r
42 # For DEBUG level (All DEBUG_0~9 are applicable)\r
43 self._DebugLogger_agent = logging.getLogger("tool_debug_agent")\r
44 _DebugFormatter = logging.Formatter("[%(asctime)s.%(msecs)d]: %(message)s", datefmt="%H:%M:%S")\r
45 self._DebugLogger_agent.setLevel(self.log_level)\r
46 _DebugChannel = logging.StreamHandler(sys.stdout)\r
47 _DebugChannel.setFormatter(_DebugFormatter)\r
48 self._DebugLogger_agent.addHandler(_DebugChannel)\r
49\r
50 # For VERBOSE, INFO, WARN level\r
51 self._InfoLogger_agent = logging.getLogger("tool_info_agent")\r
52 _InfoFormatter = logging.Formatter("%(message)s")\r
53 self._InfoLogger_agent.setLevel(self.log_level)\r
54 _InfoChannel = logging.StreamHandler(sys.stdout)\r
55 _InfoChannel.setFormatter(_InfoFormatter)\r
56 self._InfoLogger_agent.addHandler(_InfoChannel)\r
57\r
58 # For ERROR level\r
59 self._ErrorLogger_agent = logging.getLogger("tool_error_agent")\r
60 _ErrorFormatter = logging.Formatter("%(message)s")\r
61 self._ErrorLogger_agent.setLevel(self.log_level)\r
62 _ErrorCh = logging.StreamHandler(sys.stderr)\r
63 _ErrorCh.setFormatter(_ErrorFormatter)\r
64 self._ErrorLogger_agent.addHandler(_ErrorCh)\r
65\r
66 if self.log_file:\r
67 if os.path.exists(self.log_file):\r
68 os.remove(self.log_file)\r
69 _Ch = logging.FileHandler(self.log_file)\r
70 _Ch.setFormatter(_DebugFormatter)\r
71 self._DebugLogger_agent.addHandler(_Ch)\r
72\r
73 _Ch= logging.FileHandler(self.log_file)\r
74 _Ch.setFormatter(_InfoFormatter)\r
75 self._InfoLogger_agent.addHandler(_Ch)\r
76\r
77 _Ch = logging.FileHandler(self.log_file)\r
78 _Ch.setFormatter(_ErrorFormatter)\r
79 self._ErrorLogger_agent.addHandler(_Ch)\r
80\r
81 def run(self):\r
82 self.InitLogger()\r
83 while True:\r
84 log_message = self.log_q.get()\r
85 if log_message is None:\r
86 break\r
87 if log_message.name == "tool_error":\r
88 self._ErrorLogger_agent.log(log_message.levelno,log_message.getMessage())\r
89 elif log_message.name == "tool_info":\r
90 self._InfoLogger_agent.log(log_message.levelno,log_message.getMessage())\r
91 elif log_message.name == "tool_debug":\r
92 self._DebugLogger_agent.log(log_message.levelno,log_message.getMessage())\r
93 else:\r
94 self._InfoLogger_agent.log(log_message.levelno,log_message.getMessage())\r
95\r
96 def kill(self):\r
97 self.log_q.put(None)\r
673d09a2
FB
98class AutoGenManager(threading.Thread):\r
99 def __init__(self,autogen_workers, feedback_q,error_event):\r
100 super(AutoGenManager,self).__init__()\r
101 self.autogen_workers = autogen_workers\r
102 self.feedback_q = feedback_q\r
673d09a2
FB
103 self.Status = True\r
104 self.error_event = error_event\r
105 def run(self):\r
106 try:\r
107 fin_num = 0\r
108 while True:\r
109 badnews = self.feedback_q.get()\r
110 if badnews is None:\r
111 break\r
112 if badnews == "Done":\r
113 fin_num += 1\r
114 else:\r
115 self.Status = False\r
116 self.TerminateWorkers()\r
117 if fin_num == len(self.autogen_workers):\r
118 self.clearQueue()\r
119 for w in self.autogen_workers:\r
120 w.join()\r
121 break\r
122 except Exception:\r
123 return\r
124\r
125 def clearQueue(self):\r
126 taskq = self.autogen_workers[0].module_queue\r
1a624dd7 127 logq = self.autogen_workers[0].log_q\r
673d09a2
FB
128 clearQ(taskq)\r
129 clearQ(self.feedback_q)\r
1a624dd7 130 clearQ(logq)\r
673d09a2
FB
131 def TerminateWorkers(self):\r
132 self.error_event.set()\r
133 def kill(self):\r
134 self.feedback_q.put(None)\r
135class AutoGenWorkerInProcess(mp.Process):\r
94459080 136 def __init__(self,module_queue,data_pipe_file_path,feedback_q,file_lock,cache_lock,share_data,log_q,error_event):\r
673d09a2
FB
137 mp.Process.__init__(self)\r
138 self.module_queue = module_queue\r
139 self.data_pipe_file_path =data_pipe_file_path\r
140 self.data_pipe = None\r
141 self.feedback_q = feedback_q\r
142 self.PlatformMetaFileSet = {}\r
143 self.file_lock = file_lock\r
94459080 144 self.cache_lock = cache_lock\r
3285fbda 145 self.share_data = share_data\r
636ed13a 146 self.log_q = log_q\r
673d09a2
FB
147 self.error_event = error_event\r
148 def GetPlatformMetaFile(self,filepath,root):\r
149 try:\r
150 return self.PlatformMetaFileSet[(filepath,root)]\r
151 except:\r
152 self.PlatformMetaFileSet[(filepath,root)] = filepath\r
153 return self.PlatformMetaFileSet[(filepath,root)]\r
154 def run(self):\r
155 try:\r
156 taskname = "Init"\r
157 with self.file_lock:\r
158 if not os.path.exists(self.data_pipe_file_path):\r
159 self.feedback_q.put(taskname + ":" + "load data pipe %s failed." % self.data_pipe_file_path)\r
160 self.data_pipe = MemoryDataPipe()\r
161 self.data_pipe.load(self.data_pipe_file_path)\r
636ed13a 162 EdkLogger.LogClientInitialize(self.log_q)\r
673d09a2
FB
163 loglevel = self.data_pipe.Get("LogLevel")\r
164 if not loglevel:\r
165 loglevel = EdkLogger.INFO\r
166 EdkLogger.SetLevel(loglevel)\r
673d09a2
FB
167 target = self.data_pipe.Get("P_Info").get("Target")\r
168 toolchain = self.data_pipe.Get("P_Info").get("ToolChain")\r
169 archlist = self.data_pipe.Get("P_Info").get("ArchList")\r
170\r
171 active_p = self.data_pipe.Get("P_Info").get("ActivePlatform")\r
172 workspacedir = self.data_pipe.Get("P_Info").get("WorkspaceDir")\r
173 PackagesPath = os.getenv("PACKAGES_PATH")\r
174 mws.setWs(workspacedir, PackagesPath)\r
175 self.Wa = WorkSpaceInfo(\r
176 workspacedir,active_p,target,toolchain,archlist\r
177 )\r
178 self.Wa._SrcTimeStamp = self.data_pipe.Get("Workspace_timestamp")\r
179 GlobalData.gGlobalDefines = self.data_pipe.Get("G_defines")\r
180 GlobalData.gCommandLineDefines = self.data_pipe.Get("CL_defines")\r
181 os.environ._data = self.data_pipe.Get("Env_Var")\r
182 GlobalData.gWorkspace = workspacedir\r
183 GlobalData.gDisableIncludePathCheck = False\r
184 GlobalData.gFdfParser = self.data_pipe.Get("FdfParser")\r
185 GlobalData.gDatabasePath = self.data_pipe.Get("DatabasePath")\r
0e7e7a26
SS
186 GlobalData.gBinCacheSource = self.data_pipe.Get("BinCacheSource")\r
187 GlobalData.gBinCacheDest = self.data_pipe.Get("BinCacheDest")\r
94459080 188 GlobalData.gCacheIR = self.share_data\r
0e7e7a26
SS
189 GlobalData.gEnableGenfdsMultiThread = self.data_pipe.Get("EnableGenfdsMultiThread")\r
190 GlobalData.file_lock = self.file_lock\r
94459080 191 GlobalData.cache_lock = self.cache_lock\r
0e7e7a26 192 CommandTarget = self.data_pipe.Get("CommandTarget")\r
673d09a2
FB
193 pcd_from_build_option = []\r
194 for pcd_tuple in self.data_pipe.Get("BuildOptPcd"):\r
195 pcd_id = ".".join((pcd_tuple[0],pcd_tuple[1]))\r
196 if pcd_tuple[2].strip():\r
197 pcd_id = ".".join((pcd_id,pcd_tuple[2]))\r
198 pcd_from_build_option.append("=".join((pcd_id,pcd_tuple[3])))\r
199 GlobalData.BuildOptionPcd = pcd_from_build_option\r
200 module_count = 0\r
201 FfsCmd = self.data_pipe.Get("FfsCommand")\r
202 if FfsCmd is None:\r
203 FfsCmd = {}\r
0e7e7a26 204 GlobalData.FfsCmd = FfsCmd\r
673d09a2
FB
205 PlatformMetaFile = self.GetPlatformMetaFile(self.data_pipe.Get("P_Info").get("ActivePlatform"),\r
206 self.data_pipe.Get("P_Info").get("WorkspaceDir"))\r
207 libConstPcd = self.data_pipe.Get("LibConstPcd")\r
208 Refes = self.data_pipe.Get("REFS")\r
0e7e7a26
SS
209 GlobalData.libConstPcd = libConstPcd\r
210 GlobalData.Refes = Refes\r
673d09a2
FB
211 while True:\r
212 if self.module_queue.empty():\r
213 break\r
214 if self.error_event.is_set():\r
215 break\r
216 module_count += 1\r
217 module_file,module_root,module_path,module_basename,module_originalpath,module_arch,IsLib = self.module_queue.get_nowait()\r
218 modulefullpath = os.path.join(module_root,module_file)\r
219 taskname = " : ".join((modulefullpath,module_arch))\r
220 module_metafile = PathClass(module_file,module_root)\r
221 if module_path:\r
222 module_metafile.Path = module_path\r
223 if module_basename:\r
224 module_metafile.BaseName = module_basename\r
225 if module_originalpath:\r
226 module_metafile.OriginalPath = PathClass(module_originalpath,module_root)\r
227 arch = module_arch\r
228 target = self.data_pipe.Get("P_Info").get("Target")\r
229 toolchain = self.data_pipe.Get("P_Info").get("ToolChain")\r
230 Ma = ModuleAutoGen(self.Wa,module_metafile,target,toolchain,arch,PlatformMetaFile,self.data_pipe)\r
231 Ma.IsLibrary = IsLib\r
232 if IsLib:\r
233 if (Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path) in libConstPcd:\r
234 Ma.ConstPcd = libConstPcd[(Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path)]\r
235 if (Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path) in Refes:\r
236 Ma.ReferenceModules = Refes[(Ma.MetaFile.File,Ma.MetaFile.Root,Ma.Arch,Ma.MetaFile.Path)]\r
0e7e7a26
SS
237 if GlobalData.gBinCacheSource and CommandTarget in [None, "", "all"]:\r
238 Ma.GenModuleFilesHash(GlobalData.gCacheIR)\r
239 Ma.GenPreMakefileHash(GlobalData.gCacheIR)\r
240 if Ma.CanSkipbyPreMakefileCache(GlobalData.gCacheIR):\r
373298ca 241 continue\r
0e7e7a26 242\r
673d09a2 243 Ma.CreateCodeFile(False)\r
e3c8311f 244 Ma.CreateMakeFile(False,GenFfsList=FfsCmd.get((Ma.MetaFile.Path, Ma.Arch),[]))\r
0e7e7a26
SS
245\r
246 if GlobalData.gBinCacheSource and CommandTarget in [None, "", "all"]:\r
247 Ma.GenMakeHeaderFilesHash(GlobalData.gCacheIR)\r
248 Ma.GenMakeHash(GlobalData.gCacheIR)\r
249 if Ma.CanSkipbyMakeCache(GlobalData.gCacheIR):\r
250 continue\r
56c786b0
SS
251 else:\r
252 Ma.PrintFirstMakeCacheMissFile(GlobalData.gCacheIR)\r
673d09a2
FB
253 except Empty:\r
254 pass\r
255 except:\r
256 traceback.print_exc(file=sys.stdout)\r
257 self.feedback_q.put(taskname)\r
258 finally:\r
259 self.feedback_q.put("Done")\r
260 def printStatus(self):\r
261 print("Processs ID: %d Run %d modules in AutoGen " % (os.getpid(),len(AutoGen.Cache())))\r
262 print("Processs ID: %d Run %d modules in AutoGenInfo " % (os.getpid(),len(AutoGenInfo.GetCache())))\r
263 groupobj = {}\r
264 for buildobj in BuildDB.BuildObject.GetCache().values():\r
265 if str(buildobj).lower().endswith("dec"):\r
266 try:\r
267 groupobj['dec'].append(str(buildobj))\r
268 except:\r
269 groupobj['dec'] = [str(buildobj)]\r
270 if str(buildobj).lower().endswith("dsc"):\r
271 try:\r
272 groupobj['dsc'].append(str(buildobj))\r
273 except:\r
274 groupobj['dsc'] = [str(buildobj)]\r
275\r
276 if str(buildobj).lower().endswith("inf"):\r
277 try:\r
278 groupobj['inf'].append(str(buildobj))\r
279 except:\r
280 groupobj['inf'] = [str(buildobj)]\r
281\r
282 print("Processs ID: %d Run %d pkg in WDB " % (os.getpid(),len(groupobj.get("dec",[]))))\r
283 print("Processs ID: %d Run %d pla in WDB " % (os.getpid(),len(groupobj.get("dsc",[]))))\r
284 print("Processs ID: %d Run %d inf in WDB " % (os.getpid(),len(groupobj.get("inf",[]))))\r