]>
Commit | Line | Data |
---|---|---|
52302d4d LG |
1 | ## @file\r |
2 | # This file is used to create a database used by build tool\r | |
3 | #\r | |
b9a6d9d7 | 4 | # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r |
77177984 | 5 | # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r |
2e351cbe | 6 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r |
52302d4d LG |
7 | #\r |
8 | \r | |
9 | ##\r | |
10 | # Import Modules\r | |
11 | #\r | |
1ccc4d89 | 12 | from __future__ import absolute_import\r |
5a57246e | 13 | from Common.StringUtils import *\r |
52302d4d LG |
14 | from Common.DataType import *\r |
15 | from Common.Misc import *\r | |
16 | from types import *\r | |
17 | \r | |
1100bc5a GL |
18 | from .MetaDataTable import *\r |
19 | from .MetaFileTable import *\r | |
20 | from .MetaFileParser import *\r | |
52302d4d | 21 | \r |
ae7b6df8 LG |
22 | from Workspace.DecBuildData import DecBuildData\r |
23 | from Workspace.DscBuildData import DscBuildData\r | |
24 | from Workspace.InfBuildData import InfBuildData\r | |
52302d4d LG |
25 | \r |
26 | ## Database\r | |
27 | #\r | |
e56468c0 | 28 | # This class defined the build database for all modules, packages and platform.\r |
52302d4d LG |
29 | # It will call corresponding parser for the given file if it cannot find it in\r |
30 | # the database.\r | |
31 | #\r | |
32 | # @param DbPath Path of database file\r | |
33 | # @param GlobalMacros Global macros used for replacement during file parsing\r | |
fb0b35e0 | 34 | # @param RenewDb=False Create new database file if it's already there\r |
52302d4d LG |
35 | #\r |
36 | class WorkspaceDatabase(object):\r | |
52302d4d | 37 | \r |
52302d4d LG |
38 | #\r |
39 | # internal class used for call corresponding file parser and caching the result\r | |
40 | # to avoid unnecessary re-parsing\r | |
41 | #\r | |
42 | class BuildObjectFactory(object):\r | |
0d2711a6 | 43 | \r |
52302d4d LG |
44 | _FILE_TYPE_ = {\r |
45 | ".inf" : MODEL_FILE_INF,\r | |
46 | ".dec" : MODEL_FILE_DEC,\r | |
47 | ".dsc" : MODEL_FILE_DSC,\r | |
0d2711a6 LG |
48 | }\r |
49 | \r | |
50 | # file parser\r | |
51 | _FILE_PARSER_ = {\r | |
52 | MODEL_FILE_INF : InfParser,\r | |
53 | MODEL_FILE_DEC : DecParser,\r | |
54 | MODEL_FILE_DSC : DscParser,\r | |
52302d4d LG |
55 | }\r |
56 | \r | |
57 | # convert to xxxBuildData object\r | |
58 | _GENERATOR_ = {\r | |
59 | MODEL_FILE_INF : InfBuildData,\r | |
60 | MODEL_FILE_DEC : DecBuildData,\r | |
61 | MODEL_FILE_DSC : DscBuildData,\r | |
52302d4d LG |
62 | }\r |
63 | \r | |
64 | _CACHE_ = {} # (FilePath, Arch) : <object>\r | |
e8449e1d FB |
65 | def GetCache(self):\r |
66 | return self._CACHE_\r | |
52302d4d LG |
67 | \r |
68 | # constructor\r | |
69 | def __init__(self, WorkspaceDb):\r | |
70 | self.WorkspaceDb = WorkspaceDb\r | |
71 | \r | |
0d2711a6 | 72 | # key = (FilePath, Arch=None)\r |
52302d4d LG |
73 | def __contains__(self, Key):\r |
74 | FilePath = Key[0]\r | |
52302d4d LG |
75 | if len(Key) > 1:\r |
76 | Arch = Key[1]\r | |
0d2711a6 LG |
77 | else:\r |
78 | Arch = None\r | |
52302d4d LG |
79 | return (FilePath, Arch) in self._CACHE_\r |
80 | \r | |
fb0b35e0 | 81 | # key = (FilePath, Arch=None, Target=None, Toolchain=None)\r |
52302d4d LG |
82 | def __getitem__(self, Key):\r |
83 | FilePath = Key[0]\r | |
0d2711a6 LG |
84 | KeyLength = len(Key)\r |
85 | if KeyLength > 1:\r | |
52302d4d | 86 | Arch = Key[1]\r |
0d2711a6 LG |
87 | else:\r |
88 | Arch = None\r | |
89 | if KeyLength > 2:\r | |
90 | Target = Key[2]\r | |
91 | else:\r | |
92 | Target = None\r | |
93 | if KeyLength > 3:\r | |
94 | Toolchain = Key[3]\r | |
95 | else:\r | |
96 | Toolchain = None\r | |
52302d4d LG |
97 | \r |
98 | # if it's generated before, just return the cached one\r | |
0d2711a6 | 99 | Key = (FilePath, Arch, Target, Toolchain)\r |
52302d4d LG |
100 | if Key in self._CACHE_:\r |
101 | return self._CACHE_[Key]\r | |
102 | \r | |
103 | # check file type\r | |
34e733f2 FB |
104 | BuildObject = self.CreateBuildObject(FilePath, Arch, Target, Toolchain)\r |
105 | self._CACHE_[Key] = BuildObject\r | |
106 | return BuildObject\r | |
107 | def CreateBuildObject(self,FilePath, Arch, Target, Toolchain):\r | |
0d2711a6 | 108 | Ext = FilePath.Type\r |
52302d4d LG |
109 | if Ext not in self._FILE_TYPE_:\r |
110 | return None\r | |
111 | FileType = self._FILE_TYPE_[Ext]\r | |
112 | if FileType not in self._GENERATOR_:\r | |
113 | return None\r | |
114 | \r | |
0d2711a6 LG |
115 | # get the parser ready for this file\r |
116 | MetaFile = self._FILE_PARSER_[FileType](\r | |
f7496d71 LG |
117 | FilePath,\r |
118 | FileType,\r | |
cdd1b5e5 | 119 | Arch,\r |
2f818ed0 | 120 | MetaFileStorage(self.WorkspaceDb, FilePath, FileType)\r |
0d2711a6 | 121 | )\r |
fb0b35e0 | 122 | # always do post-process, in case of macros change\r |
0d2711a6 LG |
123 | MetaFile.DoPostProcess()\r |
124 | # object the build is based on\r | |
52302d4d LG |
125 | BuildObject = self._GENERATOR_[FileType](\r |
126 | FilePath,\r | |
127 | MetaFile,\r | |
128 | self,\r | |
129 | Arch,\r | |
0d2711a6 LG |
130 | Target,\r |
131 | Toolchain\r | |
52302d4d | 132 | )\r |
52302d4d LG |
133 | return BuildObject\r |
134 | \r | |
135 | # placeholder for file format conversion\r | |
136 | class TransformObjectFactory:\r | |
137 | def __init__(self, WorkspaceDb):\r | |
138 | self.WorkspaceDb = WorkspaceDb\r | |
139 | \r | |
140 | # key = FilePath, Arch\r | |
141 | def __getitem__(self, Key):\r | |
142 | pass\r | |
143 | \r | |
144 | ## Constructor of WorkspaceDatabase\r | |
145 | #\r | |
146 | # @param DbPath Path of database file\r | |
147 | # @param GlobalMacros Global macros used for replacement during file parsing\r | |
fb0b35e0 | 148 | # @param RenewDb=False Create new database file if it's already there\r |
52302d4d | 149 | #\r |
2f818ed0 B |
150 | def __init__(self):\r |
151 | self.DB = dict()\r | |
52302d4d | 152 | # create table for internal uses\r |
2f818ed0 B |
153 | self.TblDataModel = DataClass.MODEL_LIST\r |
154 | self.TblFile = []\r | |
0d2711a6 | 155 | self.Platform = None\r |
52302d4d LG |
156 | \r |
157 | # conversion object for build or file format conversion purpose\r | |
158 | self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r | |
159 | self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r | |
160 | \r | |
2f818ed0 | 161 | def SetFileTimeStamp(self,FileId,TimeStamp):\r |
643556fc | 162 | self.TblFile[FileId-1][6] = TimeStamp\r |
f7496d71 | 163 | \r |
2f818ed0 | 164 | def GetFileTimeStamp(self,FileId):\r |
643556fc | 165 | return self.TblFile[FileId-1][6]\r |
f7496d71 | 166 | \r |
52302d4d | 167 | \r |
52302d4d | 168 | ## Summarize all packages in the database\r |
0d2711a6 LG |
169 | def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r |
170 | self.Platform = Platform\r | |
47fea6af | 171 | PackageList = []\r |
b9a6d9d7 | 172 | Pa = self.BuildObject[self.Platform, Arch, TargetName, ToolChainTag]\r |
0d2711a6 LG |
173 | #\r |
174 | # Get Package related to Modules\r | |
175 | #\r | |
176 | for Module in Pa.Modules:\r | |
177 | ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]\r | |
178 | for Package in ModuleObj.Packages:\r | |
52302d4d LG |
179 | if Package not in PackageList:\r |
180 | PackageList.append(Package)\r | |
0d2711a6 LG |
181 | #\r |
182 | # Get Packages related to Libraries\r | |
183 | #\r | |
184 | for Lib in Pa.LibraryInstances:\r | |
185 | LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]\r | |
186 | for Package in LibObj.Packages:\r | |
187 | if Package not in PackageList:\r | |
47fea6af YZ |
188 | PackageList.append(Package)\r |
189 | \r | |
52302d4d LG |
190 | return PackageList\r |
191 | \r | |
192 | ## Summarize all platforms in the database\r | |
71cac3f7 CJ |
193 | def PlatformList(self):\r |
194 | RetVal = []\r | |
2f818ed0 | 195 | for PlatformFile in [item[3] for item in self.TblFile if item[5] == MODEL_FILE_DSC]:\r |
52302d4d | 196 | try:\r |
71cac3f7 | 197 | RetVal.append(self.BuildObject[PathClass(PlatformFile), TAB_COMMON])\r |
52302d4d | 198 | except:\r |
71cac3f7 CJ |
199 | pass\r |
200 | return RetVal\r | |
52302d4d | 201 | \r |
71cac3f7 | 202 | def MapPlatform(self, Dscfile):\r |
55c84777 | 203 | Platform = self.BuildObject[PathClass(Dscfile), TAB_COMMON]\r |
4231a819 | 204 | if Platform is None:\r |
d429fcd0 | 205 | EdkLogger.error('build', PARSER_ERROR, "Failed to parser DSC file: %s" % Dscfile)\r |
f0dc69e6 YZ |
206 | return Platform\r |
207 | \r | |
e8449e1d | 208 | BuildDB = WorkspaceDatabase()\r |
52302d4d LG |
209 | ##\r |
210 | #\r | |
211 | # This acts like the main() function for the script, unless it is 'import'ed into another\r | |
212 | # script.\r | |
213 | #\r | |
214 | if __name__ == '__main__':\r | |
215 | pass\r | |
216 | \r |