2 PCDAutoGenAction class.
4 This class is to manage how to generate the PCD information into Autogen.c and
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
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.
17 package org
.tianocore
.build
.pcd
.action
;
20 import java
.util
.ArrayList
;
21 import java
.util
.List
;
24 import java
.util
.UUID
;
25 import java
.util
.regex
.Matcher
;
26 import java
.util
.regex
.Pattern
;
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
;
37 /** This class is to manage how to generate the PCD information into Autogen.c and
40 public class PCDAutoGenAction
extends BuildAction
{
42 /// The reference of DBManager in GlobalData class.
44 private MemoryDatabaseManager dbManager
;
46 /// The name of module which is analysised currently.
48 private String moduleName
;
50 /// The Guid of module which is analyzed currently.
52 private UUID moduleGuid
;
54 /// The name of package whose module is analysized currently.
56 private String packageName
;
58 /// The Guid of package whose module is analyszed curretnly.
60 private UUID packageGuid
;
62 /// The arch of current module
66 /// The version of current module
68 private String version
;
70 /// Whether current autogen is for building library used by current module.
72 private boolean isBuildUsedLibrary
;
74 /// The generated string for header file.
76 private String hAutoGenString
;
78 /// The generated string for C code file.
80 private String cAutoGenString
;
82 /// The name array of <PcdCoded> in a module.
84 private String
[] pcdNameArray
;
86 Set parameter ModuleName
88 @param moduleName the module name parameter.
90 public void setModuleName(String moduleName
) {
91 this.moduleName
= moduleName
;
95 set the moduleGuid parameter.
99 public void setModuleGuid(UUID moduleGuid
) {
100 this.moduleGuid
= moduleGuid
;
104 set packageName parameter.
108 public void setPackageName(String packageName
) {
109 this.packageName
= packageName
;
113 set packageGuid parameter.
117 public void setPackageGuid(UUID packageGuid
) {
118 this.packageGuid
= packageGuid
;
126 public void setArch(String arch
) {
131 set version parameter
135 public void setVersion(String version
) {
136 this.version
= version
;
140 set isBuildUsedLibrary parameter.
142 @param isBuildUsedLibrary
144 public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary
) {
145 this.isBuildUsedLibrary
= isBuildUsedLibrary
;
148 set pcdNameArray parameter.
152 public void setPcdNameArray(String
[] pcdNameArray
) {
153 this.pcdNameArray
= pcdNameArray
;
157 Get the output of generated string for header file.
159 @return the string of header file for PCD
161 public String
OutputH() {
162 return hAutoGenString
;
166 Get the output of generated string for C Code file.
168 @return the string of C code file for PCD
170 public String
OutputC() {
171 return cAutoGenString
;
175 // Construct function
177 // This function mainly initialize some member variable.
179 // @param moduleName Parameter of this action class.
180 // @param isEmulatedPCDDriver Parameter of this action class.
182 // public PCDAutoGenAction(String moduleName,
184 // String packageName,
188 // boolean isBuildUsedLibrary,
189 // String[] pcdNameArray) {
191 // hAutoGenString = "";
192 // cAutoGenString = "";
194 // setModuleName(moduleName);
195 // setModuleGuid(moduleGuid);
196 // setPackageName(packageName);
197 // setPackageGuid(packageGuid);
198 // setPcdNameArray(pcdNameArray);
200 // setVersion(version);
201 // setIsBuildUsedLibrary(isBuildUsedLibrary);
208 This function mainly initialize some member variable.
210 @param moduleName Parameter of this action class.
211 @param isEmulatedPCDDriver Parameter of this action class.
213 public PCDAutoGenAction(String moduleName
,
214 String moduleGuidString
,
216 String packageGuidString
,
219 boolean isBuildUsedLibrary
,
220 String
[] pcdNameArray
)
221 throws BuildActionException
{
226 setModuleName(moduleName
);
227 setModuleGuid(translateSchemaStringToUUID(moduleGuidString
));
228 setPackageName(packageName
);
229 setPackageGuid(translateSchemaStringToUUID(packageGuidString
));
230 setPcdNameArray(pcdNameArray
);
233 setIsBuildUsedLibrary(isBuildUsedLibrary
);
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
]);
241 } catch (EntityException e
){
242 throw new BuildActionException(e
.getMessage());
247 Translate the schema string to UUID instance.
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}( )*(\})?
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}
256 This function will convert string and create uuid instance.
258 @param uuidString UUID string in XML file
260 @return UUID UUID instance
262 private UUID
translateSchemaStringToUUID(String uuidString
)
263 throws EntityException
{
265 String
[] splitStringArray
;
270 if (uuidString
== null) {
274 if (uuidString
.length() == 0) {
278 if (uuidString
.equals("0") ||
279 uuidString
.equalsIgnoreCase("0x0")) {
280 return new UUID(0, 0);
283 uuidString
= uuidString
.replaceAll("\\{", "");
284 uuidString
= uuidString
.replaceAll("\\}", "");
287 // If the UUID schema string is GuidArrayType type then need translate
288 // to GuidNamingConvention type at first.
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
);
297 // Remove blank space from these string and remove header string "0x"
299 for (index
= 0; index
< 11; index
++) {
300 splitStringArray
[index
] = splitStringArray
[index
].trim();
301 splitStringArray
[index
] = splitStringArray
[index
].substring(2, splitStringArray
[index
].length());
305 // Add heading '0' to normalize the string length
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
];
315 // construct the final GuidNamingConvention string
317 temp
= String
.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
328 splitStringArray
[10]);
332 return UUID
.fromString(uuidString
);
336 check the parameter for action class.
338 @throws BuildActionException Bad parameter.
340 void checkParameter() throws BuildActionException
{
345 Core execution function for this action class.
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.
352 @throws BuildActionException Failed to execute this aciton class.
354 void performAction() throws BuildActionException
{
355 ActionMessage
.debug(this,
356 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");
358 // Check the PCD memory database manager is valid.
360 if(GlobalData
.getPCDMemoryDBManager() == null) {
361 throw new BuildActionException("Memory database has not been initlizated!");
364 dbManager
= GlobalData
.getPCDMemoryDBManager();
366 if(dbManager
.getDBSize() == 0) {
370 ActionMessage
.debug(this,
371 "PCD memory database contains " + dbManager
.getDBSize() + " PCD tokens");
375 generateAutogenForModule();
379 Generate the autogen string for a common module.
381 All PCD information of this module comes from memory dabase. The collection
382 work should be done before this action execution.
384 private void generateAutogenForModule()
387 List
<UsageInstance
> usageInstanceArray
, usageContext
;
388 String
[] guidStringArray
= null;
389 String guidStringCName
= null;
390 String guidString
= null;
391 UsageInstance usageInstance
= null;
393 if (!isBuildUsedLibrary
) {
394 usageInstanceArray
= dbManager
.getUsageInstanceArrayByModuleName(moduleName
,
400 dbManager
.UsageInstanceContext
= usageInstanceArray
;
401 dbManager
.CurrentModuleName
= moduleName
;
403 System
.out
.println(String
.format("Generate %s 's library", dbManager
.CurrentModuleName
));
404 usageContext
= dbManager
.UsageInstanceContext
;
406 // For building MDE package, although all module are library, but PCD entries of
407 // these library should be used to autogen.
409 if (usageContext
== null) {
410 System
.out
.println("context is null");
411 usageInstanceArray
= dbManager
.getUsageInstanceArrayByModuleName(moduleName
,
418 usageInstanceArray
= new ArrayList
<UsageInstance
>();
419 System
.out
.println("context is not null!");
421 // Remove PCD entries which are not belong to this library.
423 for (index
= 0; index
< usageContext
.size(); index
++) {
424 if ((pcdNameArray
== null) || (pcdNameArray
.length
== 0)){
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
));
439 if(usageInstanceArray
.size() != 0) {
441 // Add "#include 'PcdLib.h'" for Header file
443 hAutoGenString
= "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
447 // Generate all PCD entry for a module.
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
);
454 usageInstance
= usageInstanceArray
.get(index
);
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
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}}",
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)));
478 Pattern pattern
= Pattern
.compile("(" + guidStringCName
+ ")+?");
479 Matcher matcher
= pattern
.matcher(cAutoGenString
+ " ");
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.
485 if (!matcher
.find()) {
486 hAutoGenString
+= String
.format("extern EFI_GUID %s;\r\n",
488 if (!isBuildUsedLibrary
) {
489 cAutoGenString
+= String
.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",
496 usageInstance
.generateAutoGen(isBuildUsedLibrary
);
498 // For every PCD entry for this module(usage instance), autogen string would
501 hAutoGenString
+= usageInstance
.getHAutogenStr() + "\r\n";
502 cAutoGenString
+= usageInstance
.getCAutogenStr();
504 } catch(EntityException exp
) {
505 throw new BuildActionException("[PCD Autogen Error]: " + exp
.getMessage());
510 // Work around code, In furture following code should be modified that get
511 // these information from Uplevel Autogen tools.
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
;
521 ActionMessage
.debug(this,
522 "Module " + moduleName
+ "'s PCD header file:\r\n" + hAutoGenString
+ "\r\n"
524 ActionMessage
.debug(this,
525 "Module " + moduleName
+ "'s PCD C file:\r\n" + cAutoGenString
+ "\r\n"
532 @param argv paramter from command line
534 public static void main(String argv
[]) {
536 String WorkSpace
= "X:/edk2";
537 String logFilePath
= WorkSpace
+ "/EdkNt32Pkg/Nt32.fpd";
538 String
[] nameArray
= null;
541 // At first, CollectPCDAction should be invoked to collect
542 // all PCD information from SPD, MSA, FPD.
544 CollectPCDAction collectionAction
= new CollectPCDAction();
545 GlobalData
.initInfo("Tools" + File
.separator
+ "Conf" + File
.separator
+ "FrameworkDatabase.db",
549 collectionAction
.perform(WorkSpace
,
551 ActionMessage
.MAX_MESSAGE_LEVEL
);
552 } catch(Exception e
) {
557 // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c
559 // PCDAutoGenAction autogenAction = new PCDAutoGenAction("MonoStatusCode",
567 // autogenAction.execute();
569 // System.out.println(autogenAction.OutputH());
570 // System.out.println("WQWQWQWQWQ");
571 // System.out.println(autogenAction.OutputC());