]>
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 | |
65 | \r | |
66 | # constructor\r | |
67 | def __init__(self, WorkspaceDb):\r | |
68 | self.WorkspaceDb = WorkspaceDb\r | |
69 | \r | |
0d2711a6 | 70 | # key = (FilePath, Arch=None)\r |
52302d4d LG |
71 | def __contains__(self, Key):\r |
72 | FilePath = Key[0]\r | |
52302d4d LG |
73 | if len(Key) > 1:\r |
74 | Arch = Key[1]\r | |
0d2711a6 LG |
75 | else:\r |
76 | Arch = None\r | |
52302d4d LG |
77 | return (FilePath, Arch) in self._CACHE_\r |
78 | \r | |
fb0b35e0 | 79 | # key = (FilePath, Arch=None, Target=None, Toolchain=None)\r |
52302d4d LG |
80 | def __getitem__(self, Key):\r |
81 | FilePath = Key[0]\r | |
0d2711a6 LG |
82 | KeyLength = len(Key)\r |
83 | if KeyLength > 1:\r | |
52302d4d | 84 | Arch = Key[1]\r |
0d2711a6 LG |
85 | else:\r |
86 | Arch = None\r | |
87 | if KeyLength > 2:\r | |
88 | Target = Key[2]\r | |
89 | else:\r | |
90 | Target = None\r | |
91 | if KeyLength > 3:\r | |
92 | Toolchain = Key[3]\r | |
93 | else:\r | |
94 | Toolchain = None\r | |
52302d4d LG |
95 | \r |
96 | # if it's generated before, just return the cached one\r | |
0d2711a6 | 97 | Key = (FilePath, Arch, Target, Toolchain)\r |
52302d4d LG |
98 | if Key in self._CACHE_:\r |
99 | return self._CACHE_[Key]\r | |
100 | \r | |
101 | # check file type\r | |
34e733f2 FB |
102 | BuildObject = self.CreateBuildObject(FilePath, Arch, Target, Toolchain)\r |
103 | self._CACHE_[Key] = BuildObject\r | |
104 | return BuildObject\r | |
105 | def CreateBuildObject(self,FilePath, Arch, Target, Toolchain):\r | |
0d2711a6 | 106 | Ext = FilePath.Type\r |
52302d4d LG |
107 | if Ext not in self._FILE_TYPE_:\r |
108 | return None\r | |
109 | FileType = self._FILE_TYPE_[Ext]\r | |
110 | if FileType not in self._GENERATOR_:\r | |
111 | return None\r | |
112 | \r | |
0d2711a6 LG |
113 | # get the parser ready for this file\r |
114 | MetaFile = self._FILE_PARSER_[FileType](\r | |
f7496d71 LG |
115 | FilePath,\r |
116 | FileType,\r | |
cdd1b5e5 | 117 | Arch,\r |
2f818ed0 | 118 | MetaFileStorage(self.WorkspaceDb, FilePath, FileType)\r |
0d2711a6 | 119 | )\r |
fb0b35e0 | 120 | # always do post-process, in case of macros change\r |
0d2711a6 LG |
121 | MetaFile.DoPostProcess()\r |
122 | # object the build is based on\r | |
52302d4d LG |
123 | BuildObject = self._GENERATOR_[FileType](\r |
124 | FilePath,\r | |
125 | MetaFile,\r | |
126 | self,\r | |
127 | Arch,\r | |
0d2711a6 LG |
128 | Target,\r |
129 | Toolchain\r | |
52302d4d | 130 | )\r |
52302d4d LG |
131 | return BuildObject\r |
132 | \r | |
133 | # placeholder for file format conversion\r | |
134 | class TransformObjectFactory:\r | |
135 | def __init__(self, WorkspaceDb):\r | |
136 | self.WorkspaceDb = WorkspaceDb\r | |
137 | \r | |
138 | # key = FilePath, Arch\r | |
139 | def __getitem__(self, Key):\r | |
140 | pass\r | |
141 | \r | |
142 | ## Constructor of WorkspaceDatabase\r | |
143 | #\r | |
144 | # @param DbPath Path of database file\r | |
145 | # @param GlobalMacros Global macros used for replacement during file parsing\r | |
fb0b35e0 | 146 | # @param RenewDb=False Create new database file if it's already there\r |
52302d4d | 147 | #\r |
2f818ed0 B |
148 | def __init__(self):\r |
149 | self.DB = dict()\r | |
52302d4d | 150 | # create table for internal uses\r |
2f818ed0 B |
151 | self.TblDataModel = DataClass.MODEL_LIST\r |
152 | self.TblFile = []\r | |
0d2711a6 | 153 | self.Platform = None\r |
52302d4d LG |
154 | \r |
155 | # conversion object for build or file format conversion purpose\r | |
156 | self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r | |
157 | self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r | |
158 | \r | |
2f818ed0 | 159 | def SetFileTimeStamp(self,FileId,TimeStamp):\r |
643556fc | 160 | self.TblFile[FileId-1][6] = TimeStamp\r |
f7496d71 | 161 | \r |
2f818ed0 | 162 | def GetFileTimeStamp(self,FileId):\r |
643556fc | 163 | return self.TblFile[FileId-1][6]\r |
f7496d71 | 164 | \r |
52302d4d | 165 | \r |
52302d4d | 166 | ## Summarize all packages in the database\r |
0d2711a6 LG |
167 | def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r |
168 | self.Platform = Platform\r | |
47fea6af | 169 | PackageList = []\r |
b9a6d9d7 | 170 | Pa = self.BuildObject[self.Platform, Arch, TargetName, ToolChainTag]\r |
0d2711a6 LG |
171 | #\r |
172 | # Get Package related to Modules\r | |
173 | #\r | |
174 | for Module in Pa.Modules:\r | |
175 | ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]\r | |
176 | for Package in ModuleObj.Packages:\r | |
52302d4d LG |
177 | if Package not in PackageList:\r |
178 | PackageList.append(Package)\r | |
0d2711a6 LG |
179 | #\r |
180 | # Get Packages related to Libraries\r | |
181 | #\r | |
182 | for Lib in Pa.LibraryInstances:\r | |
183 | LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]\r | |
184 | for Package in LibObj.Packages:\r | |
185 | if Package not in PackageList:\r | |
47fea6af YZ |
186 | PackageList.append(Package)\r |
187 | \r | |
52302d4d LG |
188 | return PackageList\r |
189 | \r | |
190 | ## Summarize all platforms in the database\r | |
71cac3f7 CJ |
191 | def PlatformList(self):\r |
192 | RetVal = []\r | |
2f818ed0 | 193 | for PlatformFile in [item[3] for item in self.TblFile if item[5] == MODEL_FILE_DSC]:\r |
52302d4d | 194 | try:\r |
71cac3f7 | 195 | RetVal.append(self.BuildObject[PathClass(PlatformFile), TAB_COMMON])\r |
52302d4d | 196 | except:\r |
71cac3f7 CJ |
197 | pass\r |
198 | return RetVal\r | |
52302d4d | 199 | \r |
71cac3f7 | 200 | def MapPlatform(self, Dscfile):\r |
55c84777 | 201 | Platform = self.BuildObject[PathClass(Dscfile), TAB_COMMON]\r |
4231a819 | 202 | if Platform is None:\r |
d429fcd0 | 203 | EdkLogger.error('build', PARSER_ERROR, "Failed to parser DSC file: %s" % Dscfile)\r |
f0dc69e6 YZ |
204 | return Platform\r |
205 | \r | |
52302d4d LG |
206 | ##\r |
207 | #\r | |
208 | # This acts like the main() function for the script, unless it is 'import'ed into another\r | |
209 | # script.\r | |
210 | #\r | |
211 | if __name__ == '__main__':\r | |
212 | pass\r | |
213 | \r |