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