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