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