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