]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / WorkspaceDatabase.py
CommitLineData
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 12from __future__ import absolute_import\r
5a57246e 13from Common.StringUtils import *\r
52302d4d
LG
14from Common.DataType import *\r
15from Common.Misc import *\r
16from types import *\r
17\r
1100bc5a
GL
18from .MetaDataTable import *\r
19from .MetaFileTable import *\r
20from .MetaFileParser import *\r
52302d4d 21\r
ae7b6df8
LG
22from Workspace.DecBuildData import DecBuildData\r
23from Workspace.DscBuildData import DscBuildData\r
24from 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
36class 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
211if __name__ == '__main__':\r
212 pass\r
213\r