]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
Abstract the logic of Platform pcd preprocess according to FPD file to a class. And...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PCDAutoGenAction.java
... / ...
CommitLineData
1/** @file\r
2 PCDAutoGenAction class.\r
3\r
4 This class is to manage how to generate the PCD information into Autogen.c and\r
5 Autogen.h.\r
6\r
7Copyright (c) 2006, Intel Corporation\r
8All rights reserved. This program and the accompanying materials\r
9are licensed and made available under the terms and conditions of the BSD License\r
10which accompanies this distribution. The full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17package org.tianocore.build.pcd.action;\r
18\r
19import java.io.File;\r
20import java.util.ArrayList;\r
21import java.util.List;\r
22import java.util.regex.Matcher;\r
23import java.util.regex.Pattern;\r
24\r
25import org.tianocore.build.global.GlobalData;\r
26import org.tianocore.build.id.ModuleIdentification;\r
27import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
28import org.tianocore.pcd.entity.Token;\r
29import org.tianocore.pcd.entity.UsageInstance;\r
30import org.tianocore.pcd.exception.BuildActionException;\r
31import org.tianocore.pcd.entity.UsageIdentification;\r
32import org.tianocore.pcd.action.BuildAction;\r
33import org.tianocore.pcd.action.ActionMessage;\r
34\r
35/** This class is to manage how to generate the PCD information into Autogen.c and\r
36 Autogen.h.\r
37**/\r
38public class PCDAutoGenAction extends BuildAction {\r
39 ///\r
40 /// The reference of DBManager in GlobalData class.\r
41 ///\r
42 private MemoryDatabaseManager dbManager;\r
43\r
44 ///\r
45 /// The identification for a UsageInstance.\r
46 ///\r
47 private UsageIdentification usageId;\r
48\r
49 ///\r
50 /// Whether current autogen is for building library used by current module.\r
51 ///\r
52 private boolean isBuildUsedLibrary;\r
53\r
54 ///\r
55 /// The generated string for header file.\r
56 ///\r
57 private String hAutoGenString;\r
58\r
59 ///\r
60 /// The generated string for C code file.\r
61 ///\r
62 private String cAutoGenString;\r
63\r
64 ///\r
65 /// The name array of <PcdCoded> in a module.\r
66 ///\r
67 private String[] pcdNameArrayInMsa;\r
68\r
69 /**\r
70 Set parameter moduleId\r
71\r
72 @param moduleName the module name parameter.\r
73 **/\r
74 public void setUsageId(UsageIdentification usageId) {\r
75 this.usageId = usageId;\r
76 }\r
77\r
78 /**\r
79 set isBuildUsedLibrary parameter.\r
80\r
81 @param isBuildUsedLibrary\r
82 **/\r
83 public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) {\r
84 this.isBuildUsedLibrary = isBuildUsedLibrary;\r
85 }\r
86\r
87 /**\r
88 set pcdNameArrayInMsa parameter.\r
89\r
90 @param pcdNameArrayInMsa\r
91 */\r
92 public void setPcdNameArrayInMsa(String[] pcdNameArrayInMsa) {\r
93 this.pcdNameArrayInMsa = pcdNameArrayInMsa;\r
94 }\r
95\r
96 /**\r
97 Get the output of generated string for header file.\r
98\r
99 @return the string of header file for PCD\r
100 **/\r
101 public String OutputH() {\r
102 return hAutoGenString;\r
103 }\r
104\r
105 /**\r
106 Get the output of generated string for C Code file.\r
107\r
108 @return the string of C code file for PCD\r
109 **/\r
110 public String OutputC() {\r
111 return cAutoGenString;\r
112 }\r
113\r
114\r
115 /**\r
116 Construct function\r
117\r
118 This function mainly initialize some member variable.\r
119\r
120 @param moduleId the identification for module\r
121 @param arch the architecture for module\r
122 @param isBuildUsedLibary Is the current module library.\r
123 @param pcdNameArrayInMsa the pcd name array got from MSA file.\r
124 **/\r
125 public PCDAutoGenAction(ModuleIdentification moduleId,\r
126 String arch,\r
127 boolean isBuildUsedLibrary,\r
128 String[] pcdNameArrayInMsa) {\r
129 dbManager = null;\r
130 hAutoGenString = "";\r
131 cAutoGenString = "";\r
132\r
133 setUsageId(new UsageIdentification(moduleId.getName(),\r
134 moduleId.getGuid(),\r
135 moduleId.getPackage().getName(),\r
136 moduleId.getPackage().getGuid(),\r
137 arch,\r
138 moduleId.getVersion(),\r
139 moduleId.getModuleType()));\r
140 setIsBuildUsedLibrary(isBuildUsedLibrary);\r
141 setPcdNameArrayInMsa(pcdNameArrayInMsa);\r
142 }\r
143\r
144 /**\r
145 check the parameter for action class.\r
146\r
147 @throws BuildActionException Bad parameter.\r
148 **/\r
149 public void checkParameter() {\r
150 }\r
151\r
152 /**\r
153 Core execution function for this action class.\r
154\r
155 All PCD information of this module comes from memory dabase. The collection\r
156 work should be done before this action execution.\r
157 Currently, we should generated all PCD information(maybe all dynamic) as array\r
158 in Pei emulated driver for simulating PCD runtime database.\r
159\r
160 @throws BuildActionException Failed to execute this aciton class.\r
161 **/\r
162 public void performAction() {\r
163 ActionMessage.debug(this,\r
164 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");\r
165 //\r
166 // Check the PCD memory database manager is valid.\r
167 //\r
168 if(GlobalData.getPCDMemoryDBManager() == null) {\r
169 throw new BuildActionException("Memory database has not been initlizated!");\r
170 }\r
171\r
172 dbManager = GlobalData.getPCDMemoryDBManager();\r
173\r
174 if(dbManager.getDBSize() == 0) {\r
175 return;\r
176 }\r
177\r
178 ActionMessage.debug(this,\r
179 "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens");\r
180\r
181 generateAutogenForModule();\r
182 }\r
183\r
184 /**\r
185 Generate the autogen string for a common module.\r
186\r
187 All PCD information of this module comes from memory dabase. The collection\r
188 work should be done before this action execution.\r
189 **/\r
190 private void generateAutogenForModule()\r
191 {\r
192 int index, index2;\r
193 List<UsageInstance> usageInstanceArray, usageContext;\r
194 String[] guidStringArray = null;\r
195 String guidStringCName = null;\r
196 String guidString = null;\r
197 String moduleName = usageId.moduleName;\r
198 UsageInstance usageInstance = null;\r
199 boolean found = false;\r
200\r
201 usageInstanceArray = null;\r
202 if (!isBuildUsedLibrary) {\r
203 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(usageId);\r
204 MemoryDatabaseManager.UsageInstanceContext = usageInstanceArray;\r
205 MemoryDatabaseManager.CurrentModuleName = moduleName;\r
206 } else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) {\r
207 usageContext = MemoryDatabaseManager.UsageInstanceContext;\r
208 //\r
209 // For building library package, although all module are library, but PCD entries of\r
210 // these library should be used to autogen.\r
211 //\r
212 if (usageContext == null) {\r
213 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(usageId);\r
214 } else {\r
215 usageInstanceArray = new ArrayList<UsageInstance>();\r
216\r
217 //\r
218 // Try to find all PCD defined in library's PCD in all <PcdEntry> in module's\r
219 // <ModuleSA> in FPD file.\r
220 //\r
221 for (index = 0; index < pcdNameArrayInMsa.length; index++) {\r
222 found = false;\r
223 for (index2 = 0; index2 < usageContext.size(); index2 ++) {\r
224 if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) {\r
225 usageInstanceArray.add(usageContext.get(index2));\r
226 found = true;\r
227 break;\r
228 }\r
229 }\r
230\r
231 if (!found) {\r
232 //\r
233 // All library's PCD should instanted in module's <ModuleSA> who\r
234 // use this library instance. If not, give errors.\r
235 //\r
236 throw new BuildActionException (String.format("[PCD Autogen Error] Module %s use library instance %s, the PCD %s " +\r
237 "is required by this library instance, but can not find " +\r
238 "it in the %s's <ModuleSA> in FPD file!",\r
239 MemoryDatabaseManager.CurrentModuleName,\r
240 moduleName,\r
241 pcdNameArrayInMsa[index],\r
242 MemoryDatabaseManager.CurrentModuleName\r
243 ));\r
244 }\r
245 }\r
246 }\r
247 }\r
248\r
249 if (usageInstanceArray == null) {\r
250 return;\r
251 }\r
252\r
253 //\r
254 // Generate all PCD entry for a module.\r
255 //\r
256 for(index = 0; index < usageInstanceArray.size(); index ++) {\r
257 usageInstance = usageInstanceArray.get(index);\r
258 //\r
259 // Before generate any PCD information into autogen.h/autogen.c for a module,\r
260 // generate TokenSpaceGuid array variable firstly. For every dynamicEx type\r
261 // PCD in this module the token, they are all reference to TokenSpaceGuid\r
262 // array.\r
263 //\r
264 if (usageInstanceArray.get(index).modulePcdType == Token.PCD_TYPE.DYNAMIC_EX) {\r
265 guidStringArray = usageInstance.parentToken.tokenSpaceName.split("-");\r
266 guidStringCName = "_gPcd_TokenSpaceGuid_" +\r
267 usageInstance.parentToken.tokenSpaceName.replaceAll("-", "_");\r
268 guidString = String.format("{ 0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",\r
269 guidStringArray[0],\r
270 guidStringArray[1],\r
271 guidStringArray[2],\r
272 (guidStringArray[3].substring(0, 2)),\r
273 (guidStringArray[3].substring(2, 4)),\r
274 (guidStringArray[4].substring(0, 2)),\r
275 (guidStringArray[4].substring(2, 4)),\r
276 (guidStringArray[4].substring(4, 6)),\r
277 (guidStringArray[4].substring(6, 8)),\r
278 (guidStringArray[4].substring(8, 10)),\r
279 (guidStringArray[4].substring(10, 12)));\r
280\r
281 Pattern pattern = Pattern.compile("(" + guidStringCName + ")+?");\r
282 Matcher matcher = pattern.matcher(cAutoGenString + " ");\r
283 //\r
284 // Find whether this guid array variable has been generated into autogen.c\r
285 // For different DyanmicEx pcd token who use same token space guid, the token space\r
286 // guid array should be only generated once.\r
287 //\r
288 if (!matcher.find()) {\r
289 hAutoGenString += String.format("extern EFI_GUID %s;\r\n", guidStringCName);\r
290 if (!isBuildUsedLibrary) {\r
291 cAutoGenString += String.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",\r
292 guidStringCName,\r
293 guidString);\r
294 }\r
295 }\r
296 }\r
297\r
298 usageInstance.generateAutoGen(isBuildUsedLibrary);\r
299 //\r
300 // For every PCD entry for this module(usage instance), autogen string would\r
301 // be appand.\r
302 //\r
303 hAutoGenString += usageInstance.getHAutogenStr() + "\r\n";\r
304 cAutoGenString += usageInstance.getCAutogenStr();\r
305 }\r
306\r
307 //\r
308 // Work around code, In furture following code should be modified that get\r
309 // these information from Uplevel Autogen tools.\r
310 //\r
311 if (moduleName.equalsIgnoreCase("PcdPeim")) {\r
312 hAutoGenString += MemoryDatabaseManager.PcdPeimHString;\r
313 cAutoGenString += MemoryDatabaseManager.PcdPeimCString;\r
314 } else if (moduleName.equalsIgnoreCase("PcdDxe")) {\r
315 hAutoGenString += MemoryDatabaseManager.PcdDxeHString;\r
316 cAutoGenString += MemoryDatabaseManager.PcdDxeCString;\r
317 }\r
318 }\r
319\r
320 /**\r
321 Test case function\r
322\r
323 @param argv paramter from command line\r
324 **/\r
325 public static void main(String argv[]) {\r
326\r
327 String WorkSpace = "X:/edk2";\r
328 String logFilePath = WorkSpace + "/EdkNt32Pkg/Nt32.fpd";\r
329\r
330 //\r
331 // At first, CollectPCDAction should be invoked to collect\r
332 // all PCD information from SPD, MSA, FPD.\r
333 //\r
334 PlatformPcdPreprocessActionForBuilding collectionAction = new PlatformPcdPreprocessActionForBuilding();\r
335 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
336 WorkSpace,null);\r
337\r
338 try {\r
339 collectionAction.perform(WorkSpace,\r
340 logFilePath,\r
341 ActionMessage.MAX_MESSAGE_LEVEL);\r
342 } catch(Exception e) {\r
343 e.printStackTrace();\r
344 }\r
345 }\r
346}\r