4 GenFvImageTask is to call GenFvImage.exe to generate FvImage.
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
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.
16 package org
.tianocore
.framework
.tasks
;
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
;
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
;
34 import org
.tianocore
.common
.logger
.EdkLog
;
39 GenFvImageTask is to call GenFvImage.exe to generate the FvImage.
42 public class GenFvImageTask
extends Task
implements EfiDefine
{
46 static final private String toolName
= "GenFvImage";
48 // Pattern to match the section header (e.g. [options], [files])
50 static final private Pattern sectionHeader
= Pattern
.compile("\\[([^\\[\\]]+)\\]");
52 // The name of input inf file
54 private FileArg infFile
= new FileArg();
58 private String outputDir
= ".";
63 GenFvImageTask execute is to assemble tool command line & execute tool
66 public void execute() throws BuildException
{
67 Project project
= this.getOwningTarget().getProject();
68 String path
= project
.getProperty("env.FRAMEWORK_TOOLS_PATH");
71 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, infFile
.toFileList() + " is uptodate!");
79 command
= path
+ File
.separator
+ toolName
;
82 String argument
= "" + infFile
;
88 Commandline cmdline
= new Commandline();
89 cmdline
.setExecutable(command
);
90 cmdline
.createArgument().setLine(argument
);
92 LogStreamHandler streamHandler
= new LogStreamHandler(this,
93 Project
.MSG_INFO
, Project
.MSG_WARN
);
94 Execute runner
= new Execute(streamHandler
, null);
96 runner
.setAntRun(project
);
97 runner
.setCommandline(cmdline
.getCommandline());
98 runner
.setWorkingDirectory(new File(outputDir
));
100 // log command line string.
102 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, Commandline
.toString(cmdline
.getCommandline()));
103 EdkLog
.log(this, infFile
.toFileList());
105 exitCode
= runner
.execute();
107 EdkLog
.log(this, "ERROR = " + Integer
.toHexString(exitCode
));
109 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, "GenFvImage succeeded!");
111 } catch (Exception e
) {
112 throw new BuildException(e
.getMessage());
115 throw new BuildException("GenFvImage: failed to generate FV file!");
122 This function is to get class member of infFile
123 @return String name of infFile
125 public String
getInfFile() {
126 return infFile
.getValue();
132 This function is to set class member of infFile.
134 @param infFile name of infFile
136 public void setInfFile(String infFile
) {
137 this.infFile
.setArg(" -I ", infFile
);
143 This function is to get output directory.
145 @return Path of output directory.
147 public String
getOutputDir() {
154 This function is to set output directory.
156 @param outputDir The output direcotry.
158 public void setOutputDir(String outputDir
) {
159 this.outputDir
= outputDir
;
165 private boolean isUptodate() {
166 String infName
= this.infFile
.getValue();
168 List
<String
> ffsFiles
= new LinkedList
<String
>();
169 File inf
= new File(infName
);
172 FileReader reader
= new FileReader(inf
);
173 BufferedReader in
= new BufferedReader(reader
);
177 // Read the inf file line by line
179 boolean inFiles
= false;
180 boolean inOptions
= false;
181 while ((str
= in
.readLine()) != null) {
183 if (str
.length() == 0) {
187 Matcher matcher
= sectionHeader
.matcher(str
);
188 if (matcher
.find()) {
190 // We take care of only "options" and "files" section
192 String sectionName
= str
.substring(matcher
.start(1), matcher
.end(1));
193 if (sectionName
.equalsIgnoreCase("options")) {
196 } else if (sectionName
.equalsIgnoreCase("files")) {
209 int equalMarkPos
= str
.indexOf("=");
210 if (equalMarkPos
< 0) {
215 // we have only interest in EFI_FILE_NAME
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) {
226 // files specified beneath the [files] section are source files
228 ffsFiles
.add(fileName
);
229 } else if (inOptions
) {
231 // file specified beneath the [options] section is the target file
233 fvName
= outputDir
+ File
.separator
+ fileName
;
236 } catch (Exception ex
) {
237 throw new BuildException(ex
.getMessage());
241 // if destionation file doesn't exist, we need to generate it.
243 File fvFile
= new File(fvName
);
244 if (!fvFile
.exists()) {
245 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, fvName
+ " doesn't exist!");
250 // the inf file itself will be taken as source file, check its timestamp
251 // against the target file
253 long fvFileTimeStamp
= fvFile
.lastModified();
254 if (inf
.lastModified() > fvFileTimeStamp
) {
255 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, infName
+ " has been changed since last build!");
260 // no change in the inf file, we need to check each source files in it
261 // against the target file
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!");