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