]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/GenFvImageTask.java
1) Added dependency check for flashmap, genfvimage, peirebase tasks
[mirror_edk2.git] / Tools / Source / FrameworkTasks / org / tianocore / framework / tasks / GenFvImageTask.java
CommitLineData
878ddf1f 1/** @file\r
2 GenFvImageTask class.\r
3\r
4 GenFvImageTask is to call GenFvImage.exe to generate FvImage.\r
5 \r
6 Copyright (c) 2006, Intel Corporation\r
7 All rights reserved. This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11 \r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15 **/\r
16package org.tianocore.framework.tasks;\r
878ddf1f 17\r
18import org.apache.tools.ant.BuildException;\r
19import org.apache.tools.ant.Project;\r
20import org.apache.tools.ant.Task;\r
93f5dd0a 21import org.apache.tools.ant.taskdefs.Execute;\r
22import org.apache.tools.ant.taskdefs.LogStreamHandler;\r
23import org.apache.tools.ant.types.Commandline;\r
878ddf1f 24\r
a236f1a1 25import java.io.File;\r
d946661a 26import java.io.InputStreamReader;\r
27import java.lang.ProcessBuilder;\r
28import java.util.LinkedList;\r
29import java.util.regex.Matcher;\r
30import java.util.regex.Pattern;\r
31import java.util.List;\r
32import java.util.StringTokenizer;\r
33import java.util.Iterator;\r
34import java.io.BufferedReader;\r
35import java.io.FileReader;\r
a236f1a1 36\r
93f5dd0a 37import org.tianocore.common.logger.EdkLog;\r
38\r
878ddf1f 39/**\r
40 GenFvImageTask\r
41 \r
42 GenFvImageTask is to call GenFvImage.exe to generate the FvImage.\r
43 \r
44**/\r
45public class GenFvImageTask extends Task implements EfiDefine{\r
93f5dd0a 46 //\r
47 // tool name\r
48 //\r
a236f1a1 49 static final private String toolName = "GenFvImage";\r
93f5dd0a 50 //\r
d946661a 51 // Pattern to match the section header (e.g. [options], [files])\r
52 // \r
53 static final private Pattern sectionHeader = Pattern.compile("\\[([^\\[\\]]+)\\]");\r
54 //\r
93f5dd0a 55 // The name of input inf file\r
56 //\r
57 private FileArg infFile = new FileArg();\r
58 //\r
59 // Output directory\r
60 //\r
a236f1a1 61 private String outputDir = ".";\r
a236f1a1 62\r
878ddf1f 63 /**\r
64 execute\r
65 \r
66 GenFvImageTask execute is to assemble tool command line & execute tool\r
67 command line.\r
68 **/\r
69 public void execute() throws BuildException {\r
70 Project project = this.getOwningTarget().getProject();\r
2da8968b 71 String path = project.getProperty("env.FRAMEWORK_TOOLS_PATH");\r
a236f1a1 72\r
d946661a 73 if (isUptodate()) {\r
74 EdkLog.log(this, EdkLog.EDK_VERBOSE, infFile.toFileList() + " is uptodate!");\r
75 return;\r
76 }\r
77\r
93f5dd0a 78 String command;\r
a236f1a1 79 if (path == null) {\r
93f5dd0a 80 command = toolName;\r
a236f1a1 81 } else {\r
93f5dd0a 82 command = path + File.separator + toolName;\r
878ddf1f 83 }\r
8742c000 84\r
93f5dd0a 85 String argument = "" + infFile;\r
86 //\r
87 // lauch the program\r
88 //\r
a236f1a1 89 int exitCode = 0;\r
878ddf1f 90 try {\r
93f5dd0a 91 Commandline cmdline = new Commandline();\r
92 cmdline.setExecutable(command);\r
93 cmdline.createArgument().setLine(argument);\r
94\r
95 LogStreamHandler streamHandler = new LogStreamHandler(this,\r
96 Project.MSG_INFO, Project.MSG_WARN);\r
97 Execute runner = new Execute(streamHandler, null);\r
a236f1a1 98\r
93f5dd0a 99 runner.setAntRun(project);\r
100 runner.setCommandline(cmdline.getCommandline());\r
101 runner.setWorkingDirectory(new File(outputDir)); \r
102 //\r
103 // log command line string.\r
104 //\r
105 EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmdline.getCommandline()));\r
106 EdkLog.log(this, infFile.toFileList());\r
107\r
108 exitCode = runner.execute();\r
a236f1a1 109 if (exitCode != 0) {\r
93f5dd0a 110 EdkLog.log(this, "ERROR = " + Integer.toHexString(exitCode));\r
878ddf1f 111 } else {\r
93f5dd0a 112 EdkLog.log(this, EdkLog.EDK_VERBOSE, "GenFvImage succeeded!");\r
878ddf1f 113 }\r
878ddf1f 114 } catch (Exception e) {\r
a236f1a1 115 throw new BuildException(e.getMessage());\r
116 } finally {\r
117 if (exitCode != 0) {\r
c59963f5 118 throw new BuildException("GenFvImage: failed to generate FV file!");\r
a236f1a1 119 }\r
120 }\r
878ddf1f 121 }\r
122 /**\r
123 getInfFile\r
124 \r
125 This function is to get class member of infFile\r
126 @return String name of infFile\r
127 **/\r
128 public String getInfFile() {\r
93f5dd0a 129 return infFile.getValue();\r
878ddf1f 130 }\r
131 \r
132 /**\r
133 setInfFile\r
134 \r
135 This function is to set class member of infFile.\r
136 \r
137 @param infFile name of infFile\r
138 **/\r
139 public void setInfFile(String infFile) {\r
93f5dd0a 140 this.infFile.setArg(" -I ", infFile);\r
878ddf1f 141 }\r
142 \r
a236f1a1 143 /**\r
144 getOutputDir\r
145 \r
146 This function is to get output directory.\r
147 \r
148 @return Path of output directory.\r
149 **/\r
150 public String getOutputDir() {\r
151 return outputDir;\r
152 }\r
153\r
154 /**\r
155 setOutputDir\r
156 \r
157 This function is to set output directory.\r
158 \r
159 @param outputDir The output direcotry.\r
160 **/\r
161 public void setOutputDir(String outputDir) {\r
162 this.outputDir = outputDir;\r
163 }\r
d946661a 164\r
165 //\r
166 // dependency check\r
167 // \r
168 private boolean isUptodate() {\r
169 String infName = this.infFile.getValue();\r
170 String fvName = "";\r
171 List<String> ffsFiles = new LinkedList<String>();\r
172 File inf = new File(infName);\r
173\r
174 try {\r
175 FileReader reader = new FileReader(inf);\r
176 BufferedReader in = new BufferedReader(reader);\r
177 String str;\r
178\r
179 //\r
180 // Read the inf file line by line\r
181 // \r
182 boolean inFiles = false;\r
183 boolean inOptions = false;\r
184 while ((str = in.readLine()) != null) {\r
185 str = str.trim();\r
186 if (str.length() == 0) {\r
187 continue;\r
188 }\r
189\r
190 Matcher matcher = sectionHeader.matcher(str);\r
191 if (matcher.find()) {\r
192 //\r
193 // We take care of only "options" and "files" section\r
194 // \r
195 String sectionName = str.substring(matcher.start(1), matcher.end(1));\r
196 if (sectionName.equalsIgnoreCase("options")) {\r
197 inOptions = true;\r
198 inFiles = false;\r
199 } else if (sectionName.equalsIgnoreCase("files")) {\r
200 inFiles = true;\r
201 inOptions = false;\r
202 } else {\r
203 inFiles = false;\r
204 inOptions = false;\r
205 }\r
206 continue;\r
207 }\r
208\r
209 //\r
210 // skip invalid line\r
211 // \r
212 int equalMarkPos = str.indexOf("=");\r
213 if (equalMarkPos < 0) {\r
214 continue;\r
215 }\r
216\r
217 //\r
218 // we have only interest in EFI_FILE_NAME\r
219 // \r
220 String fileNameFlag = str.substring(0, equalMarkPos).trim();\r
221 String fileName = str.substring(equalMarkPos + 1).trim();\r
222 if (!fileNameFlag.equalsIgnoreCase("EFI_FILE_NAME")\r
223 || fileName.length() == 0) {\r
224 continue;\r
225 }\r
226\r
227 if (inFiles) {\r
228 //\r
229 // files specified beneath the [files] section are source files\r
230 // \r
231 ffsFiles.add(fileName);\r
232 } else if (inOptions) {\r
233 //\r
234 // file specified beneath the [options] section is the target file\r
235 // \r
236 fvName = outputDir + File.separator + fileName;\r
237 }\r
238 }\r
239 } catch (Exception ex) {\r
240 throw new BuildException(ex.getMessage());\r
241 }\r
242\r
243 //\r
244 // if destionation file doesn't exist, we need to generate it.\r
245 // \r
246 File fvFile = new File(fvName);\r
247 if (!fvFile.exists()) {\r
248 EdkLog.log(this, EdkLog.EDK_VERBOSE, fvName + " doesn't exist!");\r
249 return false;\r
250 }\r
251\r
252 //\r
253 // the inf file itself will be taken as source file, check its timestamp\r
254 // against the target file\r
255 // \r
256 long fvFileTimeStamp = fvFile.lastModified();\r
257 if (inf.lastModified() > fvFileTimeStamp) {\r
258 EdkLog.log(this, EdkLog.EDK_VERBOSE, infName + " has been changed since last build!");\r
259 return false;\r
260 }\r
261\r
262 //\r
263 // no change in the inf file, we need to check each source files in it\r
264 // against the target file\r
265 // \r
266 for (Iterator it = ffsFiles.iterator(); it.hasNext(); ) {\r
267 String fileName = (String)it.next();\r
268 File file = new File(fileName);\r
269 if (file.lastModified() > fvFileTimeStamp) {\r
270 EdkLog.log(this, EdkLog.EDK_VERBOSE, fileName + " has been changed since last build!");\r
271 return false;\r
272 }\r
273 }\r
274\r
275 return true;\r
276 }\r
8742c000 277}\r