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