]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
7365345c39c131b1da72f9404060bc5cf5b16f01
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PCDAutoGenAction.java
1 /** @file
2 PCDAutoGenAction class.
3
4 This class is to manage how to generate the PCD information into Autogen.c and
5 Autogen.h.
6
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17 package org.tianocore.build.pcd.action;
18
19 import java.io.File;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.UUID;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import org.apache.xmlbeans.XmlObject;
29 import org.tianocore.build.global.GlobalData;
30 import org.tianocore.build.global.SurfaceAreaQuery;
31 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
32 import org.tianocore.build.pcd.entity.Token;
33 import org.tianocore.build.pcd.entity.UsageInstance;
34 import org.tianocore.build.pcd.exception.BuildActionException;
35 import org.tianocore.build.pcd.exception.EntityException;
36
37 /** This class is to manage how to generate the PCD information into Autogen.c and
38 Autogen.h.
39 **/
40 public class PCDAutoGenAction extends BuildAction {
41 ///
42 /// The reference of DBManager in GlobalData class.
43 ///
44 private MemoryDatabaseManager dbManager;
45 ///
46 /// The name of module which is analysised currently.
47 ///
48 private String moduleName;
49 ///
50 /// The Guid of module which is analyzed currently.
51 ///
52 private UUID moduleGuid;
53 ///
54 /// The name of package whose module is analysized currently.
55 ///
56 private String packageName;
57 ///
58 /// The Guid of package whose module is analyszed curretnly.
59 ///
60 private UUID packageGuid;
61 ///
62 /// The arch of current module
63 ///
64 private String arch;
65 ///
66 /// The version of current module
67 ///
68 private String version;
69 ///
70 /// Whether current autogen is for building library used by current module.
71 ///
72 private boolean isBuildUsedLibrary;
73 ///
74 /// The generated string for header file.
75 ///
76 private String hAutoGenString;
77 ///
78 /// The generated string for C code file.
79 ///
80 private String cAutoGenString;
81 ///
82 /// The name array of <PcdCoded> in a module.
83 ///
84 private String[] pcdNameArray;
85 /**
86 Set parameter ModuleName
87
88 @param moduleName the module name parameter.
89 **/
90 public void setModuleName(String moduleName) {
91 this.moduleName = moduleName;
92 }
93
94 /**
95 set the moduleGuid parameter.
96
97 @param moduleGuid
98 **/
99 public void setModuleGuid(UUID moduleGuid) {
100 this.moduleGuid = moduleGuid;
101 }
102
103 /**
104 set packageName parameter.
105
106 @param packageName
107 **/
108 public void setPackageName(String packageName) {
109 this.packageName = packageName;
110 }
111
112 /**
113 set packageGuid parameter.
114
115 @param packageGuid
116 **/
117 public void setPackageGuid(UUID packageGuid) {
118 this.packageGuid = packageGuid;
119 }
120
121 /**
122 set Arch parameter.
123
124 @param arch
125 **/
126 public void setArch(String arch) {
127 this.arch = arch;
128 }
129
130 /**
131 set version parameter
132
133 @param version
134 */
135 public void setVersion(String version) {
136 this.version = version;
137 }
138
139 /**
140 set isBuildUsedLibrary parameter.
141
142 @param isBuildUsedLibrary
143 */
144 public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) {
145 this.isBuildUsedLibrary = isBuildUsedLibrary;
146 }
147 /**
148 set pcdNameArray parameter.
149
150 @param pcdNameArray
151 */
152 public void setPcdNameArray(String[] pcdNameArray) {
153 this.pcdNameArray = pcdNameArray;
154 }
155
156 /**
157 Get the output of generated string for header file.
158
159 @return the string of header file for PCD
160 **/
161 public String OutputH() {
162 return hAutoGenString;
163 }
164
165 /**
166 Get the output of generated string for C Code file.
167
168 @return the string of C code file for PCD
169 **/
170 public String OutputC() {
171 return cAutoGenString;
172 }
173
174 // /**
175 // Construct function
176 //
177 // This function mainly initialize some member variable.
178 //
179 // @param moduleName Parameter of this action class.
180 // @param isEmulatedPCDDriver Parameter of this action class.
181 // **/
182 // public PCDAutoGenAction(String moduleName,
183 // UUID moduleGuid,
184 // String packageName,
185 // UUID packageGuid,
186 // String arch,
187 // String version,
188 // boolean isBuildUsedLibrary,
189 // String[] pcdNameArray) {
190 // dbManager = null;
191 // hAutoGenString = "";
192 // cAutoGenString = "";
193 //
194 // setModuleName(moduleName);
195 // setModuleGuid(moduleGuid);
196 // setPackageName(packageName);
197 // setPackageGuid(packageGuid);
198 // setPcdNameArray(pcdNameArray);
199 // setArch(arch);
200 // setVersion(version);
201 // setIsBuildUsedLibrary(isBuildUsedLibrary);
202 // }
203
204
205 /**
206 Construct function
207
208 This function mainly initialize some member variable.
209
210 @param moduleName Parameter of this action class.
211 @param isEmulatedPCDDriver Parameter of this action class.
212 **/
213 public PCDAutoGenAction(String moduleName,
214 String moduleGuidString,
215 String packageName,
216 String packageGuidString,
217 String arch,
218 String version,
219 boolean isBuildUsedLibrary,
220 String[] pcdNameArray)
221 throws BuildActionException {
222 dbManager = null;
223 hAutoGenString = "";
224 cAutoGenString = "";
225 try {
226 setModuleName(moduleName);
227 setModuleGuid(translateSchemaStringToUUID(moduleGuidString));
228 setPackageName(packageName);
229 setPackageGuid(translateSchemaStringToUUID(packageGuidString));
230 setPcdNameArray(pcdNameArray);
231 setArch(arch);
232 setVersion(version);
233 setIsBuildUsedLibrary(isBuildUsedLibrary);
234
235 if (isBuildUsedLibrary) {
236 System.out.println("Build for library");
237 for (int index = 0; index < pcdNameArray.length; index ++) {
238 System.out.println(pcdNameArray[index]);
239 }
240 }
241 } catch (EntityException e){
242 throw new BuildActionException(e.getMessage());
243 }
244 }
245
246 /**
247 Translate the schema string to UUID instance.
248
249 In schema, the string of UUID is defined as following two types string:
250 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
251 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
252
253 2) GuidNamingConvention: pattern =
254 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
255
256 This function will convert string and create uuid instance.
257
258 @param uuidString UUID string in XML file
259
260 @return UUID UUID instance
261 **/
262 private UUID translateSchemaStringToUUID(String uuidString)
263 throws EntityException {
264 String temp;
265 String[] splitStringArray;
266 int index;
267 int chIndex;
268 int chLen;
269
270 if (uuidString == null) {
271 return null;
272 }
273
274 if (uuidString.length() == 0) {
275 return null;
276 }
277
278 if (uuidString.equals("0") ||
279 uuidString.equalsIgnoreCase("0x0")) {
280 return new UUID(0, 0);
281 }
282
283 uuidString = uuidString.replaceAll("\\{", "");
284 uuidString = uuidString.replaceAll("\\}", "");
285
286 //
287 // If the UUID schema string is GuidArrayType type then need translate
288 // to GuidNamingConvention type at first.
289 //
290 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
291 splitStringArray = uuidString.split("," );
292 if (splitStringArray.length != 11) {
293 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);
294 }
295
296 //
297 // Remove blank space from these string and remove header string "0x"
298 //
299 for (index = 0; index < 11; index ++) {
300 splitStringArray[index] = splitStringArray[index].trim();
301 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
302 }
303
304 //
305 // Add heading '0' to normalize the string length
306 //
307 for (index = 3; index < 11; index ++) {
308 chLen = splitStringArray[index].length();
309 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
310 splitStringArray[index] = "0" + splitStringArray[index];
311 }
312 }
313
314 //
315 // construct the final GuidNamingConvention string
316 //
317 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
318 splitStringArray[0],
319 splitStringArray[1],
320 splitStringArray[2],
321 splitStringArray[3],
322 splitStringArray[4],
323 splitStringArray[5],
324 splitStringArray[6],
325 splitStringArray[7],
326 splitStringArray[8],
327 splitStringArray[9],
328 splitStringArray[10]);
329 uuidString = temp;
330 }
331
332 return UUID.fromString(uuidString);
333 }
334
335 /**
336 check the parameter for action class.
337
338 @throws BuildActionException Bad parameter.
339 **/
340 void checkParameter() throws BuildActionException {
341
342 }
343
344 /**
345 Core execution function for this action class.
346
347 All PCD information of this module comes from memory dabase. The collection
348 work should be done before this action execution.
349 Currently, we should generated all PCD information(maybe all dynamic) as array
350 in Pei emulated driver for simulating PCD runtime database.
351
352 @throws BuildActionException Failed to execute this aciton class.
353 **/
354 void performAction() throws BuildActionException {
355 ActionMessage.debug(this,
356 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");
357 //
358 // Check the PCD memory database manager is valid.
359 //
360 if(GlobalData.getPCDMemoryDBManager() == null) {
361 throw new BuildActionException("Memory database has not been initlizated!");
362 }
363
364 dbManager = GlobalData.getPCDMemoryDBManager();
365
366 if(dbManager.getDBSize() == 0) {
367 return;
368 }
369
370 ActionMessage.debug(this,
371 "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens");
372
373
374
375 generateAutogenForModule();
376 }
377
378 /**
379 Generate the autogen string for a common module.
380
381 All PCD information of this module comes from memory dabase. The collection
382 work should be done before this action execution.
383 **/
384 private void generateAutogenForModule()
385 {
386 int index, index2;
387 List<UsageInstance> usageInstanceArray, usageContext;
388 String[] guidStringArray = null;
389 String guidStringCName = null;
390 String guidString = null;
391 UsageInstance usageInstance = null;
392
393 if (!isBuildUsedLibrary) {
394 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName,
395 moduleGuid,
396 packageName,
397 packageGuid,
398 arch,
399 version);
400 dbManager.UsageInstanceContext = usageInstanceArray;
401 dbManager.CurrentModuleName = moduleName;
402 } else {
403 System.out.println(String.format("Generate %s 's library", dbManager.CurrentModuleName));
404 usageContext = dbManager.UsageInstanceContext;
405 //
406 // For building MDE package, although all module are library, but PCD entries of
407 // these library should be used to autogen.
408 //
409 if (usageContext == null) {
410 System.out.println("context is null");
411 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName,
412 moduleGuid,
413 packageName,
414 packageGuid,
415 arch,
416 version);
417 } else {
418 usageInstanceArray = new ArrayList<UsageInstance>();
419 System.out.println("context is not null!");
420 //
421 // Remove PCD entries which are not belong to this library.
422 //
423 for (index = 0; index < usageContext.size(); index++) {
424 if ((pcdNameArray == null) || (pcdNameArray.length == 0)){
425 break;
426 }
427
428 for (index2 = 0; index2 < pcdNameArray.length; index2 ++) {
429 if (pcdNameArray[index2].equalsIgnoreCase(usageContext.get(index).parentToken.cName)) {
430 System.out.println("Found! for PCD entry " + pcdNameArray[index2]);
431 usageInstanceArray.add(usageContext.get(index));
432 break;
433 }
434 }
435 }
436 }
437 }
438
439 if(usageInstanceArray.size() != 0) {
440 //
441 // Add "#include 'PcdLib.h'" for Header file
442 //
443 hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
444 }
445
446 //
447 // Generate all PCD entry for a module.
448 //
449 for(index = 0; index < usageInstanceArray.size(); index ++) {
450 ActionMessage.debug(this,
451 "Module " + moduleName + "'s PCD [" + Integer.toHexString(index) +
452 "]: " + usageInstanceArray.get(index).parentToken.cName);
453 try {
454 usageInstance = usageInstanceArray.get(index);
455 //
456 // Before generate any PCD information into autogen.h/autogen.c for a module,
457 // generate TokenSpaceGuid array variable firstly. For every dynamicEx type
458 // PCD in this module the token, they are all reference to TokenSpaceGuid
459 // array.
460 //
461 if (usageInstanceArray.get(index).modulePcdType == Token.PCD_TYPE.DYNAMIC_EX) {
462 guidStringArray = usageInstance.parentToken.tokenSpaceName.toString().split("-");
463 guidStringCName = "_gPcd_TokenSpaceGuid_" +
464 usageInstance.parentToken.tokenSpaceName.toString().replaceAll("-", "_");
465 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}}",
466 guidStringArray[0],
467 guidStringArray[1],
468 guidStringArray[2],
469 (guidStringArray[3].substring(0, 2)),
470 (guidStringArray[3].substring(2, 4)),
471 (guidStringArray[4].substring(0, 2)),
472 (guidStringArray[4].substring(2, 4)),
473 (guidStringArray[4].substring(4, 6)),
474 (guidStringArray[4].substring(6, 8)),
475 (guidStringArray[4].substring(8, 10)),
476 (guidStringArray[4].substring(10, 12)));
477
478 Pattern pattern = Pattern.compile("(" + guidStringCName + ")+?");
479 Matcher matcher = pattern.matcher(cAutoGenString + " ");
480 //
481 // Find whether this guid array variable has been generated into autogen.c
482 // For different DyanmicEx pcd token who use same token space guid, the token space
483 // guid array should be only generated once.
484 //
485 if (!matcher.find()) {
486 hAutoGenString += String.format("extern EFI_GUID %s;\r\n",
487 guidStringCName);
488 if (!isBuildUsedLibrary) {
489 cAutoGenString += String.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",
490 guidStringCName,
491 guidString);
492 }
493 }
494 }
495
496 usageInstance.generateAutoGen(isBuildUsedLibrary);
497 //
498 // For every PCD entry for this module(usage instance), autogen string would
499 // be appand.
500 //
501 hAutoGenString += usageInstance.getHAutogenStr() + "\r\n";
502 cAutoGenString += usageInstance.getCAutogenStr();
503
504 } catch(EntityException exp) {
505 throw new BuildActionException("[PCD Autogen Error]: " + exp.getMessage());
506 }
507 }
508
509 //
510 // Work around code, In furture following code should be modified that get
511 // these information from Uplevel Autogen tools.
512 //
513 if (moduleName.equalsIgnoreCase("PcdPeim")) {
514 hAutoGenString += dbManager.PcdPeimHString;
515 cAutoGenString += dbManager.PcdPeimCString;
516 } else if (moduleName.equalsIgnoreCase("PcdDxe")) {
517 hAutoGenString += dbManager.PcdDxeHString;
518 cAutoGenString += dbManager.PcdDxeCString;
519 }
520
521 ActionMessage.debug(this,
522 "Module " + moduleName + "'s PCD header file:\r\n" + hAutoGenString + "\r\n"
523 );
524 ActionMessage.debug(this,
525 "Module " + moduleName + "'s PCD C file:\r\n" + cAutoGenString + "\r\n"
526 );
527 }
528
529 /**
530 Test case function
531
532 @param argv paramter from command line
533 **/
534 public static void main(String argv[]) {
535
536 String WorkSpace = "X:/edk2";
537 String logFilePath = WorkSpace + "/EdkNt32Pkg/Nt32.fpd";
538 String[] nameArray = null;
539
540 //
541 // At first, CollectPCDAction should be invoked to collect
542 // all PCD information from SPD, MSA, FPD.
543 //
544 CollectPCDAction collectionAction = new CollectPCDAction();
545 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
546 WorkSpace,null);
547
548 try {
549 collectionAction.perform(WorkSpace,
550 logFilePath,
551 ActionMessage.MAX_MESSAGE_LEVEL);
552 } catch(Exception e) {
553 e.printStackTrace();
554 }
555
556 //
557 // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c
558 //
559 // PCDAutoGenAction autogenAction = new PCDAutoGenAction("MonoStatusCode",
560 // null,
561 // null,
562 // null,
563 // "IA32",
564 // null,
565 // false,
566 // nameArray);
567 // autogenAction.execute();
568 //
569 // System.out.println(autogenAction.OutputH());
570 // System.out.println("WQWQWQWQWQ");
571 // System.out.println(autogenAction.OutputC());
572 }
573 }