]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
There is a rule here:
[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 } catch (EntityException e){
235 throw new BuildActionException(e.getMessage());
236 }
237 }
238
239 /**
240 Translate the schema string to UUID instance.
241
242 In schema, the string of UUID is defined as following two types string:
243 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
244 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
245
246 2) GuidNamingConvention: pattern =
247 [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}
248
249 This function will convert string and create uuid instance.
250
251 @param uuidString UUID string in XML file
252
253 @return UUID UUID instance
254 **/
255 private UUID translateSchemaStringToUUID(String uuidString)
256 throws EntityException {
257 String temp;
258 String[] splitStringArray;
259 int index;
260 int chIndex;
261 int chLen;
262
263 if (uuidString == null) {
264 return null;
265 }
266
267 if (uuidString.length() == 0) {
268 return null;
269 }
270
271 if (uuidString.equals("0") ||
272 uuidString.equalsIgnoreCase("0x0")) {
273 return new UUID(0, 0);
274 }
275
276 uuidString = uuidString.replaceAll("\\{", "");
277 uuidString = uuidString.replaceAll("\\}", "");
278
279 //
280 // If the UUID schema string is GuidArrayType type then need translate
281 // to GuidNamingConvention type at first.
282 //
283 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
284 splitStringArray = uuidString.split("," );
285 if (splitStringArray.length != 11) {
286 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);
287 }
288
289 //
290 // Remove blank space from these string and remove header string "0x"
291 //
292 for (index = 0; index < 11; index ++) {
293 splitStringArray[index] = splitStringArray[index].trim();
294 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
295 }
296
297 //
298 // Add heading '0' to normalize the string length
299 //
300 for (index = 3; index < 11; index ++) {
301 chLen = splitStringArray[index].length();
302 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
303 splitStringArray[index] = "0" + splitStringArray[index];
304 }
305 }
306
307 //
308 // construct the final GuidNamingConvention string
309 //
310 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
311 splitStringArray[0],
312 splitStringArray[1],
313 splitStringArray[2],
314 splitStringArray[3],
315 splitStringArray[4],
316 splitStringArray[5],
317 splitStringArray[6],
318 splitStringArray[7],
319 splitStringArray[8],
320 splitStringArray[9],
321 splitStringArray[10]);
322 uuidString = temp;
323 }
324
325 return UUID.fromString(uuidString);
326 }
327
328 /**
329 check the parameter for action class.
330
331 @throws BuildActionException Bad parameter.
332 **/
333 void checkParameter() throws BuildActionException {
334
335 }
336
337 /**
338 Core execution function for this action class.
339
340 All PCD information of this module comes from memory dabase. The collection
341 work should be done before this action execution.
342 Currently, we should generated all PCD information(maybe all dynamic) as array
343 in Pei emulated driver for simulating PCD runtime database.
344
345 @throws BuildActionException Failed to execute this aciton class.
346 **/
347 void performAction() throws BuildActionException {
348 ActionMessage.debug(this,
349 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");
350 //
351 // Check the PCD memory database manager is valid.
352 //
353 if(GlobalData.getPCDMemoryDBManager() == null) {
354 throw new BuildActionException("Memory database has not been initlizated!");
355 }
356
357 dbManager = GlobalData.getPCDMemoryDBManager();
358
359 if(dbManager.getDBSize() == 0) {
360 return;
361 }
362
363 ActionMessage.debug(this,
364 "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens");
365
366
367
368 generateAutogenForModule();
369 }
370
371 /**
372 Generate the autogen string for a common module.
373
374 All PCD information of this module comes from memory dabase. The collection
375 work should be done before this action execution.
376 **/
377 private void generateAutogenForModule()
378 {
379 int index, index2;
380 List<UsageInstance> usageInstanceArray, usageContext;
381 String[] guidStringArray = null;
382 String guidStringCName = null;
383 String guidString = null;
384 UsageInstance usageInstance = null;
385 boolean found = false;
386
387 usageInstanceArray = null;
388 if (!isBuildUsedLibrary) {
389 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName,
390 moduleGuid,
391 packageName,
392 packageGuid,
393 arch,
394 version);
395 dbManager.UsageInstanceContext = usageInstanceArray;
396 dbManager.CurrentModuleName = moduleName;
397 } else if ((pcdNameArray != null) && (pcdNameArray.length > 0)) {
398 usageContext = dbManager.UsageInstanceContext;
399 //
400 // For building library package, although all module are library, but PCD entries of
401 // these library should be used to autogen.
402 //
403 if (usageContext == null) {
404 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName,
405 moduleGuid,
406 packageName,
407 packageGuid,
408 arch,
409 version);
410 } else {
411 usageInstanceArray = new ArrayList<UsageInstance>();
412
413 //
414 // Try to find all PCD defined in library's PCD in all <PcdEntry> in module's
415 // <ModuleSA> in FPD file.
416 //
417 for (index = 0; index < pcdNameArray.length; index++) {
418 found = false;
419 for (index2 = 0; index2 < usageContext.size(); index2 ++) {
420 if (pcdNameArray[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) {
421 usageInstanceArray.add(usageContext.get(index2));
422 found = true;
423 break;
424 }
425 }
426
427 if (!found) {
428 //
429 // All library's PCD should instanted in module's <ModuleSA> who
430 // use this library instance. If not, give errors.
431 //
432 throw new BuildActionException (String.format("[PCD Autogen Error] Module %s use library instance %s, the PCD %s " +
433 "is required by this library instance, but can not find " +
434 "it in the %s's <ModuleSA> in FPD file!",
435 dbManager.CurrentModuleName,
436 moduleName,
437 pcdNameArray[index],
438 dbManager.CurrentModuleName
439 ));
440 }
441 }
442 }
443 }
444
445 if (usageInstanceArray == null) {
446 return;
447 }
448
449 //
450 // Generate all PCD entry for a module.
451 //
452 for(index = 0; index < usageInstanceArray.size(); index ++) {
453 ActionMessage.debug(this,
454 "Module " + moduleName + "'s PCD [" + Integer.toHexString(index) +
455 "]: " + usageInstanceArray.get(index).parentToken.cName);
456 try {
457 usageInstance = usageInstanceArray.get(index);
458 //
459 // Before generate any PCD information into autogen.h/autogen.c for a module,
460 // generate TokenSpaceGuid array variable firstly. For every dynamicEx type
461 // PCD in this module the token, they are all reference to TokenSpaceGuid
462 // array.
463 //
464 if (usageInstanceArray.get(index).modulePcdType == Token.PCD_TYPE.DYNAMIC_EX) {
465 guidStringArray = usageInstance.parentToken.tokenSpaceName.toString().split("-");
466 guidStringCName = "_gPcd_TokenSpaceGuid_" +
467 usageInstance.parentToken.tokenSpaceName.toString().replaceAll("-", "_");
468 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[0],
470 guidStringArray[1],
471 guidStringArray[2],
472 (guidStringArray[3].substring(0, 2)),
473 (guidStringArray[3].substring(2, 4)),
474 (guidStringArray[4].substring(0, 2)),
475 (guidStringArray[4].substring(2, 4)),
476 (guidStringArray[4].substring(4, 6)),
477 (guidStringArray[4].substring(6, 8)),
478 (guidStringArray[4].substring(8, 10)),
479 (guidStringArray[4].substring(10, 12)));
480
481 Pattern pattern = Pattern.compile("(" + guidStringCName + ")+?");
482 Matcher matcher = pattern.matcher(cAutoGenString + " ");
483 //
484 // Find whether this guid array variable has been generated into autogen.c
485 // For different DyanmicEx pcd token who use same token space guid, the token space
486 // guid array should be only generated once.
487 //
488 if (!matcher.find()) {
489 hAutoGenString += String.format("extern EFI_GUID %s;\r\n",
490 guidStringCName);
491 if (!isBuildUsedLibrary) {
492 cAutoGenString += String.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",
493 guidStringCName,
494 guidString);
495 }
496 }
497 }
498
499 usageInstance.generateAutoGen(isBuildUsedLibrary);
500 //
501 // For every PCD entry for this module(usage instance), autogen string would
502 // be appand.
503 //
504 hAutoGenString += usageInstance.getHAutogenStr() + "\r\n";
505 cAutoGenString += usageInstance.getCAutogenStr();
506
507 } catch(EntityException exp) {
508 throw new BuildActionException("[PCD Autogen Error]: " + exp.getMessage());
509 }
510 }
511
512 //
513 // Work around code, In furture following code should be modified that get
514 // these information from Uplevel Autogen tools.
515 //
516 if (moduleName.equalsIgnoreCase("PcdPeim")) {
517 hAutoGenString += dbManager.PcdPeimHString;
518 cAutoGenString += dbManager.PcdPeimCString;
519 } else if (moduleName.equalsIgnoreCase("PcdDxe")) {
520 hAutoGenString += dbManager.PcdDxeHString;
521 cAutoGenString += dbManager.PcdDxeCString;
522 }
523
524 ActionMessage.debug(this,
525 "Module " + moduleName + "'s PCD header file:\r\n" + hAutoGenString + "\r\n"
526 );
527 ActionMessage.debug(this,
528 "Module " + moduleName + "'s PCD C file:\r\n" + cAutoGenString + "\r\n"
529 );
530 }
531
532 /**
533 Test case function
534
535 @param argv paramter from command line
536 **/
537 public static void main(String argv[]) {
538
539 String WorkSpace = "X:/edk2";
540 String logFilePath = WorkSpace + "/EdkNt32Pkg/Nt32.fpd";
541 String[] nameArray = null;
542
543 //
544 // At first, CollectPCDAction should be invoked to collect
545 // all PCD information from SPD, MSA, FPD.
546 //
547 CollectPCDAction collectionAction = new CollectPCDAction();
548 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
549 WorkSpace,null);
550
551 try {
552 collectionAction.perform(WorkSpace,
553 logFilePath,
554 ActionMessage.MAX_MESSAGE_LEVEL);
555 } catch(Exception e) {
556 e.printStackTrace();
557 }
558
559 //
560 // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c
561 //
562 // PCDAutoGenAction autogenAction = new PCDAutoGenAction("MonoStatusCode",
563 // null,
564 // null,
565 // null,
566 // "IA32",
567 // null,
568 // false,
569 // nameArray);
570 // autogenAction.execute();
571 //
572 // System.out.println(autogenAction.OutputH());
573 // System.out.println("WQWQWQWQWQ");
574 // System.out.println(autogenAction.OutputC());
575 }
576 }